Linux-2.6.12-rc2

Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.

Let it rip!
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
new file mode 100644
index 0000000..5e666aa
--- /dev/null
+++ b/arch/mips/Kconfig
@@ -0,0 +1,1658 @@
+config MIPS
+	bool
+	default y
+	# Horrible source of confusion.  Die, die, die ...
+	select EMBEDDED
+
+config MIPS64
+	bool "64-bit kernel"
+	help
+	  Select this option if you want to build a 64-bit kernel.  You should
+	  only select this option if you have hardware that actually has a
+	  64-bit processor and if your application will actually benefit from
+	  64-bit processing, otherwise say N.  You must say Y for kernels for
+	  SGI IP27 (Origin 200 and 2000) and SGI IP32 (O2).  If in doubt say N.
+
+config 64BIT
+	def_bool MIPS64
+
+config MIPS32
+	bool
+	depends on MIPS64 = 'n'
+	default y
+
+mainmenu "Linux/MIPS Kernel Configuration"
+
+source "init/Kconfig"
+
+menu "Machine selection"
+
+config MACH_JAZZ
+	bool "Support for the Jazz family of machines"
+	select ARC
+	select ARC32
+	select GENERIC_ISA_DMA
+	select I8259
+	select ISA
+	help
+	 This a family of machines based on the MIPS R4030 chipset which was
+	 used by several vendors to build RISC/os and Windows NT workstations.
+	 Members include the Acer PICA, MIPS Magnum 4000, MIPS Millenium and
+	 Olivetti M700-10 workstations.
+
+config ACER_PICA_61
+	bool "Support for Acer PICA 1 chipset (EXPERIMENTAL)"
+	depends on MACH_JAZZ && EXPERIMENTAL
+	select DMA_NONCOHERENT
+	help
+	  This is a machine with a R4400 133/150 MHz CPU. To compile a Linux
+	  kernel that runs on these, say Y here. For details about Linux on
+	  the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
+	  <http://www.linux-mips.org/>.
+
+config MIPS_MAGNUM_4000
+	bool "Support for MIPS Magnum 4000"
+	depends on MACH_JAZZ
+	select DMA_NONCOHERENT
+	help
+	  This is a machine with a R4000 100 MHz CPU. To compile a Linux
+	  kernel that runs on these, say Y here. For details about Linux on
+	  the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
+	  <http://www.linux-mips.org/>.
+
+config OLIVETTI_M700
+	bool "Support for Olivetti M700-10"
+	depends on MACH_JAZZ
+	select DMA_NONCOHERENT
+	help
+	  This is a machine with a R4000 100 MHz CPU. To compile a Linux
+	  kernel that runs on these, say Y here. For details about Linux on
+	  the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
+	  <http://www.linux-mips.org/>.
+
+config MACH_VR41XX
+	bool "Support for NEC VR41XX-based machines"
+
+config NEC_CMBVR4133
+	bool "Support for NEC CMB-VR4133"
+	depends on MACH_VR41XX
+	select CPU_VR41XX
+	select DMA_NONCOHERENT
+	select IRQ_CPU
+	select HW_HAS_PCI
+	select PCI_VR41XX
+
+config ROCKHOPPER
+	bool "Support for Rockhopper baseboard"
+	depends on NEC_CMBVR4133
+	select I8259
+	select HAVE_STD_PC_SERIAL_PORT
+
+config CASIO_E55
+	bool "Support for CASIO CASSIOPEIA E-10/15/55/65"
+	depends on MACH_VR41XX
+	select DMA_NONCOHERENT
+	select IRQ_CPU
+	select ISA
+
+config IBM_WORKPAD
+	bool "Support for IBM WorkPad z50"
+	depends on MACH_VR41XX
+	select DMA_NONCOHERENT
+	select IRQ_CPU
+	select ISA
+
+config TANBAC_TB0226
+	bool "Support for TANBAC TB0226 (Mbase)"
+	depends on MACH_VR41XX
+	select DMA_NONCOHERENT
+	select HW_HAS_PCI
+	select IRQ_CPU
+	help
+	  The TANBAC TB0226 (Mbase) is a MIPS-based platform manufactured by TANBAC.
+	  Please refer to <http://www.tanbac.co.jp/> about Mbase.
+
+config TANBAC_TB0229
+	bool "Support for TANBAC TB0229 (VR4131DIMM)"
+	depends on MACH_VR41XX
+	select DMA_NONCOHERENT
+	select HW_HAS_PCI
+	select IRQ_CPU
+	help
+	  The TANBAC TB0229 (VR4131DIMM) is a MIPS-based platform manufactured by TANBAC.
+	  Please refer to <http://www.tanbac.co.jp/> about VR4131DIMM.
+
+config VICTOR_MPC30X
+	bool "Support for Victor MP-C303/304"
+	select DMA_NONCOHERENT
+	select HW_HAS_PCI
+	select IRQ_CPU
+	depends on MACH_VR41XX
+
+config ZAO_CAPCELLA
+	bool "Support for ZAO Networks Capcella"
+	depends on MACH_VR41XX
+	select DMA_NONCOHERENT
+	select HW_HAS_PCI
+	select IRQ_CPU
+
+config PCI_VR41XX
+	bool "Add PCI control unit support of NEC VR4100 series"
+	depends on MACH_VR41XX && PCI
+
+config VRC4171
+	tristate "Add NEC VRC4171 companion chip support"
+	depends on MACH_VR41XX && ISA
+	---help---
+	  The NEC VRC4171/4171A is a companion chip for NEC VR4111/VR4121.
+
+config VRC4173
+	tristate "Add NEC VRC4173 companion chip support"
+	depends on MACH_VR41XX && PCI_VR41XX
+	---help---
+	  The NEC VRC4173 is a companion chip for NEC VR4122/VR4131.
+
+config TOSHIBA_JMR3927
+	bool "Support for Toshiba JMR-TX3927 board"
+	depends on MIPS32
+	select DMA_NONCOHERENT
+	select HW_HAS_PCI
+	select SWAP_IO_SPACE
+
+config MIPS_COBALT
+	bool "Support for Cobalt Server (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	select DMA_NONCOHERENT
+	select HW_HAS_PCI
+	select I8259
+	select IRQ_CPU
+
+config MACH_DECSTATION
+	bool "Support for DECstations"
+	select BOOT_ELF32
+	select DMA_NONCOHERENT
+	select IRQ_CPU
+	depends on MIPS32 || EXPERIMENTAL
+	---help---
+	  This enables support for DEC's MIPS based workstations.  For details
+	  see the Linux/MIPS FAQ on <http://www.linux-mips.org/> and the
+	  DECstation porting pages on <http://decstation.unix-ag.org/>.
+
+	  If you have one of the following DECstation Models you definitely
+	  want to choose R4xx0 for the CPU Type:
+
+	  	DECstation 5000/50
+	  	DECstation 5000/150
+	  	DECstation 5000/260
+	  	DECsystem 5900/260
+
+	  otherwise choose R3000.
+
+config MIPS_EV64120
+	bool "Support for Galileo EV64120 Evaluation board (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	select DMA_NONCOHERENT
+	select HW_HAS_PCI
+	select MIPS_GT64120
+	help
+	  This is an evaluation board based on the Galileo GT-64120
+	  single-chip system controller that contains a MIPS R5000 compatible
+	  core running at 75/100MHz.  Their website is located at
+	  <http://www.marvell.com/>.  Say Y here if you wish to build a
+	  kernel for this platform.
+
+config EVB_PCI1
+	bool "Enable Second PCI (PCI1)"
+	depends on MIPS_EV64120
+
+config MIPS_EV96100
+	bool "Support for Galileo EV96100 Evaluation board (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	select DMA_NONCOHERENT
+	select HW_HAS_PCI
+	select IRQ_CPU
+	select MIPS_GT96100
+	select RM7000_CPU_SCACHE
+	select SWAP_IO_SPACE
+	help
+	  This is an evaluation board based on the Galileo GT-96100 LAN/WAN
+	  communications controllers containing a MIPS R5000 compatible core
+	  running at 83MHz. Their website is <http://www.marvell.com/>. Say Y
+	  here if you wish to build a kernel for this platform.
+
+config MIPS_IVR
+	bool "Support for Globespan IVR board"
+	select DMA_NONCOHERENT
+	select HW_HAS_PCI
+	help
+	  This is an evaluation board built by Globespan to showcase thir
+	  iVR (Internet Video Recorder) design. It utilizes a QED RM5231
+	  R5000 MIPS core. More information can be found out their website
+	  located at <http://www.globespan.net/>. Say Y here if you wish to
+	  build a kernel for this platform.
+
+config LASAT
+	bool "Support for LASAT Networks platforms"
+	select DMA_NONCOHERENT
+	select HW_HAS_PCI
+	select MIPS_GT64120
+	select R5000_CPU_SCACHE
+
+config PICVUE
+	tristate "PICVUE LCD display driver"
+	depends on LASAT
+
+config PICVUE_PROC
+	tristate "PICVUE LCD display driver /proc interface"
+	depends on PICVUE
+
+config DS1603
+	bool "DS1603 RTC driver"
+	depends on LASAT
+
+config LASAT_SYSCTL
+	bool "LASAT sysctl interface"
+	depends on LASAT
+
+config MIPS_ITE8172
+	bool "Support for ITE 8172G board"
+	select DMA_NONCOHERENT
+	select HW_HAS_PCI
+	help
+	  Ths is an evaluation board made by ITE <http://www.ite.com.tw/>
+	  with ATX form factor that utilizes a MIPS R5000 to work with its
+	  ITE8172G companion internet appliance chip. The MIPS core can be
+	  either a NEC Vr5432 or QED RM5231. Say Y here if you wish to build
+	  a kernel for this platform.
+
+config IT8172_REVC
+	bool "Support for older IT8172 (Rev C)"
+	depends on MIPS_ITE8172
+	help
+	  Say Y here to support the older, Revision C version of the Integrated
+	  Technology Express, Inc. ITE8172 SBC.  Vendor page at
+	  <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the
+	  board at <http://www.mvista.com/partners/semiconductor/ite.html>.
+
+config MIPS_ATLAS
+	bool "Support for MIPS Atlas board"
+	select BOOT_ELF32
+	select DMA_NONCOHERENT
+	select HW_HAS_PCI
+	select MIPS_GT64120
+	select SWAP_IO_SPACE
+	help
+	  This enables support for the QED R5231-based MIPS Atlas evaluation
+	  board.
+
+config MIPS_MALTA
+	bool "Support for MIPS Malta board"
+	select BOOT_ELF32
+	select HAVE_STD_PC_SERIAL_PORT
+	select DMA_NONCOHERENT
+	select GENERIC_ISA_DMA
+	select HW_HAS_PCI
+	select I8259
+	select MIPS_GT64120
+	select SWAP_IO_SPACE
+	help
+	  This enables support for the VR5000-based MIPS Malta evaluation
+	  board.
+
+config MIPS_SEAD
+	bool "Support for MIPS SEAD board (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	select IRQ_CPU
+	select DMA_NONCOHERENT
+
+config MOMENCO_OCELOT
+	bool "Support for Momentum Ocelot board"
+	select DMA_NONCOHERENT
+	select HW_HAS_PCI
+	select IRQ_CPU
+	select IRQ_CPU_RM7K
+	select MIPS_GT64120
+	select RM7000_CPU_SCACHE
+	select SWAP_IO_SPACE
+	help
+	  The Ocelot is a MIPS-based Single Board Computer (SBC) made by
+	  Momentum Computer <http://www.momenco.com/>.
+
+config MOMENCO_OCELOT_G
+	bool "Support for Momentum Ocelot-G board"
+	select DMA_NONCOHERENT
+	select HW_HAS_PCI
+	select IRQ_CPU
+	select IRQ_CPU_RM7K
+	select PCI_MARVELL
+	select RM7000_CPU_SCACHE
+	select SWAP_IO_SPACE
+	help
+	  The Ocelot is a MIPS-based Single Board Computer (SBC) made by
+	  Momentum Computer <http://www.momenco.com/>.
+
+config MOMENCO_OCELOT_C
+	bool "Support for Momentum Ocelot-C board"
+	select DMA_NONCOHERENT
+	select HW_HAS_PCI
+	select IRQ_CPU
+	select IRQ_MV64340
+	select PCI_MARVELL
+	select RM7000_CPU_SCACHE
+	select SWAP_IO_SPACE
+	help
+	  The Ocelot is a MIPS-based Single Board Computer (SBC) made by
+	  Momentum Computer <http://www.momenco.com/>.
+
+config MOMENCO_OCELOT_3
+	bool "Support for Momentum Ocelot-3 board"
+	select BOOT_ELF32
+	select DMA_NONCOHERENT
+	select HW_HAS_PCI
+	select IRQ_CPU
+	select IRQ_CPU_RM7K
+	select IRQ_MV64340
+	select PCI_MARVELL
+	select RM7000_CPU_SCACHE
+	select SWAP_IO_SPACE
+	help
+	  The Ocelot-3 is based off Discovery III System Controller and
+	  PMC-Sierra Rm79000 core.
+
+config MOMENCO_JAGUAR_ATX
+	bool "Support for Momentum Jaguar board"
+	select BOOT_ELF32
+	select DMA_NONCOHERENT
+	select HW_HAS_PCI
+	select IRQ_CPU
+	select IRQ_CPU_RM7K
+	select IRQ_MV64340
+	select LIMITED_DMA
+	select PCI_MARVELL
+	select RM7000_CPU_SCACHE
+	select SWAP_IO_SPACE
+	help
+	  The Jaguar ATX is a MIPS-based Single Board Computer (SBC) made by
+	  Momentum Computer <http://www.momenco.com/>.
+
+config JAGUAR_DMALOW
+	bool "Low DMA Mode"
+	depends on MOMENCO_JAGUAR_ATX
+	help
+	  Select to Y if jump JP5 is set on your board, N otherwise.  Normally
+	  the jumper is set, so if you feel unsafe, just say Y.
+
+config PMC_YOSEMITE
+	bool "Support for PMC-Sierra Yosemite eval board"
+	select DMA_COHERENT
+	select HW_HAS_PCI
+	select IRQ_CPU
+	select IRQ_CPU_RM7K
+	select IRQ_CPU_RM9K
+	select SWAP_IO_SPACE
+	help
+	  Yosemite is an evaluation board for the RM9000x2 processor
+	  manufactured by PMC-Sierra
+
+config HYPERTRANSPORT
+	bool "Hypertransport Support for PMC-Sierra Yosemite"
+	depends on PMC_YOSEMITE
+
+config DDB5074
+	bool "Support for NEC DDB Vrc-5074 (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	select DMA_NONCOHERENT
+	select HAVE_STD_PC_SERIAL_PORT
+	select HW_HAS_PCI
+	select IRQ_CPU
+	select I8259
+	select ISA
+	help
+	  This enables support for the VR5000-based NEC DDB Vrc-5074
+	  evaluation board.
+
+config DDB5476
+	bool "Support for NEC DDB Vrc-5476"
+	select DMA_NONCOHERENT
+	select HAVE_STD_PC_SERIAL_PORT
+	select HW_HAS_PCI
+	select IRQ_CPU
+	select I8259
+	select ISA
+	help
+	  This enables support for the R5432-based NEC DDB Vrc-5476
+	  evaluation board.
+
+	  Features : kernel debugging, serial terminal, NFS root fs, on-board
+	  ether port USB, AC97, PCI, PCI VGA card & framebuffer console,
+	  IDE controller, PS2 keyboard, PS2 mouse, etc.
+
+config DDB5477
+	bool "Support for NEC DDB Vrc-5477"
+	select DMA_NONCOHERENT
+	select HW_HAS_PCI
+	select I8259
+	select IRQ_CPU
+	help
+	  This enables support for the R5432-based NEC DDB Vrc-5477,
+	  or Rockhopper/SolutionGear boards with R5432/R5500 CPUs.
+
+	  Features : kernel debugging, serial terminal, NFS root fs, on-board
+	  ether port USB, AC97, PCI, etc.
+
+config DDB5477_BUS_FREQUENCY
+	int "bus frequency (in kHZ, 0 for auto-detect)"
+	depends on DDB5477
+	default 0
+
+config NEC_OSPREY
+	bool "Support for NEC Osprey board"
+	select DMA_NONCOHERENT
+	select IRQ_CPU
+
+config SGI_IP22
+	bool "Support for SGI IP22 (Indy/Indigo2)"
+	select ARC
+	select ARC32
+	select BOOT_ELF32
+	select DMA_NONCOHERENT
+	select IP22_CPU_SCACHE
+	select IRQ_CPU
+	select SWAP_IO_SPACE
+	help
+	  This are the SGI Indy, Challenge S and Indigo2, as well as certain
+	  OEM variants like the Tandem CMN B006S. To compile a Linux kernel
+	  that runs on these, say Y here.
+
+config SGI_IP27
+	bool "Support for SGI IP27 (Origin200/2000)"
+	depends on MIPS64
+	select ARC
+	select ARC64
+	select DMA_IP27
+	select HW_HAS_PCI
+	select PCI_DOMAINS
+	help
+	  This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics
+	  workstations.  To compile a Linux kernel that runs on these, say Y
+	  here.
+
+#config SGI_SN0_XXL
+#	bool "IP27 XXL"
+#	depends on SGI_IP27
+#	  This options adds support for userspace processes upto 16TB size.
+#	  Normally the limit is just .5TB.
+
+config SGI_SN0_N_MODE
+	bool "IP27 N-Mode"
+	depends on SGI_IP27
+	help
+	  The nodes of Origin 200, Origin 2000 and Onyx 2 systems can be
+	  configured in either N-Modes which allows for more nodes or M-Mode
+	  which allows for more memory.  Your system is most probably
+	  running in M-Mode, so you should say N here.
+
+config DISCONTIGMEM
+	bool
+	default y if SGI_IP27
+	help
+	  Say Y to upport efficient handling of discontiguous physical memory,
+	  for architectures which are either NUMA (Non-Uniform Memory Access)
+	  or have huge holes in the physical address space for other reasons.
+	  See <file:Documentation/vm/numa> for more.
+
+config NUMA
+	bool "NUMA Support"
+	depends on SGI_IP27
+	help
+	  Say Y to compile the kernel to support NUMA (Non-Uniform Memory
+	  Access).  This option is for configuring high-end multiprocessor
+	  server machines.  If in doubt, say N.
+
+config MAPPED_KERNEL
+	bool "Mapped kernel support"
+	depends on SGI_IP27
+	help
+	  Change the way a Linux kernel is loaded into memory on a MIPS64
+	  machine.  This is required in order to support text replication and
+	  NUMA.  If you need to understand it, read the source code.
+
+config REPLICATE_KTEXT
+	bool "Kernel text replication support"
+	depends on SGI_IP27
+	help
+	  Say Y here to enable replicating the kernel text across multiple
+	  nodes in a NUMA cluster.  This trades memory for speed.
+
+config REPLICATE_EXHANDLERS
+	bool "Exception handler replication support"
+	depends on SGI_IP27
+	help
+	  Say Y here to enable replicating the kernel exception handlers
+	  across multiple nodes in a NUMA cluster. This trades memory for
+	  speed.
+
+config SGI_IP32
+	bool "Support for SGI IP32 (O2) (EXPERIMENTAL)"
+	depends on MIPS64 && EXPERIMENTAL
+	select ARC
+	select ARC32
+	select BOOT_ELF32
+	select OWN_DMA
+	select DMA_IP32
+	select DMA_NONCOHERENT
+	select HW_HAS_PCI
+	select R5000_CPU_SCACHE
+	select RM7000_CPU_SCACHE
+	help
+	  If you want this kernel to run on SGI O2 workstation, say Y here.
+
+config SOC_AU1X00
+	depends on MIPS32
+	bool "Support for AMD/Alchemy Au1X00 SOCs"
+
+choice
+	prompt "Au1X00 SOC Type"
+	depends on SOC_AU1X00
+	help
+	  Say Y here to enable support for one of three AMD/Alchemy
+	  SOCs. For additional documentation see www.amd.com.
+
+config SOC_AU1000
+	bool "SOC_AU1000"
+config SOC_AU1100
+	bool "SOC_AU1100"
+config SOC_AU1500
+	bool "SOC_AU1500"
+config SOC_AU1550
+	bool "SOC_AU1550"
+
+endchoice
+
+choice
+	prompt "AMD/Alchemy Au1x00 board support"
+	depends on SOC_AU1X00
+	help
+	  These are evaluation boards built by AMD/Alchemy to
+	  showcase their Au1X00 Internet Edge Processors. The SOC design
+	  is based on the MIPS32 architecture running at 266/400/500MHz
+	  with many integrated peripherals. Further information can be
+	  found at their website, <http://www.amd.com/>. Say Y here if you
+	  wish to build a kernel for this platform.
+
+config MIPS_PB1000
+	bool "PB1000 board"
+	depends on SOC_AU1000
+	select DMA_NONCOHERENT
+	select HW_HAS_PCI
+	select SWAP_IO_SPACE
+
+config MIPS_PB1100
+	bool "PB1100 board"
+	depends on SOC_AU1100
+	select DMA_NONCOHERENT
+	select HW_HAS_PCI
+	select SWAP_IO_SPACE
+
+config MIPS_PB1500
+	bool "PB1500 board"
+	depends on SOC_AU1500
+	select DMA_COHERENT
+	select HW_HAS_PCI
+
+config MIPS_PB1550
+	bool "PB1550 board"
+	depends on SOC_AU1550
+	select DMA_COHERENT
+	select HW_HAS_PCI
+	select MIPS_DISABLE_OBSOLETE_IDE
+
+config MIPS_DB1000
+	bool "DB1000 board"
+	depends on SOC_AU1000
+	select DMA_NONCOHERENT
+	select HW_HAS_PCI
+
+config MIPS_DB1100
+	bool "DB1100 board"
+	depends on SOC_AU1100
+	select DMA_NONCOHERENT
+
+config MIPS_DB1500
+	bool "DB1500 board"
+	depends on SOC_AU1500
+	select DMA_COHERENT
+	select HW_HAS_PCI
+	select MIPS_DISABLE_OBSOLETE_IDE
+
+config MIPS_DB1550
+	bool "DB1550 board"
+	depends on SOC_AU1550
+	select HW_HAS_PCI
+	select DMA_COHERENT
+	select MIPS_DISABLE_OBSOLETE_IDE
+
+config MIPS_BOSPORUS
+	bool "Bosporus board"
+	depends on SOC_AU1500
+	select DMA_NONCOHERENT
+
+config MIPS_MIRAGE
+	bool "Mirage board"
+	depends on SOC_AU1500
+	select DMA_NONCOHERENT
+
+config MIPS_XXS1500
+	bool "MyCable XXS1500 board"
+	depends on SOC_AU1500
+	select DMA_NONCOHERENT
+
+config MIPS_MTX1
+	bool "4G Systems MTX-1 board"
+	depends on SOC_AU1500
+	select HW_HAS_PCI
+	select DMA_NONCOHERENT
+
+endchoice
+
+config SIBYTE_SB1xxx_SOC
+	bool "Support for Broadcom BCM1xxx SOCs (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	select BOOT_ELF32
+	select DMA_COHERENT
+	select SWAP_IO_SPACE
+
+choice
+	prompt "BCM1xxx SOC-based board"
+	depends on SIBYTE_SB1xxx_SOC
+	default SIBYTE_SWARM
+	help
+	  Enable support for boards based on the SiByte line of SOCs
+	  from Broadcom.  There are configurations for the known
+	  evaluation boards, or you can choose "Other" and add your
+	  own board support code.
+
+config SIBYTE_SWARM
+	bool "BCM91250A-SWARM"
+	select SIBYTE_SB1250
+
+config SIBYTE_SENTOSA
+	bool "BCM91250E-Sentosa"
+	select SIBYTE_SB1250
+
+config SIBYTE_RHONE
+	bool "BCM91125E-Rhone"
+	select SIBYTE_BCM1125H
+
+config SIBYTE_CARMEL
+	bool "BCM91120x-Carmel"
+	select SIBYTE_BCM1120
+
+config SIBYTE_PTSWARM
+	bool "BCM91250PT-PTSWARM"
+	select SIBYTE_SB1250
+
+config SIBYTE_LITTLESUR
+	bool "BCM91250C2-LittleSur"
+	select SIBYTE_SB1250
+
+config SIBYTE_CRHINE
+	bool "BCM91120C-CRhine"
+	select SIBYTE_BCM1120
+
+config SIBYTE_CRHONE
+	bool "BCM91125C-CRhone"
+	select SIBYTE_BCM1125
+
+config SIBYTE_UNKNOWN
+	bool "Other"
+
+endchoice
+
+config SIBYTE_BOARD
+	bool
+	depends on SIBYTE_SB1xxx_SOC && !SIBYTE_UNKNOWN
+	default y
+
+choice
+	prompt "BCM1xxx SOC Type"
+	depends on SIBYTE_UNKNOWN
+	default SIBYTE_UNK_BCM1250
+	help
+	  Since you haven't chosen a known evaluation board from
+	  Broadcom, you must explicitly pick the SOC this kernel is
+	  targetted for.
+
+config SIBYTE_UNK_BCM1250
+	bool "BCM1250"
+	select SIBYTE_SB1250
+
+config SIBYTE_UNK_BCM1120
+	bool "BCM1120"
+	select SIBYTE_BCM1120
+
+config SIBYTE_UNK_BCM1125
+	bool "BCM1125"
+	select SIBYTE_BCM1125
+
+config SIBYTE_UNK_BCM1125H
+	bool "BCM1125H"
+	select SIBYTE_BCM1125H
+
+endchoice
+
+config SIBYTE_SB1250
+	bool
+	select HW_HAS_PCI
+
+config SIBYTE_BCM1120
+	bool
+	select SIBYTE_BCM112X
+
+config SIBYTE_BCM1125
+	bool
+	select HW_HAS_PCI
+	select SIBYTE_BCM112X
+
+config SIBYTE_BCM1125H
+	bool
+	select HW_HAS_PCI
+	select SIBYTE_BCM112X
+
+config SIBYTE_BCM112X
+	bool
+
+choice
+	prompt "SiByte SOC Stepping"
+	depends on SIBYTE_SB1xxx_SOC
+
+config CPU_SB1_PASS_1
+	bool "1250 Pass1"
+	depends on SIBYTE_SB1250
+	select CPU_HAS_PREFETCH
+
+config CPU_SB1_PASS_2_1250
+	bool "1250 An"
+	depends on SIBYTE_SB1250
+	select CPU_SB1_PASS_2
+	help
+	  Also called BCM1250 Pass 2
+
+config CPU_SB1_PASS_2_2
+	bool "1250 Bn"
+	depends on SIBYTE_SB1250
+	select CPU_HAS_PREFETCH
+	help
+	  Also called BCM1250 Pass 2.2
+
+config CPU_SB1_PASS_4
+	bool "1250 Cn"
+	depends on SIBYTE_SB1250
+	select CPU_HAS_PREFETCH
+	help
+	  Also called BCM1250 Pass 3
+
+config CPU_SB1_PASS_2_112x
+	bool "112x Hybrid"
+	depends on SIBYTE_BCM112X
+	select CPU_SB1_PASS_2
+
+config CPU_SB1_PASS_3
+	bool "112x An"
+	depends on SIBYTE_BCM112X
+	select CPU_HAS_PREFETCH
+
+endchoice
+
+config CPU_SB1_PASS_2
+	bool
+
+config SIBYTE_HAS_LDT
+	bool
+	depends on PCI && (SIBYTE_SB1250 || SIBYTE_BCM1125H)
+	default y
+
+config SIMULATION
+	bool "Running under simulation"
+	depends on SIBYTE_SB1xxx_SOC
+	help
+	  Build a kernel suitable for running under the GDB simulator.
+	  Primarily adjusts the kernel's notion of time.
+
+config SIBYTE_CFE
+	bool "Booting from CFE"
+	depends on SIBYTE_SB1xxx_SOC
+	help
+	  Make use of the CFE API for enumerating available memory,
+	  controlling secondary CPUs, and possibly console output.
+
+config SIBYTE_CFE_CONSOLE
+	bool "Use firmware console"
+	depends on SIBYTE_CFE
+	help
+	  Use the CFE API's console write routines during boot.  Other console
+	  options (VT console, sb1250 duart console, etc.) should not be
+	  configured.
+
+config SIBYTE_STANDALONE
+	bool
+	depends on SIBYTE_SB1xxx_SOC && !SIBYTE_CFE
+	default y
+
+config SIBYTE_STANDALONE_RAM_SIZE
+	int "Memory size (in megabytes)"
+	depends on SIBYTE_STANDALONE
+	default "32"
+
+config SIBYTE_BUS_WATCHER
+	bool "Support for Bus Watcher statistics"
+	depends on SIBYTE_SB1xxx_SOC
+	help
+	  Handle and keep statistics on the bus error interrupts (COR_ECC,
+	  BAD_ECC, IO_BUS).
+
+config SIBYTE_BW_TRACE
+	bool "Capture bus trace before bus error"
+	depends on SIBYTE_BUS_WATCHER
+	help
+	  Run a continuous bus trace, dumping the raw data as soon as
+	  a ZBbus error is detected.  Cannot work if ZBbus profiling
+	  is turned on, and also will interfere with JTAG-based trace
+	  buffer activity.  Raw buffer data is dumped to console, and
+	  must be processed off-line.
+
+config SIBYTE_SB1250_PROF
+	bool "Support for SB1/SOC profiling - SB1/SCD perf counters"
+	depends on SIBYTE_SB1xxx_SOC
+
+config SIBYTE_TBPROF
+	bool "Support for ZBbus profiling"
+	depends on SIBYTE_SB1xxx_SOC
+
+config SNI_RM200_PCI
+	bool "Support for SNI RM200 PCI"
+	select ARC
+	select ARC32
+	select BOOT_ELF32
+	select DMA_NONCOHERENT
+	select GENERIC_ISA_DMA
+	select HAVE_STD_PC_SERIAL_PORT
+	select HW_HAS_PCI
+	select I8259
+	select ISA
+	help
+	  The SNI RM200 PCI was a MIPS-based platform manufactured by Siemens
+	  Nixdorf Informationssysteme (SNI), parent company of Pyramid
+	  Technology and now in turn merged with Fujitsu.  Say Y here to
+	  support this machine type.
+
+config TOSHIBA_RBTX4927
+	bool "Support for Toshiba TBTX49[23]7 board"
+	depends on MIPS32
+	select DMA_NONCOHERENT
+	select HAS_TXX9_SERIAL
+	select HW_HAS_PCI
+	select I8259
+	select ISA
+	select SWAP_IO_SPACE
+	help
+	  This Toshiba board is based on the TX4927 processor. Say Y here to
+	  support this machine type
+
+config TOSHIBA_FPCIB0
+	bool "FPCIB0 Backplane Support"
+	depends on TOSHIBA_RBTX4927
+
+config RWSEM_GENERIC_SPINLOCK
+	bool
+	default y
+
+config RWSEM_XCHGADD_ALGORITHM
+	bool
+
+config GENERIC_CALIBRATE_DELAY
+	bool
+	default y
+
+config HAVE_DEC_LOCK
+	bool
+	default y
+
+#
+# Select some configuration options automatically based on user selections.
+#
+config ARC
+	bool
+	depends on SNI_RM200_PCI || SGI_IP32 || SGI_IP27 || SGI_IP22 || MIPS_MAGNUM_4000 || OLIVETTI_M700 || ACER_PICA_61
+	default y
+
+config	DMA_COHERENT
+	bool
+
+config	DMA_IP27
+	bool
+
+config	DMA_NONCOHERENT
+	bool
+
+config EARLY_PRINTK
+	bool
+	depends on MACH_DECSTATION
+	default y
+
+config GENERIC_ISA_DMA
+	bool
+	depends on SNI_RM200_PCI || MIPS_MAGNUM_4000 || OLIVETTI_M700 || ACER_PICA_61 || MIPS_MALTA
+	default y
+
+config I8259
+	bool
+	depends on SNI_RM200_PCI || DDB5477 || DDB5476 || DDB5074 || MACH_JAZZ || MIPS_MALTA || MIPS_COBALT
+	default y
+
+config LIMITED_DMA
+	bool
+	select HIGHMEM
+
+config MIPS_BONITO64
+	bool
+	depends on MIPS_ATLAS || MIPS_MALTA
+	default y
+
+config MIPS_MSC
+	bool
+	depends on MIPS_ATLAS || MIPS_MALTA
+	default y
+
+config MIPS_NILE4
+	bool
+	depends on LASAT
+	default y
+
+config MIPS_DISABLE_OBSOLETE_IDE
+	bool
+
+config CPU_LITTLE_ENDIAN
+	bool "Generate little endian code"
+	default y if ACER_PICA_61 || CASIO_E55 || DDB5074 || DDB5476 || DDB5477 || MACH_DECSTATION || IBM_WORKPAD || LASAT || MIPS_COBALT || MIPS_ITE8172 || MIPS_IVR || SOC_AU1X00 || NEC_OSPREY || OLIVETTI_M700 || SNI_RM200_PCI || VICTOR_MPC30X || ZAO_CAPCELLA
+	default n if MIPS_EV64120 || MIPS_EV96100 || MOMENCO_OCELOT || MOMENCO_OCELOT_G || SGI_IP22 || SGI_IP27 || SGI_IP32 || TOSHIBA_JMR3927
+	help
+	  Some MIPS machines can be configured for either little or big endian
+	  byte order. These modes require different kernels. Say Y if your
+	  machine is little endian, N if it's a big endian machine.
+
+config IRQ_CPU
+	bool
+
+config IRQ_CPU_RM7K
+	bool
+
+config IRQ_MV64340
+	bool
+
+config DDB5XXX_COMMON
+	bool
+	depends on DDB5074 || DDB5476 || DDB5477
+	default y
+
+config MIPS_BOARDS_GEN
+	bool
+	depends on MIPS_ATLAS || MIPS_MALTA || MIPS_SEAD
+	default y
+
+config MIPS_GT64111
+	bool
+	depends on MIPS_COBALT
+	default y
+
+config MIPS_GT64120
+	bool
+	depends on MIPS_EV64120 || MIPS_EV96100 || LASAT || MIPS_ATLAS || MIPS_MALTA || MOMENCO_OCELOT
+	default y
+
+config MIPS_TX3927
+	bool
+	depends on TOSHIBA_JMR3927
+	select HAS_TXX9_SERIAL
+	default y
+
+config PCI_MARVELL
+	bool
+
+config ITE_BOARD_GEN
+	bool
+	depends on MIPS_IVR || MIPS_ITE8172
+	default y
+
+config SWAP_IO_SPACE
+	bool
+
+#
+# Unfortunately not all GT64120 systems run the chip at the same clock.
+# As the user for the clock rate and try to minimize the available options.
+#
+choice
+	prompt "Galileo Chip Clock"
+	#default SYSCLK_83 if MIPS_EV64120
+	depends on MIPS_EV64120 || MOMENCO_OCELOT || MOMENCO_OCELOT_G
+	default SYSCLK_83 if MIPS_EV64120
+	default SYSCLK_100 if MOMENCO_OCELOT || MOMENCO_OCELOT_G
+
+config SYSCLK_75
+	bool "75" if MIPS_EV64120
+
+config SYSCLK_83
+	bool "83.3" if MIPS_EV64120
+
+config SYSCLK_100
+	bool "100" if MIPS_EV64120 || MOMENCO_OCELOT || MOMENCO_OCELOT_G
+
+endchoice
+
+config AU1X00_USB_DEVICE
+	bool
+	depends on MIPS_PB1500 || MIPS_PB1100 || MIPS_PB1000
+	default n
+
+config MIPS_GT96100
+	bool
+	depends on MIPS_EV96100
+	default y
+	help
+	  Say Y here to support the Galileo Technology GT96100 communications
+	  controller card.  There is a web page at <http://www.galileot.com/>.
+
+config IT8172_CIR
+	bool
+	depends on MIPS_ITE8172 || MIPS_IVR
+	default y
+
+config IT8712
+	bool
+	depends on MIPS_ITE8172
+	default y
+
+config BOOT_ELF32
+	bool
+	depends on MACH_DECSTATION || MIPS_ATLAS || MIPS_MALTA || MOMENCO_JAGUAR_ATX || MOMENCO_OCELOT_3 || SIBYTE_SB1xxx_SOC || SGI_IP32 || SGI_IP22 || SNI_RM200_PCI
+	default y
+
+config MIPS_L1_CACHE_SHIFT
+	int
+	default "4" if MACH_DECSTATION
+	default "7" if SGI_IP27
+	default "5"
+
+config ARC32
+	bool
+	depends on MACH_JAZZ || SNI_RM200_PCI || SGI_IP22 || SGI_IP32
+	default y
+
+config FB
+	bool
+	depends on MIPS_MAGNUM_4000 || OLIVETTI_M700
+	default y
+	---help---
+	  The frame buffer device provides an abstraction for the graphics
+	  hardware. It represents the frame buffer of some video hardware and
+	  allows application software to access the graphics hardware through
+	  a well-defined interface, so the software doesn't need to know
+	  anything about the low-level (hardware register) stuff.
+
+	  Frame buffer devices work identically across the different
+	  architectures supported by Linux and make the implementation of
+	  application programs easier and more portable; at this point, an X
+	  server exists which uses the frame buffer device exclusively.
+	  On several non-X86 architectures, the frame buffer device is the
+	  only way to use the graphics hardware.
+
+	  The device is accessed through special device nodes, usually located
+	  in the /dev directory, i.e. /dev/fb*.
+
+	  You need an utility program called fbset to make full use of frame
+	  buffer devices. Please read <file:Documentation/fb/framebuffer.txt>
+	  and the Framebuffer-HOWTO at <http://www.tldp.org/docs.html#howto>
+	  for more information.
+
+	  Say Y here and to the driver for your graphics board below if you
+	  are compiling a kernel for a non-x86 architecture.
+
+	  If you are compiling for the x86 architecture, you can say Y if you
+	  want to play with it, but it is not essential. Please note that
+	  running graphical applications that directly touch the hardware
+	  (e.g. an accelerated X server) and that are not frame buffer
+	  device-aware may cause unexpected results. If unsure, say N.
+
+config HAVE_STD_PC_SERIAL_PORT
+	bool
+
+config VR4181
+	bool
+	depends on NEC_OSPREY
+	default y
+
+config ARC_CONSOLE
+	bool "ARC console support"
+	depends on SGI_IP22 || SNI_RM200_PCI
+
+config ARC_MEMORY
+	bool
+	depends on MACH_JAZZ || SNI_RM200_PCI || SGI_IP32
+	default y
+
+config ARC_PROMLIB
+	bool
+	depends on MACH_JAZZ || SNI_RM200_PCI || SGI_IP22 || SGI_IP32
+	default y
+
+config ARC64
+	bool
+	depends on SGI_IP27
+	default y
+
+config BOOT_ELF64
+	bool
+	depends on SGI_IP27
+	default y
+
+#config MAPPED_PCI_IO y
+#	bool
+#	depends on SGI_IP27
+#	default y
+
+config QL_ISP_A64
+	bool
+	depends on SGI_IP27
+	default y
+
+config TOSHIBA_BOARDS
+	bool
+	depends on TOSHIBA_JMR3927 || TOSHIBA_RBTX4927
+	default y
+
+endmenu
+
+menu "CPU selection"
+
+choice
+	prompt "CPU type"
+	default CPU_R4X00
+
+config CPU_MIPS32
+	bool "MIPS32"
+
+config CPU_MIPS64
+	bool "MIPS64"
+
+config CPU_R3000
+	bool "R3000"
+	depends on MIPS32
+	help
+	  Please make sure to pick the right CPU type. Linux/MIPS is not
+	  designed to be generic, i.e. Kernels compiled for R3000 CPUs will
+	  *not* work on R4000 machines and vice versa.  However, since most
+	  of the supported machines have an R4000 (or similar) CPU, R4x00
+	  might be a safe bet.  If the resulting kernel does not work,
+	  try to recompile with R3000.
+
+config CPU_TX39XX
+	bool "R39XX"
+	depends on MIPS32
+
+config CPU_VR41XX
+	bool "R41xx"
+	help
+	  The options selects support for the NEC VR41xx series of processors.
+	  Only choose this option if you have one of these processors as a
+	  kernel built with this option will not run on any other type of
+	  processor or vice versa.
+
+config CPU_R4300
+	bool "R4300"
+	help
+	  MIPS Technologies R4300-series processors.
+
+config CPU_R4X00
+	bool "R4x00"
+	help
+	  MIPS Technologies R4000-series processors other than 4300, including
+	  the R4000, R4400, R4600, and 4700.
+
+config CPU_TX49XX
+	bool "R49XX"
+
+config CPU_R5000
+	bool "R5000"
+	help
+	  MIPS Technologies R5000-series processors other than the Nevada.
+
+config CPU_R5432
+	bool "R5432"
+
+config CPU_R6000
+	bool "R6000"
+	depends on MIPS32 && EXPERIMENTAL
+	help
+	  MIPS Technologies R6000 and R6000A series processors.  Note these
+	  processors are extremly rare and the support for them is incomplete.
+
+config CPU_NEVADA
+	bool "RM52xx"
+	help
+	  QED / PMC-Sierra RM52xx-series ("Nevada") processors.
+
+config CPU_R8000
+	bool "R8000"
+	depends on MIPS64 && EXPERIMENTAL
+	help
+	  MIPS Technologies R8000 processors.  Note these processors are
+	  uncommon and the support for them is incomplete.
+
+config CPU_R10000
+	bool "R10000"
+	help
+	  MIPS Technologies R10000-series processors.
+
+config CPU_RM7000
+	bool "RM7000"
+
+config CPU_RM9000
+	bool "RM9000"
+
+config CPU_SB1
+	bool "SB1"
+
+endchoice
+
+choice
+	prompt "Kernel page size"
+	default PAGE_SIZE_4KB
+
+config PAGE_SIZE_4KB
+	bool "4kB"
+	help
+	 This option select the standard 4kB Linux page size.  On some
+	 R3000-family processors this is the only available page size.  Using
+	 4kB page size will minimize memory consumption and is therefore
+	 recommended for low memory systems.
+
+config PAGE_SIZE_8KB
+	bool "8kB"
+	depends on EXPERIMENTAL && CPU_R8000
+	help
+	  Using 8kB page size will result in higher performance kernel at
+	  the price of higher memory consumption.  This option is available
+	  only on the R8000 processor.  Not that at the time of this writing
+	  this option is still high experimental; there are also issues with
+	  compatibility of user applications.
+
+config PAGE_SIZE_16KB
+	bool "16kB"
+	depends on EXPERIMENTAL && !CPU_R3000 && !CPU_TX39XX
+	help
+	  Using 16kB page size will result in higher performance kernel at
+	  the price of higher memory consumption.  This option is available on
+	  all non-R3000 family processor.  Not that at the time of this
+	  writing this option is still high experimental; there are also
+	  issues with compatibility of user applications.
+
+config PAGE_SIZE_64KB
+	bool "64kB"
+	depends on EXPERIMENTAL && !CPU_R3000 && !CPU_TX39XX
+	help
+	  Using 64kB page size will result in higher performance kernel at
+	  the price of higher memory consumption.  This option is available on
+	  all non-R3000 family processor.  Not that at the time of this
+	  writing this option is still high experimental; there are also
+	  issues with compatibility of user applications.
+
+endchoice
+
+config BOARD_SCACHE
+	bool
+
+config IP22_CPU_SCACHE
+	bool
+	select BOARD_SCACHE
+
+config R5000_CPU_SCACHE
+	bool
+	select BOARD_SCACHE
+
+config RM7000_CPU_SCACHE
+	bool
+	select BOARD_SCACHE
+
+config SIBYTE_DMA_PAGEOPS
+	bool "Use DMA to clear/copy pages"
+	depends on CPU_SB1
+	help
+	  Instead of using the CPU to zero and copy pages, use a Data Mover
+	  channel.  These DMA channels are otherwise unused by the standard
+	  SiByte Linux port.  Seems to give a small performance benefit.
+
+config CPU_HAS_PREFETCH
+	bool "Enable prefetches" if CPU_SB1 && !CPU_SB1_PASS_2
+	default y if CPU_MIPS32 || CPU_MIPS64 || CPU_RM7000 || CPU_RM9000 || CPU_R10000
+
+config VTAG_ICACHE
+	bool "Support for Virtual Tagged I-cache" if CPU_MIPS64 || CPU_MIPS32
+	default y if CPU_SB1
+
+config SB1_PASS_1_WORKAROUNDS
+	bool
+	depends on CPU_SB1_PASS_1
+	default y
+
+config SB1_PASS_2_WORKAROUNDS
+	bool
+	depends on CPU_SB1 && (CPU_SB1_PASS_2_2 || CPU_SB1_PASS_2)
+	default y
+
+config SB1_PASS_2_1_WORKAROUNDS
+	bool
+	depends on CPU_SB1 && CPU_SB1_PASS_2
+	default y
+
+config 64BIT_PHYS_ADDR
+	bool "Support for 64-bit physical address space"
+	depends on (CPU_R4X00 || CPU_R5000 || CPU_RM7000 || CPU_RM9000 || CPU_R10000 || CPU_SB1 || CPU_MIPS32 || CPU_MIPS64) && MIPS32
+
+config CPU_ADVANCED
+	bool "Override CPU Options"
+	depends on MIPS32
+	help
+	  Saying yes here allows you to select support for various features
+	  your CPU may or may not have.  Most people should say N here.
+
+config CPU_HAS_LLSC
+	bool "ll/sc Instructions available" if CPU_ADVANCED
+	default y if !CPU_ADVANCED && !CPU_R3000 && !CPU_VR41XX && !CPU_TX39XX
+	help
+	  MIPS R4000 series and later provide the Load Linked (ll)
+	  and Store Conditional (sc) instructions. More information is
+	  available at <http://www.go-ecs.com/mips/miptek1.htm>.
+
+	  Say Y here if your CPU has the ll and sc instructions.  Say Y here
+	  for better performance, N if you don't know.  You must say Y here
+	  for multiprocessor machines.
+
+config CPU_HAS_LLDSCD
+	bool "lld/scd Instructions available" if CPU_ADVANCED
+	default y if !CPU_ADVANCED && !CPU_R3000 && !CPU_VR41XX && !CPU_TX39XX && !CPU_MIPS32
+	help
+	  Say Y here if your CPU has the lld and scd instructions, the 64-bit
+	  equivalents of ll and sc.  Say Y here for better performance, N if
+	  you don't know.  You must say Y here for multiprocessor machines.
+
+config CPU_HAS_WB
+	bool "Writeback Buffer available" if CPU_ADVANCED
+	default y if !CPU_ADVANCED && CPU_R3000 && MACH_DECSTATION
+	help
+	  Say N here for slightly better performance.  You must say Y here for
+	  machines which require flushing of write buffers in software.  Saying
+	  Y is the safe option; N may result in kernel malfunction and crashes.
+
+config CPU_HAS_SYNC
+	bool
+	depends on !CPU_R3000
+	default y
+
+#
+# - Highmem only makes sense for the 32-bit kernel.
+# - The current highmem code will only work properly on physically indexed
+#   caches such as R3000, SB1, R7000 or those that look like they're virtually
+#   indexed such as R4000/R4400 SC and MC versions or R10000.  So for the
+#   moment we protect the user and offer the highmem option only on machines
+#   where it's known to be safe.  This will not offer highmem on a few systems
+#   such as MIPS32 and MIPS64 CPUs which may have virtual and physically
+#   indexed CPUs but we're playing safe.
+# - We should not offer highmem for system of which we already know that they
+#   don't have memory configurations that could gain from highmem support in
+#   the kernel because they don't support configurations with RAM at physical
+#   addresses > 0x20000000.
+#
+config HIGHMEM
+	bool "High Memory Support"
+	depends on MIPS32 && (CPU_R3000 || CPU_SB1 || CPU_R7000 || CPU_RM9000 || CPU_R10000) && !(MACH_DECSTATION || MOMENCO_JAGUAR_ATX)
+
+config SMP
+	bool "Multi-Processing support"
+	depends on CPU_RM9000 || (SIBYTE_SB1250 && !SIBYTE_STANDALONE) || SGI_IP27
+	---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.
+
+	  People using multiprocessor machines who say Y here should also say
+	  Y to "Enhanced Real Time Clock Support", below.
+
+	  See also the <file:Documentation/smp.txt> and the SMP-HOWTO
+	  available at <http://www.tldp.org/docs.html#howto>.
+
+	  If you don't know what to do here, say N.
+
+config NR_CPUS
+	int "Maximum number of CPUs (2-64)"
+	range 2 64
+	depends on SMP
+	default "64" if SGI_IP27
+	default "2"
+	help
+	  This allows you to specify the maximum number of CPUs which this
+	  kernel will support.  The maximum supported value is 32 for 32-bit
+	  kernel and 64 for 64-bit kernels; 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.
+
+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.
+
+config RTC_DS1742
+	bool "DS1742 BRAM/RTC support"
+	depends on TOSHIBA_JMR3927 || TOSHIBA_RBTX4927
+
+config MIPS_INSANE_LARGE
+	bool "Support for large 64-bit configurations"
+	depends on CPU_R10000 && MIPS64
+	help
+	  MIPS R10000 does support a 44 bit / 16TB address space as opposed to
+	  previous 64-bit processors which only supported 40 bit / 1TB. If you
+	  need processes of more than 1TB virtual address space, say Y here.
+	  This will result in additional memory usage, so it is not
+	  recommended for normal users.
+
+config RWSEM_GENERIC_SPINLOCK
+	bool
+	default y
+
+endmenu
+
+menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)"
+
+config HW_HAS_PCI
+	bool
+
+config PCI
+	bool "Support for PCI controller"
+	depends on HW_HAS_PCI
+	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, or VESA. If you have PCI,
+	  say Y, otherwise N.
+
+	  The PCI-HOWTO, available from
+	  <http://www.tldp.org/docs.html#howto>, contains valuable
+	  information about which PCI hardware does work under Linux and which
+	  doesn't.
+
+config PCI_DOMAINS
+	bool
+	depends on PCI
+
+source "drivers/pci/Kconfig"
+
+#
+# ISA support is now enabled via select.  Too many systems still have the one
+# or other ISA chip on the board that users don't know about so don't expect
+# users to choose the right thing ...
+#
+config ISA
+	bool
+
+config EISA
+	bool "EISA support"
+	depends on SGI_IP22 || SNI_RM200_PCI
+	select 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"
+
+config TC
+	bool "TURBOchannel support"
+	depends on MACH_DECSTATION
+	help
+	  TurboChannel is a DEC (now Compaq (now HP)) bus for Alpha and MIPS
+	  processors.  Documentation on writing device drivers for TurboChannel
+	  is available at:
+	  <http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/AA-PS3HD-TET1_html/TITLE.html>.
+
+#config ACCESSBUS
+#	bool "Access.Bus support"
+#	depends on TC
+
+config MMU
+	bool
+	default y
+
+config MCA
+	bool
+
+config SBUS
+	bool
+
+source "drivers/pcmcia/Kconfig"
+
+source "drivers/pci/hotplug/Kconfig"
+
+endmenu
+
+menu "Executable file formats"
+
+source "fs/Kconfig.binfmt"
+
+config TRAD_SIGNALS
+	bool
+	default y if MIPS32
+
+config BUILD_ELF64
+	bool "Use 64-bit ELF format for building"
+	depends on MIPS64
+	help
+	  A 64-bit kernel is usually built using the 64-bit ELF binary object
+	  format as it's one that allows arbitrary 64-bit constructs.  For
+	  kernels that are loaded within the KSEG compatibility segments the
+	  32-bit ELF format can optionally be used resulting in a somewhat
+	  smaller binary, but this option is not explicitly supported by the
+	  toolchain and since binutils 2.14 it does not even work at all.
+
+	  Say Y to use the 64-bit format or N to use the 32-bit one.
+
+	  If unsure say Y.
+
+config BINFMT_IRIX
+	bool "Include IRIX binary compatibility"
+	depends on !CPU_LITTLE_ENDIAN && MIPS32 && BROKEN
+
+config MIPS32_COMPAT
+	bool "Kernel support for Linux/MIPS 32-bit binary compatibility"
+	depends on MIPS64
+	help
+	  Select this option if you want Linux/MIPS 32-bit binary
+	  compatibility. Since all software available for Linux/MIPS is
+	  currently 32-bit you should say Y here.
+
+config COMPAT
+	bool
+	depends on MIPS32_COMPAT
+	default y
+
+config MIPS32_O32
+	bool "Kernel support for o32 binaries"
+	depends on MIPS32_COMPAT
+	help
+	  Select this option if you want to run o32 binaries.  These are pure
+	  32-bit binaries as used by the 32-bit Linux/MIPS port.  Most of
+	  existing binaries are in this format.
+
+	  If unsure, say Y.
+
+config MIPS32_N32
+	bool "Kernel support for n32 binaries"
+	depends on MIPS32_COMPAT
+	help
+	  Select this option if you want to run n32 binaries.  These are
+	  64-bit binaries using 32-bit quantities for addressing and certain
+	  data that would normally be 64-bit.  They are used in special
+	  cases.
+
+	  If unsure, say N.
+
+config BINFMT_ELF32
+	bool
+	default y if MIPS32_O32 || MIPS32_N32
+
+config PM
+	bool "Power Management support (EXPERIMENTAL)"
+	depends on EXPERIMENTAL && MACH_AU1X00
+
+endmenu
+
+source "drivers/Kconfig"
+
+source "fs/Kconfig"
+
+source "arch/mips/Kconfig.debug"
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+source "lib/Kconfig"
+
+#
+# Use the generic interrupt handling code in kernel/irq/:
+#
+config GENERIC_HARDIRQS
+	bool
+	default y
+
+config GENERIC_IRQ_PROBE
+	bool
+	default y
diff --git a/arch/mips/Kconfig.debug b/arch/mips/Kconfig.debug
new file mode 100644
index 0000000..d3c5cc3
--- /dev/null
+++ b/arch/mips/Kconfig.debug
@@ -0,0 +1,76 @@
+menu "Kernel hacking"
+
+source "lib/Kconfig.debug"
+
+config CROSSCOMPILE
+	bool "Are you using a crosscompiler"
+	help
+	  Say Y here if you are compiling the kernel on a different
+	  architecture than the one it is intended to run on.
+
+config CMDLINE
+	string "Default kernel command string"
+	default ""
+	help
+          On some platforms, there is currently no way for the boot loader to
+          pass arguments to the kernel. For these platforms, you can supply
+          some command-line options at build time by entering them here.  In
+          other cases you can specify kernel args so that you don't have
+	  to set them up in board prom initialization routines.
+
+config DEBUG_STACK_USAGE
+	bool "Enable stack utilization instrumentation"
+	depends on DEBUG_KERNEL
+	help
+	  Enables the display of the minimum amount of free stack which each
+	  task has ever had available in the sysrq-T and sysrq-P debug output.
+
+	  This option will slow down process creation somewhat.
+
+config KGDB
+	bool "Remote GDB kernel debugging"
+	depends on DEBUG_KERNEL
+	select DEBUG_INFO
+	help
+	  If you say Y here, it will be possible to remotely debug the MIPS
+	  kernel using gdb. This enlarges your kernel image disk size by
+	  several megabytes and requires a machine with more than 16 MB,
+	  better 32 MB RAM to avoid excessive linking time. This is only
+	  useful for kernel hackers. If unsure, say N.
+
+config GDB_CONSOLE
+	bool "Console output to GDB"
+	depends on KGDB
+	help
+	  If you are using GDB for remote debugging over a serial port and
+	  would like kernel messages to be formatted into GDB $O packets so
+	  that GDB prints them as program output, say 'Y'.
+
+config SB1XXX_CORELIS
+	bool "Corelis Debugger"
+	depends on SIBYTE_SB1xxx_SOC
+	select DEBUG_INFO
+	help
+	  Select compile flags that produce code that can be processed by the
+	  Corelis mksym utility and UDB Emulator.
+
+config RUNTIME_DEBUG
+	bool "Enable run-time debugging"
+	depends on DEBUG_KERNEL
+	help
+	  If you say Y here, some debugging macros will do run-time checking.
+	  If you say N here, those macros will mostly turn to no-ops.  See
+	  include/asm-mips/debug.h for debuging macros.
+	  If unsure, say N.
+
+config MIPS_UNCACHED
+	bool "Run uncached"
+	depends on DEBUG_KERNEL && !SMP && !SGI_IP27
+	help
+	  If you say Y here there kernel will disable all CPU caches.  This will
+	  reduce the system's performance dramatically but can help finding
+	  otherwise hard to track bugs.  It can also useful if you're doing
+	  hardware debugging with a logic analyzer and need to see all traffic
+	  on the bus.
+
+endmenu
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
new file mode 100644
index 0000000..bc1c442
--- /dev/null
+++ b/arch/mips/Makefile
@@ -0,0 +1,767 @@
+#
+# 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) 1994, 95, 96, 2003 by Ralf Baechle
+# DECStation modifications by Paul M. Antoine, 1996
+# Copyright (C) 2002, 2003, 2004  Maciej W. Rozycki
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies. Remember to do have actions
+# for "archclean" cleaning up for this architecture.
+#
+
+as-option = $(shell if $(CC) $(CFLAGS) $(1) -Wa,-Z -c -o /dev/null \
+	     -xassembler /dev/null > /dev/null 2>&1; then echo "$(1)"; \
+	     else echo "$(2)"; fi ;)
+
+cflags-y :=
+
+#
+# Select the object file format to substitute into the linker script.
+#
+ifdef CONFIG_CPU_LITTLE_ENDIAN
+32bit-tool-prefix	= mipsel-linux-
+64bit-tool-prefix	= mips64el-linux-
+32bit-bfd		= elf32-tradlittlemips
+64bit-bfd		= elf64-tradlittlemips
+32bit-emul		= elf32ltsmip
+64bit-emul		= elf64ltsmip
+else
+32bit-tool-prefix	= mips-linux-
+64bit-tool-prefix	= mips64-linux-
+32bit-bfd		= elf32-tradbigmips
+64bit-bfd		= elf64-tradbigmips
+32bit-emul		= elf32btsmip
+64bit-emul		= elf64btsmip
+endif
+
+ifdef CONFIG_MIPS32
+gcc-abi			= 32
+tool-prefix		= $(32bit-tool-prefix)
+UTS_MACHINE		:= mips
+endif
+ifdef CONFIG_MIPS64
+gcc-abi			= 64
+tool-prefix		= $(64bit-tool-prefix)
+UTS_MACHINE		:= mips64
+endif
+
+ifdef CONFIG_CROSSCOMPILE
+CROSS_COMPILE		:= $(tool-prefix)
+endif
+
+ifdef CONFIG_BUILD_ELF64
+gas-abi			= 64
+ld-emul			= $(64bit-emul)
+vmlinux-32		= vmlinux.32
+vmlinux-64		= vmlinux
+else
+gas-abi			= 32
+ld-emul			= $(32bit-emul)
+vmlinux-32		= vmlinux
+vmlinux-64		= vmlinux.64
+
+cflags-$(CONFIG_MIPS64)	+= $(call cc-option,-mno-explicit-relocs)
+endif
+
+#
+# GCC uses -G 0 -mabicalls -fpic as default.  We don't want PIC in the kernel
+# code since it only slows down the whole thing.  At some point we might make
+# use of global pointer optimizations but their use of $28 conflicts with
+# the current pointer optimization.
+#
+# The DECStation requires an ECOFF kernel for remote booting, other MIPS
+# machines may also.  Since BFD is incredibly buggy with respect to
+# crossformat linking we rely on the elf2ecoff tool for format conversion.
+#
+cflags-y			+= -I $(TOPDIR)/include/asm/gcc
+cflags-y			+= -G 0 -mno-abicalls -fno-pic -pipe
+cflags-y			+= $(call cc-option, -finline-limit=100000)
+LDFLAGS_vmlinux			+= -G 0 -static -n
+MODFLAGS			+= -mlong-calls
+
+cflags-$(CONFIG_SB1XXX_CORELIS)	+= -mno-sched-prolog -fno-omit-frame-pointer
+
+#
+# Use: $(call set_gccflags,<cpu0>,<isa0>,<cpu1>,<isa1>,<isa2>)
+#
+# <cpu0>,<isa0> -- preferred CPU and ISA designations (may require
+#                  recent tools)
+# <cpu1>,<isa1> -- fallback CPU and ISA designations (have to work
+#                  with up to the oldest supported tools)
+# <isa2>        -- an ISA designation used as an ABI selector for
+#                  gcc versions that do not support "-mabi=32"
+#                  (depending on the CPU type, either "mips1" or
+#                  "mips2")
+#
+set_gccflags = $(shell \
+while :; do \
+	cpu=$(1); isa=-$(2); \
+	for gcc_opt in -march= -mcpu=; do \
+		$(CC) $$gcc_opt$$cpu $$isa -S -o /dev/null \
+			-xc /dev/null > /dev/null 2>&1 && \
+			break 2; \
+	done; \
+	cpu=$(3); isa=-$(4); \
+	for gcc_opt in -march= -mcpu=; do \
+		$(CC) $$gcc_opt$$cpu $$isa -S -o /dev/null \
+			-xc /dev/null > /dev/null 2>&1 && \
+			break 2; \
+	done; \
+	break; \
+done; \
+gcc_abi=-mabi=$(gcc-abi); gcc_cpu=$$cpu; \
+if $(CC) $$gcc_abi -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then \
+	gcc_isa=$$isa; \
+else \
+	gcc_abi=; gcc_isa=-$(5); \
+fi; \
+gas_abi=-Wa,-$(gcc-abi); gas_cpu=$$cpu; gas_isa=-Wa,$$isa; \
+while :; do \
+	for gas_opt in -Wa,-march= -Wa,-mcpu=; do \
+		$(CC) $$gas_abi $$gas_opt$$cpu $$gas_isa -Wa,-Z -c \
+			-o /dev/null -xassembler /dev/null > /dev/null 2>&1 && \
+			break 2; \
+	done; \
+	gas_abi=; gas_opt=; gas_cpu=; gas_isa=; \
+	break; \
+done; \
+if test "$(gcc-abi)" != "$(gas-abi)"; then \
+	gas_abi="-Wa,-$(gas-abi) -Wa,-mgp$(gcc-abi)"; \
+fi; \
+if test "$$gcc_opt" = -march= && test -n "$$gcc_abi"; then \
+	$(CC) $$gcc_abi $$gcc_opt$$gcc_cpu -S -o /dev/null \
+		-xc /dev/null > /dev/null 2>&1 && \
+		gcc_isa=; \
+fi; \
+echo $$gcc_abi $$gcc_opt$$gcc_cpu $$gcc_isa $$gas_abi $$gas_opt$$gas_cpu $$gas_isa)
+
+#
+# CPU-dependent compiler/assembler options for optimization.
+#
+cflags-$(CONFIG_CPU_R3000)	+= \
+			$(call set_gccflags,r3000,mips1,r3000,mips1,mips1)
+
+cflags-$(CONFIG_CPU_TX39XX)	+= \
+			$(call set_gccflags,r3900,mips1,r3000,mips1,mips1)
+
+cflags-$(CONFIG_CPU_R6000)	+= \
+			$(call set_gccflags,r6000,mips2,r6000,mips2,mips2) \
+			-Wa,--trap
+
+cflags-$(CONFIG_CPU_R4300)	+= \
+			$(call set_gccflags,r4300,mips3,r4300,mips3,mips2) \
+			-Wa,--trap
+
+cflags-$(CONFIG_CPU_VR41XX)	+= \
+			$(call set_gccflags,r4100,mips3,r4600,mips3,mips2) \
+			-Wa,--trap
+
+cflags-$(CONFIG_CPU_R4X00)	+= \
+			$(call set_gccflags,r4600,mips3,r4600,mips3,mips2) \
+			-Wa,--trap
+
+cflags-$(CONFIG_CPU_TX49XX)	+= \
+			$(call set_gccflags,r4600,mips3,r4600,mips3,mips2)  \
+			-Wa,--trap
+
+cflags-$(CONFIG_CPU_MIPS32)	+= \
+			$(call set_gccflags,mips32,mips32,r4600,mips3,mips2) \
+			-Wa,--trap
+
+cflags-$(CONFIG_CPU_MIPS64)	+= \
+			$(call set_gccflags,mips64,mips64,r4600,mips3,mips2) \
+			-Wa,--trap
+
+cflags-$(CONFIG_CPU_R5000)	+= \
+			$(call set_gccflags,r5000,mips4,r5000,mips4,mips2) \
+			-Wa,--trap 
+
+cflags-$(CONFIG_CPU_R5432)	+= \
+			$(call set_gccflags,r5400,mips4,r5000,mips4,mips2) \
+			-Wa,--trap
+
+cflags-$(CONFIG_CPU_NEVADA)	+= \
+			$(call set_gccflags,rm5200,mips4,r5000,mips4,mips2) \
+			-Wa,--trap
+#			$(call cc-option,-mmad)
+
+cflags-$(CONFIG_CPU_RM7000)	+= \
+			$(call set_gccflags,rm7000,mips4,r5000,mips4,mips2) \
+			-Wa,--trap
+
+cflags-$(CONFIG_CPU_RM9000)	+= \
+			$(call set_gccflags,rm9000,mips4,r5000,mips4,mips2) \
+			-Wa,--trap
+
+cflags-$(CONFIG_CPU_SB1)	+= \
+			$(call set_gccflags,sb1,mips64,r5000,mips4,mips2) \
+			-Wa,--trap
+
+cflags-$(CONFIG_CPU_R8000)	+= \
+			$(call set_gccflags,r8000,mips4,r8000,mips4,mips2) \
+			-Wa,--trap
+
+cflags-$(CONFIG_CPU_R10000)	+= \
+			$(call set_gccflags,r10000,mips4,r8000,mips4,mips2) \
+			-Wa,--trap
+
+ifdef CONFIG_CPU_SB1
+ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+MODFLAGS	+= -msb1-pass1-workarounds
+endif
+endif
+
+#
+# Firmware support
+#
+libs-$(CONFIG_ARC)		+= arch/mips/arc/
+libs-$(CONFIG_SIBYTE_CFE)	+= arch/mips/sibyte/cfe/
+
+#
+# Board-dependent options and extra files
+#
+
+#
+# Acer PICA 61, Mips Magnum 4000 and Olivetti M700.
+#
+core-$(CONFIG_MACH_JAZZ)	+= arch/mips/jazz/
+cflags-$(CONFIG_MACH_JAZZ)	+= -Iinclude/asm-mips/mach-jazz
+load-$(CONFIG_MACH_JAZZ)	+= 0xffffffff80080000
+
+#
+# Common Alchemy Au1x00 stuff
+#
+core-$(CONFIG_SOC_AU1X00)	+= arch/mips/au1000/common/
+cflags-$(CONFIG_SOC_AU1X00)	+= -Iinclude/asm-mips/mach-au1x00
+
+#
+# AMD Alchemy Pb1000 eval board
+#
+libs-$(CONFIG_MIPS_PB1000)	+= arch/mips/au1000/pb1000/
+cflags-$(CONFIG_MIPS_PB1000)	+= -Iinclude/asm-mips/mach-pb1x00
+load-$(CONFIG_MIPS_PB1000)	+= 0xffffffff80100000
+
+#
+# AMD Alchemy Pb1100 eval board
+#
+libs-$(CONFIG_MIPS_PB1100)	+= arch/mips/au1000/pb1100/
+cflags-$(CONFIG_MIPS_PB1100)	+= -Iinclude/asm-mips/mach-pb1x00
+load-$(CONFIG_MIPS_PB1100)	+= 0xffffffff80100000
+
+#
+# AMD Alchemy Pb1500 eval board
+#
+libs-$(CONFIG_MIPS_PB1500)	+= arch/mips/au1000/pb1500/
+cflags-$(CONFIG_MIPS_PB1500)	+= -Iinclude/asm-mips/mach-pb1x00
+load-$(CONFIG_MIPS_PB1500)	+= 0xffffffff80100000
+
+#
+# AMD Alchemy Pb1550 eval board
+#
+libs-$(CONFIG_MIPS_PB1550)	+= arch/mips/au1000/pb1550/
+cflags-$(CONFIG_MIPS_PB1550)	+= -Iinclude/asm-mips/mach-pb1x00
+load-$(CONFIG_MIPS_PB1550)	+= 0xffffffff80100000
+
+#
+# AMD Alchemy Db1000 eval board
+#
+libs-$(CONFIG_MIPS_DB1000)	+= arch/mips/au1000/db1x00/
+cflags-$(CONFIG_MIPS_DB1000)	+= -Iinclude/asm-mips/mach-db1x00
+load-$(CONFIG_MIPS_DB1000)	+= 0xffffffff80100000
+
+#
+# AMD Alchemy Db1100 eval board
+#
+libs-$(CONFIG_MIPS_DB1100)	+= arch/mips/au1000/db1x00/
+cflags-$(CONFIG_MIPS_DB1100)	+= -Iinclude/asm-mips/mach-db1x00
+load-$(CONFIG_MIPS_DB1100)	+= 0xffffffff80100000
+
+#
+# AMD Alchemy Db1500 eval board
+#
+libs-$(CONFIG_MIPS_DB1500)	+= arch/mips/au1000/db1x00/
+cflags-$(CONFIG_MIPS_DB1500)	+= -Iinclude/asm-mips/mach-db1x00
+load-$(CONFIG_MIPS_DB1500)	+= 0xffffffff80100000
+
+#
+# AMD Alchemy Db1550 eval board
+#
+libs-$(CONFIG_MIPS_DB1550)	+= arch/mips/au1000/db1x00/
+cflags-$(CONFIG_MIPS_DB1550)	+= -Iinclude/asm-mips/mach-db1x00
+load-$(CONFIG_MIPS_DB1550)	+= 0xffffffff80100000
+
+#
+# AMD Alchemy Bosporus eval board
+#
+libs-$(CONFIG_MIPS_BOSPORUS)	+= arch/mips/au1000/db1x00/
+cflags-$(CONFIG_MIPS_BOSPORUS)	+= -Iinclude/asm-mips/mach-db1x00
+load-$(CONFIG_MIPS_BOSPORUS)	+= 0xffffffff80100000
+
+#
+# AMD Alchemy Mirage eval board
+#
+libs-$(CONFIG_MIPS_MIRAGE)	+= arch/mips/au1000/db1x00/
+cflags-$(CONFIG_MIPS_MIRAGE)	+= -Iinclude/asm-mips/mach-db1x00
+load-$(CONFIG_MIPS_MIRAGE)	+= 0xffffffff80100000
+
+#
+# 4G-Systems eval board
+#
+libs-$(CONFIG_MIPS_MTX1)	+= arch/mips/au1000/mtx-1/
+load-$(CONFIG_MIPS_MTX1)	+= 0xffffffff80100000
+
+#
+# MyCable eval board
+#
+libs-$(CONFIG_MIPS_XXS1500)	+= arch/mips/au1000/xxs1500/
+load-$(CONFIG_MIPS_XXS1500)	+= 0xffffffff80100000
+
+#
+# Cobalt Server
+#
+core-$(CONFIG_MIPS_COBALT)	+= arch/mips/cobalt/
+load-$(CONFIG_MIPS_COBALT)	+= 0xffffffff80080000
+
+#
+# DECstation family
+#
+core-$(CONFIG_MACH_DECSTATION)	+= arch/mips/dec/
+cflags-$(CONFIG_MACH_DECSTATION)+= -Iinclude/asm-mips/mach-dec
+libs-$(CONFIG_MACH_DECSTATION)	+= arch/mips/dec/prom/
+load-$(CONFIG_MACH_DECSTATION)	+= 0xffffffff80040000
+CLEAN_FILES			+= drivers/tc/lk201-map.c
+
+#
+# Galileo EV64120 Board
+#
+core-$(CONFIG_MIPS_EV64120)	+= arch/mips/gt64120/ev64120/
+core-$(CONFIG_MIPS_EV64120)	+= arch/mips/gt64120/common/
+cflags-$(CONFIG_MIPS_EV64120)	+= -Iinclude/asm-mips/mach-ev64120
+load-$(CONFIG_MIPS_EV64120)	+= 0xffffffff80100000
+
+#
+# Galileo EV96100 Board
+#
+core-$(CONFIG_MIPS_EV96100)	+= arch/mips/galileo-boards/ev96100/
+cflags-$(CONFIG_MIPS_EV96100)	+= -Iinclude/asm-mips/mach-ev96100
+load-$(CONFIG_MIPS_EV96100)	+= 0xffffffff80100000
+
+#
+# Globespan IVR eval board with QED 5231 CPU
+#
+core-$(CONFIG_ITE_BOARD_GEN)	+= arch/mips/ite-boards/generic/
+core-$(CONFIG_MIPS_IVR)		+= arch/mips/ite-boards/ivr/
+load-$(CONFIG_MIPS_IVR)		+= 0xffffffff80100000
+
+#
+# ITE 8172 eval board with QED 5231 CPU
+#
+core-$(CONFIG_MIPS_ITE8172)	+= arch/mips/ite-boards/qed-4n-s01b/
+load-$(CONFIG_MIPS_ITE8172)	+= 0xffffffff80100000
+
+#
+# For all MIPS, Inc. eval boards
+#
+core-$(CONFIG_MIPS_BOARDS_GEN)	+= arch/mips/mips-boards/generic/
+
+#
+# MIPS Atlas board
+#
+core-$(CONFIG_MIPS_ATLAS)	+= arch/mips/mips-boards/atlas/
+cflags-$(CONFIG_MIPS_ATLAS)	+= -Iinclude/asm-mips/mach-atlas
+cflags-$(CONFIG_MIPS_ATLAS)	+= -Iinclude/asm-mips/mach-mips
+load-$(CONFIG_MIPS_ATLAS)	+= 0xffffffff80100000
+
+#
+# MIPS Malta board
+#
+core-$(CONFIG_MIPS_MALTA)	+= arch/mips/mips-boards/malta/
+cflags-$(CONFIG_MIPS_MALTA)	+= -Iinclude/asm-mips/mach-mips
+load-$(CONFIG_MIPS_MALTA)	+= 0xffffffff80100000
+
+#
+# MIPS SEAD board
+#
+core-$(CONFIG_MIPS_SEAD)	+= arch/mips/mips-boards/sead/
+load-$(CONFIG_MIPS_SEAD)	+= 0xffffffff80100000
+
+#
+# Momentum Ocelot board
+#
+# The Ocelot setup.o must be linked early - it does the ioremap() for the
+# mips_io_port_base.
+#
+core-$(CONFIG_MOMENCO_OCELOT)	+= arch/mips/gt64120/common/ \
+				   arch/mips/gt64120/momenco_ocelot/
+cflags-$(CONFIG_MOMENCO_OCELOT)	+= -Iinclude/asm-mips/mach-ocelot
+load-$(CONFIG_MOMENCO_OCELOT)	+= 0xffffffff80100000
+
+#
+# Momentum Ocelot-G board
+#
+# The Ocelot-G setup.o must be linked early - it does the ioremap() for the
+# mips_io_port_base.
+#
+core-$(CONFIG_MOMENCO_OCELOT_G)	+= arch/mips/momentum/ocelot_g/
+load-$(CONFIG_MOMENCO_OCELOT_G)	+= 0xffffffff80100000
+
+#
+# Momentum Ocelot-C and -CS boards
+#
+# The Ocelot-C[S] setup.o must be linked early - it does the ioremap() for the
+# mips_io_port_base.
+core-$(CONFIG_MOMENCO_OCELOT_C)	+= arch/mips/momentum/ocelot_c/
+load-$(CONFIG_MOMENCO_OCELOT_C)	+= 0xffffffff80100000
+
+#
+# PMC-Sierra Yosemite
+#
+core-$(CONFIG_PMC_YOSEMITE)	+= arch/mips/pmc-sierra/yosemite/
+cflags-$(CONFIG_PMC_YOSEMITE)	+= -Iinclude/asm-mips/mach-yosemite
+load-$(CONFIG_PMC_YOSEMITE)	+= 0xffffffff80100000
+
+#
+# Momentum Ocelot-3
+#
+core-$(CONFIG_MOMENCO_OCELOT_3) 	+= arch/mips/momentum/ocelot_3/
+cflags-$(CONFIG_MOMENCO_OCELOT_3)	+= -Iinclude/asm-mips/mach-ocelot3
+load-$(CONFIG_MOMENCO_OCELOT_3) 	+= 0xffffffff80100000
+
+#
+# Momentum Jaguar ATX
+#
+core-$(CONFIG_MOMENCO_JAGUAR_ATX)	+= arch/mips/momentum/jaguar_atx/
+cflags-$(CONFIG_MOMENCO_JAGUAR_ATX)	+= -Iinclude/asm-mips/mach-ja
+#ifdef CONFIG_JAGUAR_DMALOW
+#load-$(CONFIG_MOMENCO_JAGUAR_ATX)	+= 0xffffffff88000000
+#else
+load-$(CONFIG_MOMENCO_JAGUAR_ATX)	+= 0xffffffff80100000
+#endif
+
+#
+# NEC DDB
+#
+core-$(CONFIG_DDB5XXX_COMMON)	+= arch/mips/ddb5xxx/common/
+
+#
+# NEC DDB Vrc-5074
+#
+core-$(CONFIG_DDB5074)		+= arch/mips/ddb5xxx/ddb5074/
+load-$(CONFIG_DDB5074)		+= 0xffffffff80080000
+
+#
+# NEC DDB Vrc-5476
+#
+core-$(CONFIG_DDB5476)		+= arch/mips/ddb5xxx/ddb5476/
+load-$(CONFIG_DDB5476)		+= 0xffffffff80080000
+
+#
+# NEC DDB Vrc-5477
+#
+core-$(CONFIG_DDB5477)		+= arch/mips/ddb5xxx/ddb5477/
+load-$(CONFIG_DDB5477)		+= 0xffffffff80100000
+
+core-$(CONFIG_LASAT)		+= arch/mips/lasat/
+cflags-$(CONFIG_LASAT)		+= -Iinclude/asm-mips/mach-lasat
+load-$(CONFIG_LASAT)		+= 0xffffffff80000000
+
+#
+# NEC Osprey (vr4181) board
+#
+core-$(CONFIG_NEC_OSPREY)	+= arch/mips/vr4181/common/ \
+				   arch/mips/vr4181/osprey/
+load-$(CONFIG_NEC_OSPREY)	+= 0xffffffff80002000
+
+#
+# Common VR41xx
+#
+core-$(CONFIG_MACH_VR41XX)	+= arch/mips/vr41xx/common/
+cflags-$(CONFIG_MACH_VR41XX)	+= -Iinclude/asm-mips/mach-vr41xx
+
+#
+# NEC VR4133
+#
+core-$(CONFIG_NEC_CMBVR4133)	+= arch/mips/vr41xx/nec-cmbvr4133/
+load-$(CONFIG_NEC_CMBVR4133)	+= 0xffffffff80100000
+
+#
+# ZAO Networks Capcella (VR4131)
+#
+core-$(CONFIG_ZAO_CAPCELLA)	+= arch/mips/vr41xx/zao-capcella/
+load-$(CONFIG_ZAO_CAPCELLA)	+= 0xffffffff80000000
+
+#
+# Victor MP-C303/304 (VR4122)
+#
+core-$(CONFIG_VICTOR_MPC30X)	+= arch/mips/vr41xx/victor-mpc30x/
+load-$(CONFIG_VICTOR_MPC30X)	+= 0xffffffff80001000
+
+#
+# IBM WorkPad z50 (VR4121)
+#
+core-$(CONFIG_IBM_WORKPAD)	+= arch/mips/vr41xx/ibm-workpad/
+load-$(CONFIG_IBM_WORKPAD)	+= 0xffffffff80004000
+
+#
+# CASIO CASSIPEIA E-55/65 (VR4111)
+#
+core-$(CONFIG_CASIO_E55)	+= arch/mips/vr41xx/casio-e55/
+load-$(CONFIG_CASIO_E55)	+= 0xffffffff80004000
+
+#
+# TANBAC TB0226 Mbase (VR4131)
+#
+core-$(CONFIG_TANBAC_TB0226)	+= arch/mips/vr41xx/tanbac-tb0226/
+load-$(CONFIG_TANBAC_TB0226)	+= 0xffffffff80000000
+
+#
+# TANBAC TB0229 VR4131DIMM (VR4131)
+#
+core-$(CONFIG_TANBAC_TB0229)	+= arch/mips/vr41xx/tanbac-tb0229/
+load-$(CONFIG_TANBAC_TB0229)	+= 0xffffffff80000000
+
+#
+# SGI IP22 (Indy/Indigo2)
+#
+# Set the load address to >= 0xffffffff88069000 if you want to leave space for
+# symmon, 0xffffffff80002000 for production kernels.  Note that the value must
+# be aligned to a multiple of the kernel stack size or the handling of the
+# current variable will break so for 64-bit kernels we have to raise the start
+# address by 8kb.
+#
+core-$(CONFIG_SGI_IP22)		+= arch/mips/sgi-ip22/
+cflags-$(CONFIG_SGI_IP22)	+= -Iinclude/asm-mips/mach-ip22
+ifdef CONFIG_MIPS32
+load-$(CONFIG_SGI_IP22)		+= 0xffffffff88002000
+endif
+ifdef CONFIG_MIPS64
+load-$(CONFIG_SGI_IP22)		+= 0xffffffff88004000
+endif
+
+#
+# SGI-IP27 (Origin200/2000)
+#
+# Set the load address to >= 0xc000000000300000 if you want to leave space for
+# symmon, 0xc00000000001c000 for production kernels.  Note that the value must
+# be 16kb aligned or the handling of the current variable will break.
+#
+ifdef CONFIG_SGI_IP27
+core-$(CONFIG_SGI_IP27)		+= arch/mips/sgi-ip27/
+cflags-$(CONFIG_SGI_IP27)	+= -Iinclude/asm-mips/mach-ip27
+ifdef CONFIG_BUILD_ELF64
+ifdef CONFIG_MAPPED_KERNEL
+load-$(CONFIG_SGI_IP27)		+= 0xc00000004001c000
+OBJCOPYFLAGS			:= --change-addresses=0x3fffffff80000000
+dataoffset-$(CONFIG_SGI_IP27)	+= 0x01000000
+else
+load-$(CONFIG_SGI_IP27)		+= 0xa80000000001c000
+OBJCOPYFLAGS			:= --change-addresses=0x57ffffff80000000
+endif
+else
+ifdef CONFIG_MAPPED_KERNEL
+load-$(CONFIG_SGI_IP27)		+= 0xffffffffc001c000
+OBJCOPYFLAGS			:= --change-addresses=0xc000000080000000
+dataoffset-$(CONFIG_SGI_IP27)	+= 0x01000000
+else
+load-$(CONFIG_SGI_IP27)		+= 0xffffffff8001c000
+OBJCOPYFLAGS			:= --change-addresses=0xa800000080000000
+endif
+endif
+endif
+
+#
+# SGI-IP32 (O2)
+#
+# Set the load address to >= 80069000 if you want to leave space for symmon,
+# 0xffffffff80004000 for production kernels.  Note that the value must be aligned to
+# a multiple of the kernel stack size or the handling of the current variable
+# will break.
+#
+core-$(CONFIG_SGI_IP32)		+= arch/mips/sgi-ip32/
+cflags-$(CONFIG_SGI_IP32)	+= -Iinclude/asm-mips/mach-ip32
+load-$(CONFIG_SGI_IP32)		+= 0xffffffff80004000
+
+#
+# Sibyte SB1250 SOC
+#
+# This is a LIB so that it links at the end, and initcalls are later
+# the sequence; but it is built as an object so that modules don't get
+# removed (as happens, even if they have __initcall/module_init)
+#
+core-$(CONFIG_SIBYTE_BCM112X)	+= arch/mips/sibyte/sb1250/
+cflags-$(CONFIG_SIBYTE_BCM112X)	+= -Iinclude/asm-mips/mach-sibyte
+
+core-$(CONFIG_SIBYTE_SB1250)	+= arch/mips/sibyte/sb1250/
+cflags-$(CONFIG_SIBYTE_SB1250)	+= -Iinclude/asm-mips/mach-sibyte
+
+#
+# Sibyte BCM91120x (Carmel) board
+# Sibyte BCM91120C (CRhine) board
+# Sibyte BCM91125C (CRhone) board
+# Sibyte BCM91125E (Rhone) board
+# Sibyte SWARM board
+#
+libs-$(CONFIG_SIBYTE_CARMEL)	+= arch/mips/sibyte/swarm/
+load-$(CONFIG_SIBYTE_CARMEL)	:= 0xffffffff80100000
+libs-$(CONFIG_SIBYTE_CRHINE)	+= arch/mips/sibyte/swarm/
+load-$(CONFIG_SIBYTE_CRHINE)	:= 0xffffffff80100000
+libs-$(CONFIG_SIBYTE_CRHONE)	+= arch/mips/sibyte/swarm/
+load-$(CONFIG_SIBYTE_CRHONE)	:= 0xffffffff80100000
+libs-$(CONFIG_SIBYTE_RHONE)	+= arch/mips/sibyte/swarm/
+load-$(CONFIG_SIBYTE_RHONE)	:= 0xffffffff80100000
+libs-$(CONFIG_SIBYTE_SENTOSA)	+= arch/mips/sibyte/swarm/
+load-$(CONFIG_SIBYTE_SENTOSA)	:= 0xffffffff80100000
+libs-$(CONFIG_SIBYTE_SWARM)	+= arch/mips/sibyte/swarm/
+load-$(CONFIG_SIBYTE_SWARM)	:= 0xffffffff80100000
+
+#
+# SNI RM200 PCI
+#
+core-$(CONFIG_SNI_RM200_PCI)	+= arch/mips/sni/
+cflags-$(CONFIG_SNI_RM200_PCI)	+= -Iinclude/asm-mips/mach-rm200
+load-$(CONFIG_SNI_RM200_PCI)	+= 0xffffffff80600000
+
+#
+# Toshiba JMR-TX3927 board
+#
+core-$(CONFIG_TOSHIBA_JMR3927)	+= arch/mips/jmr3927/rbhma3100/ \
+				   arch/mips/jmr3927/common/
+load-$(CONFIG_TOSHIBA_JMR3927)	+= 0xffffffff80050000
+
+#
+# Toshiba RBTX4927 board or
+# Toshiba RBTX4937 board
+#
+core-$(CONFIG_TOSHIBA_RBTX4927)	+= arch/mips/tx4927/toshiba_rbtx4927/
+core-$(CONFIG_TOSHIBA_RBTX4927)	+= arch/mips/tx4927/common/
+load-$(CONFIG_TOSHIBA_RBTX4927)	+= 0xffffffff80020000
+
+cflags-y			+= -Iinclude/asm-mips/mach-generic
+drivers-$(CONFIG_PCI)		+= arch/mips/pci/
+
+ifdef CONFIG_MIPS32
+ifdef CONFIG_CPU_LITTLE_ENDIAN
+JIFFIES			= jiffies_64
+else
+JIFFIES			= jiffies_64 + 4
+endif
+else
+JIFFIES			= jiffies_64
+endif
+
+AFLAGS		+= $(cflags-y)
+CFLAGS		+= $(cflags-y)
+
+LDFLAGS			+= -m $(ld-emul)
+
+OBJCOPYFLAGS		+= --remove-section=.reginfo
+
+#
+# Choosing incompatible machines durings configuration will result in
+# error messages during linking.  Select a default linkscript if
+# none has been choosen above.
+#
+
+CPPFLAGS_vmlinux.lds := \
+	$(CFLAGS) \
+	-D"LOADADDR=$(load-y)" \
+	-D"JIFFIES=$(JIFFIES)" \
+	-D"DATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0)"
+
+head-y := arch/mips/kernel/head.o arch/mips/kernel/init_task.o
+
+libs-y			+= arch/mips/lib/
+libs-$(CONFIG_MIPS32)	+= arch/mips/lib-32/
+libs-$(CONFIG_MIPS64)	+= arch/mips/lib-64/
+
+core-y			+= arch/mips/kernel/ arch/mips/mm/ arch/mips/math-emu/
+
+drivers-$(CONFIG_OPROFILE)	+= arch/mips/oprofile/
+
+ifdef CONFIG_LASAT
+rom.bin rom.sw: vmlinux
+	$(call descend,arch/mips/lasat/image,$@)
+endif
+
+#
+# Some machines like the Indy need 32-bit ELF binaries for booting purposes.
+# Other need ECOFF, so we build a 32-bit ELF binary for them which we then
+# convert to ECOFF using elf2ecoff.
+#
+vmlinux.32: vmlinux
+	$(OBJCOPY) -O $(32bit-bfd) $(OBJCOPYFLAGS) $< $@
+
+#
+# The 64-bit ELF tools are pretty broken so at this time we generate 64-bit
+# ELF files from 32-bit files by conversion.
+#
+vmlinux.64: vmlinux
+	$(OBJCOPY) -O $(64bit-bfd) $(OBJCOPYFLAGS) $< $@
+
+makeboot =$(Q)$(MAKE) $(build)=arch/mips/boot VMLINUX=$(vmlinux-32) $(1)
+
+ifdef CONFIG_BOOT_ELF32
+all:	$(vmlinux-32)
+endif
+
+ifdef CONFIG_BOOT_ELF64
+all:	$(vmlinux-64)
+endif
+
+ifdef CONFIG_SNI_RM200_PCI
+all:	vmlinux.ecoff
+endif
+
+vmlinux.ecoff vmlinux.rm200: $(vmlinux-32)
+	+@$(call makeboot,$@)
+
+vmlinux.srec: $(vmlinux-32)
+	+@$(call makeboot,$@)
+
+CLEAN_FILES += vmlinux.ecoff \
+	       vmlinux.srec \
+	       vmlinux.rm200.tmp \
+	       vmlinux.rm200
+
+archclean:
+	@$(MAKE) $(clean)=arch/mips/boot
+	@$(MAKE) $(clean)=arch/mips/lasat
+
+# Generate <asm/offset.h 
+#
+# The default rule is suffering from funny problems on MIPS so we using our
+# own ...
+#
+# ---------------------------------------------------------------------------
+
+define filechk_gen-asm-offset.h
+	(set -e; \
+	 echo "#ifndef _ASM_OFFSET_H"; \
+	 echo "#define _ASM_OFFSET_H"; \
+	 echo "/*"; \
+	 echo " * DO NOT MODIFY."; \
+	 echo " *"; \
+	 echo " * This file was generated by arch/$(ARCH)/Makefile"; \
+	 echo " *"; \
+	 echo " */"; \
+	 echo ""; \
+	 sed -ne "/^@@@/s///p"; \
+	 echo "#endif /* _ASM_OFFSET_H */" )
+endef
+
+prepare: include/asm-$(ARCH)/offset.h
+
+arch/$(ARCH)/kernel/offset.s: include/asm include/linux/version.h \
+				   include/config/MARKER
+
+include/asm-$(ARCH)/offset.h: arch/$(ARCH)/kernel/offset.s
+	$(call filechk,gen-asm-offset.h)
+
+CLEAN_FILES += include/asm-$(ARCH)/offset.h.tmp \
+	       include/asm-$(ARCH)/offset.h \
+	       vmlinux.32 \
+	       vmlinux.64 \
+	       vmlinux.ecoff
diff --git a/arch/mips/arc/Makefile b/arch/mips/arc/Makefile
new file mode 100644
index 0000000..e842493
--- /dev/null
+++ b/arch/mips/arc/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the ARC prom monitor library routines under Linux.
+#
+
+lib-y				+= cmdline.o env.o file.o identify.o init.o \
+				   misc.o time.o tree.o
+
+lib-$(CONFIG_ARC_MEMORY)	+= memory.o
+lib-$(CONFIG_ARC_CONSOLE)	+= arc_con.o
+lib-$(CONFIG_ARC_PROMLIB)	+= promlib.o
diff --git a/arch/mips/arc/arc_con.c b/arch/mips/arc/arc_con.c
new file mode 100644
index 0000000..51785a6
--- /dev/null
+++ b/arch/mips/arc/arc_con.c
@@ -0,0 +1,50 @@
+/*
+ * Wrap-around code for a console using the
+ * ARC io-routines.
+ *
+ * Copyright (c) 1998 Harald Koerfgen
+ * Copyright (c) 2001 Ralf Baechle
+ * Copyright (c) 2002 Thiemo Seufer
+ */
+#include <linux/tty.h>
+#include <linux/major.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/fs.h>
+#include <asm/sgialib.h>
+
+static void prom_console_write(struct console *co, const char *s,
+			       unsigned count)
+{
+	/* Do each character */
+	while (count--) {
+		if (*s == '\n')
+			prom_putchar('\r');
+		prom_putchar(*s++);
+	}
+}
+
+static int __init prom_console_setup(struct console *co, char *options)
+{
+	return !(prom_flags & PROM_FLAG_USE_AS_CONSOLE);
+}
+
+static struct console arc_cons = {
+	.name		= "arc",
+	.write		= prom_console_write,
+	.setup		= prom_console_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= -1,
+};
+
+/*
+ *    Register console.
+ */
+
+static int __init arc_console_init(void)
+{
+	register_console(&arc_cons);
+
+	return 0;
+}
+console_initcall(arc_console_init);
diff --git a/arch/mips/arc/cmdline.c b/arch/mips/arc/cmdline.c
new file mode 100644
index 0000000..fd604ef
--- /dev/null
+++ b/arch/mips/arc/cmdline.c
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ *
+ * cmdline.c: Kernel command line creation using ARCS argc/argv.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#include <asm/sgialib.h>
+#include <asm/bootinfo.h>
+
+#undef DEBUG_CMDLINE
+
+char * __init prom_getcmdline(void)
+{
+	return arcs_cmdline;
+}
+
+static char *ignored[] = {
+	"ConsoleIn=",
+	"ConsoleOut=",
+	"SystemPartition=",
+	"OSLoader=",
+	"OSLoadPartition=",
+	"OSLoadFilename=",
+	"OSLoadOptions="
+};
+
+static char *used_arc[][2] = {
+	{ "OSLoadPartition=", "root=" },
+	{ "OSLoadOptions=", "" }
+};
+
+static char * __init move_firmware_args(char* cp)
+{
+	char *s;
+	int actr, i;
+
+	actr = 1; /* Always ignore argv[0] */
+
+	while (actr < prom_argc) {
+		for(i = 0; i < ARRAY_SIZE(used_arc); i++) {
+			int len = strlen(used_arc[i][0]);
+
+			if (!strncmp(prom_argv(actr), used_arc[i][0], len)) {
+			/* Ok, we want it. First append the replacement... */
+				strcat(cp, used_arc[i][1]);
+				cp += strlen(used_arc[i][1]);
+				/* ... and now the argument */
+				s = strstr(prom_argv(actr), "=");
+				if (s) {
+					s++;
+					strcpy(cp, s);
+					cp += strlen(s);
+				}
+				*cp++ = ' ';
+				break;
+			}
+		}
+		actr++;
+	}
+
+	return cp;
+}
+
+void __init prom_init_cmdline(void)
+{
+	char *cp;
+	int actr, i;
+
+	actr = 1; /* Always ignore argv[0] */
+
+	cp = arcs_cmdline;
+	/*
+	 * Move ARC variables to the beginning to make sure they can be
+	 * overridden by later arguments.
+	 */
+	cp = move_firmware_args(cp);
+
+	while (actr < prom_argc) {
+		for (i = 0; i < ARRAY_SIZE(ignored); i++) {
+			int len = strlen(ignored[i]);
+
+			if (!strncmp(prom_argv(actr), ignored[i], len))
+				goto pic_cont;
+		}
+		/* Ok, we want it. */
+		strcpy(cp, prom_argv(actr));
+		cp += strlen(prom_argv(actr));
+		*cp++ = ' ';
+
+	pic_cont:
+		actr++;
+	}
+
+	if (cp != arcs_cmdline)		/* get rid of trailing space */
+		--cp;
+	*cp = '\0';
+
+#ifdef DEBUG_CMDLINE
+	printk(KERN_DEBUG "prom cmdline: %s\n", arcs_cmdline);
+#endif
+}
diff --git a/arch/mips/arc/console.c b/arch/mips/arc/console.c
new file mode 100644
index 0000000..6a9d144
--- /dev/null
+++ b/arch/mips/arc/console.c
@@ -0,0 +1,63 @@
+/*
+ * 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) 1996 David S. Miller (dm@sgi.com)
+ * Compability with board caches, Ulf Carlsson
+ */
+#include <linux/kernel.h>
+#include <asm/sgialib.h>
+#include <asm/bcache.h>
+
+/*
+ * IP22 boardcache is not compatible with board caches.  Thus we disable it
+ * during romvec action.  Since r4xx0.c is always compiled and linked with your
+ * kernel, this shouldn't cause any harm regardless what MIPS processor you
+ * have.
+ *
+ * The ARC write and read functions seem to interfere with the serial lines
+ * in some way. You should be careful with them.
+ */
+
+void prom_putchar(char c)
+{
+	ULONG cnt;
+	CHAR it = c;
+
+	bc_disable();
+	ArcWrite(1, &it, 1, &cnt);
+	bc_enable();
+}
+
+char prom_getchar(void)
+{
+	ULONG cnt;
+	CHAR c;
+
+	bc_disable();
+	ArcRead(0, &c, 1, &cnt);
+	bc_enable();
+
+	return c;
+}
+
+void prom_printf(char *fmt, ...)
+{
+	va_list args;
+	char ppbuf[1024];
+	char *bptr;
+
+	va_start(args, fmt);
+	vsprintf(ppbuf, fmt, args);
+
+	bptr = ppbuf;
+
+	while (*bptr != 0) {
+		if (*bptr == '\n')
+			prom_putchar('\r');
+
+		prom_putchar(*bptr++);
+	}
+	va_end(args);
+}
diff --git a/arch/mips/arc/env.c b/arch/mips/arc/env.c
new file mode 100644
index 0000000..e521a6e
--- /dev/null
+++ b/arch/mips/arc/env.c
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ *
+ * env.c: ARCS environment variable routines.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#include <asm/arc/types.h>
+#include <asm/sgialib.h>
+
+PCHAR __init
+ArcGetEnvironmentVariable(CHAR *name)
+{
+	return (CHAR *) ARC_CALL1(get_evar, name);
+}
+
+LONG __init
+ArcSetEnvironmentVariable(PCHAR name, PCHAR value)
+{
+	return ARC_CALL2(set_evar, name, value);
+}
diff --git a/arch/mips/arc/file.c b/arch/mips/arc/file.c
new file mode 100644
index 0000000..a43425b
--- /dev/null
+++ b/arch/mips/arc/file.c
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ *
+ * ARC firmware interface.
+ *
+ * Copyright (C) 1994, 1995, 1996, 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/init.h>
+
+#include <asm/arc/types.h>
+#include <asm/sgialib.h>
+
+LONG __init
+ArcGetDirectoryEntry(ULONG FileID, struct linux_vdirent *Buffer,
+                     ULONG N, ULONG *Count)
+{
+	return ARC_CALL4(get_vdirent, FileID, Buffer, N, Count);
+}
+
+LONG __init
+ArcOpen(CHAR *Path, enum linux_omode OpenMode, ULONG *FileID)
+{
+	return ARC_CALL3(open, Path, OpenMode, FileID);
+}
+
+LONG __init
+ArcClose(ULONG FileID)
+{
+	return ARC_CALL1(close, FileID);
+}
+
+LONG __init
+ArcRead(ULONG FileID, VOID *Buffer, ULONG N, ULONG *Count)
+{
+	return ARC_CALL4(read, FileID, Buffer, N, Count);
+}
+
+LONG __init
+ArcGetReadStatus(ULONG FileID)
+{
+	return ARC_CALL1(get_rstatus, FileID);
+}
+
+LONG __init
+ArcWrite(ULONG FileID, PVOID Buffer, ULONG N, PULONG Count)
+{
+	return ARC_CALL4(write, FileID, Buffer, N, Count);
+}
+
+LONG __init
+ArcSeek(ULONG FileID, struct linux_bigint *Position, enum linux_seekmode SeekMode)
+{
+	return ARC_CALL3(seek, FileID, Position, SeekMode);
+}
+
+LONG __init
+ArcMount(char *name, enum linux_mountops op)
+{
+	return ARC_CALL2(mount, name, op);
+}
+
+LONG __init
+ArcGetFileInformation(ULONG FileID, struct linux_finfo *Information)
+{
+	return ARC_CALL2(get_finfo, FileID, Information);
+}
+
+LONG __init ArcSetFileInformation(ULONG FileID, ULONG AttributeFlags,
+                                  ULONG AttributeMask)
+{
+	return ARC_CALL3(set_finfo, FileID, AttributeFlags, AttributeMask);
+}
diff --git a/arch/mips/arc/identify.c b/arch/mips/arc/identify.c
new file mode 100644
index 0000000..0dd7a34
--- /dev/null
+++ b/arch/mips/arc/identify.c
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ *
+ * identify.c: identify machine by looking up system identifier
+ *
+ * Copyright (C) 1998 Thomas Bogendoerfer
+ *
+ * This code is based on arch/mips/sgi/kernel/system.c, which is
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/string.h>
+
+#include <asm/sgialib.h>
+#include <asm/bootinfo.h>
+
+struct smatch {
+	char *arcname;
+	char *liname;
+	int group;
+	int type;
+	int flags;
+};
+
+static struct smatch mach_table[] = {
+	{	"SGI-IP22",
+		"SGI Indy",
+		MACH_GROUP_SGI,
+		MACH_SGI_IP22,
+		PROM_FLAG_ARCS
+	}, {	"SGI-IP27",
+		"SGI Origin",
+		MACH_GROUP_SGI,
+		MACH_SGI_IP27,
+		PROM_FLAG_ARCS
+	}, {	"SGI-IP28",
+		"SGI IP28",
+		MACH_GROUP_SGI,
+		MACH_SGI_IP28,
+		PROM_FLAG_ARCS
+	}, {	"SGI-IP32",
+		"SGI O2",
+		MACH_GROUP_SGI,
+		MACH_SGI_IP32,
+		PROM_FLAG_ARCS
+	}, {	"Microsoft-Jazz",
+		"Jazz MIPS_Magnum_4000",
+		MACH_GROUP_JAZZ,
+		MACH_MIPS_MAGNUM_4000,
+		0
+	}, {	"PICA-61",
+		"Jazz Acer_PICA_61",
+		MACH_GROUP_JAZZ,
+		MACH_ACER_PICA_61,
+		0
+	}, {	"RM200PCI",
+		"SNI RM200_PCI",
+		MACH_GROUP_SNI_RM,
+		MACH_SNI_RM200_PCI,
+		PROM_FLAG_DONT_FREE_TEMP
+	}
+};
+
+int prom_flags;
+
+static struct smatch * __init string_to_mach(const char *s)
+{
+	int i;
+
+	for (i = 0; i < (sizeof(mach_table) / sizeof (mach_table[0])); i++) {
+		if (!strcmp(s, mach_table[i].arcname))
+			return &mach_table[i];
+	}
+
+	panic("Yeee, could not determine architecture type <%s>", s);
+}
+
+char *system_type;
+
+const char *get_system_type(void)
+{
+	return system_type;
+}
+
+void __init prom_identify_arch(void)
+{
+	pcomponent *p;
+	struct smatch *mach;
+	const char *iname;
+
+	/*
+	 * The root component tells us what machine architecture we have here.
+	 */
+	p = ArcGetChild(PROM_NULL_COMPONENT);
+	if (p == NULL) {
+#ifdef CONFIG_SGI_IP27
+		/* IP27 PROM misbehaves, seems to not implement ARC
+		   GetChild().  So we just assume it's an IP27.  */
+		iname = "SGI-IP27";
+#else
+		iname = "Unknown";
+#endif
+	} else
+		iname = (char *) (long) p->iname;
+
+	printk("ARCH: %s\n", iname);
+	mach = string_to_mach(iname);
+	system_type = mach->liname;
+
+	mips_machgroup = mach->group;
+	mips_machtype = mach->type;
+	prom_flags = mach->flags;
+}
diff --git a/arch/mips/arc/init.c b/arch/mips/arc/init.c
new file mode 100644
index 0000000..76ab505
--- /dev/null
+++ b/arch/mips/arc/init.c
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ *
+ * PROM library initialisation code.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+#include <asm/bootinfo.h>
+#include <asm/sgialib.h>
+
+#undef DEBUG_PROM_INIT
+
+/* Master romvec interface. */
+struct linux_romvec *romvec;
+int prom_argc;
+LONG *_prom_argv, *_prom_envp;
+
+void __init prom_init(void)
+{
+	PSYSTEM_PARAMETER_BLOCK pb = PROMBLOCK;
+	romvec = ROMVECTOR;
+	prom_argc = fw_arg0;
+	_prom_argv = (LONG *) fw_arg1;
+	_prom_envp = (LONG *) fw_arg2;
+
+	if (pb->magic != 0x53435241) {
+		prom_printf("Aieee, bad prom vector magic %08lx\n", pb->magic);
+		while(1)
+			;
+	}
+
+	prom_init_cmdline();
+	prom_identify_arch();
+	printk(KERN_INFO "PROMLIB: ARC firmware Version %d Revision %d\n",
+	       pb->ver, pb->rev);
+	prom_meminit();
+
+#ifdef DEBUG_PROM_INIT
+	prom_printf("Press a key to reboot\n");
+	prom_getchar();
+	ArcEnterInteractiveMode();
+#endif
+}
diff --git a/arch/mips/arc/memory.c b/arch/mips/arc/memory.c
new file mode 100644
index 0000000..958d2eb
--- /dev/null
+++ b/arch/mips/arc/memory.c
@@ -0,0 +1,170 @@
+/*
+ * memory.c: PROM library functions for acquiring/using memory descriptors
+ *           given to us from the ARCS firmware.
+ *
+ * Copyright (C) 1996 by David S. Miller
+ * Copyright (C) 1999, 2000, 2001 by Ralf Baechle
+ * Copyright (C) 1999, 2000 by Silicon Graphics, Inc.
+ *
+ * PROM library functions for acquiring/using memory descriptors given to us
+ * from the ARCS firmware.  This is only used when CONFIG_ARC_MEMORY is set
+ * because on some machines like SGI IP27 the ARC memory configuration data
+ * completly bogus and alternate easier to use mechanisms are available.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/swap.h>
+
+#include <asm/sgialib.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/bootinfo.h>
+
+#undef DEBUG
+
+/*
+ * For ARC firmware memory functions the unit of meassuring memory is always
+ * a 4k page of memory
+ */
+#define ARC_PAGE_SHIFT	12
+
+struct linux_mdesc * __init ArcGetMemoryDescriptor(struct linux_mdesc *Current)
+{
+	return (struct linux_mdesc *) ARC_CALL1(get_mdesc, Current);
+}
+
+#ifdef DEBUG /* convenient for debugging */
+static char *arcs_mtypes[8] = {
+	"Exception Block",
+	"ARCS Romvec Page",
+	"Free/Contig RAM",
+	"Generic Free RAM",
+	"Bad Memory",
+	"Standalone Program Pages",
+	"ARCS Temp Storage Area",
+	"ARCS Permanent Storage Area"
+};
+
+static char *arc_mtypes[8] = {
+	"Exception Block",
+	"SystemParameterBlock",
+	"FreeMemory",
+	"Bad Memory",
+	"LoadedProgram",
+	"FirmwareTemporary",
+	"FirmwarePermanent",
+	"FreeContiguous"
+};
+#define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] \
+						: arc_mtypes[a.arc]
+#endif
+
+static inline int memtype_classify_arcs (union linux_memtypes type)
+{
+	switch (type.arcs) {
+	case arcs_fcontig:
+	case arcs_free:
+		return BOOT_MEM_RAM;
+	case arcs_atmp:
+		return BOOT_MEM_ROM_DATA;
+	case arcs_eblock:
+	case arcs_rvpage:
+	case arcs_bmem:
+	case arcs_prog:
+	case arcs_aperm:
+		return BOOT_MEM_RESERVED;
+	default:
+		BUG();
+	}
+	while(1);				/* Nuke warning.  */
+}
+
+static inline int memtype_classify_arc (union linux_memtypes type)
+{
+	switch (type.arc) {
+	case arc_free:
+	case arc_fcontig:
+		return BOOT_MEM_RAM;
+	case arc_atmp:
+		return BOOT_MEM_ROM_DATA;
+	case arc_eblock:
+	case arc_rvpage:
+	case arc_bmem:
+	case arc_prog:
+	case arc_aperm:
+		return BOOT_MEM_RESERVED;
+	default:
+		BUG();
+	}
+	while(1);				/* Nuke warning.  */
+}
+
+static int __init prom_memtype_classify (union linux_memtypes type)
+{
+	if (prom_flags & PROM_FLAG_ARCS)	/* SGI is ``different'' ... */
+		return memtype_classify_arcs(type);
+
+	return memtype_classify_arc(type);
+}
+
+void __init prom_meminit(void)
+{
+	struct linux_mdesc *p;
+
+#ifdef DEBUG
+	int i = 0;
+
+	prom_printf("ARCS MEMORY DESCRIPTOR dump:\n");
+	p = ArcGetMemoryDescriptor(PROM_NULL_MDESC);
+	while(p) {
+		prom_printf("[%d,%p]: base<%08lx> pages<%08lx> type<%s>\n",
+			    i, p, p->base, p->pages, mtypes(p->type));
+		p = ArcGetMemoryDescriptor(p);
+		i++;
+	}
+#endif
+
+	p = PROM_NULL_MDESC;
+	while ((p = ArcGetMemoryDescriptor(p))) {
+		unsigned long base, size;
+		long type;
+
+		base = p->base << ARC_PAGE_SHIFT;
+		size = p->pages << ARC_PAGE_SHIFT;
+		type = prom_memtype_classify(p->type);
+
+		add_memory_region(base, size, type);
+	}
+}
+
+unsigned long __init prom_free_prom_memory(void)
+{
+	unsigned long freed = 0;
+	unsigned long addr;
+	int i;
+
+	if (prom_flags & PROM_FLAG_DONT_FREE_TEMP)
+		return 0;
+
+	for (i = 0; i < boot_mem_map.nr_map; i++) {
+		if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
+			continue;
+
+		addr = boot_mem_map.map[i].addr;
+		while (addr < boot_mem_map.map[i].addr
+			      + boot_mem_map.map[i].size) {
+			ClearPageReserved(virt_to_page(__va(addr)));
+			set_page_count(virt_to_page(__va(addr)), 1);
+			free_page((unsigned long)__va(addr));
+			addr += PAGE_SIZE;
+			freed += PAGE_SIZE;
+		}
+	}
+	printk(KERN_INFO "Freeing prom memory: %ldkb freed\n", freed >> 10);
+
+	return freed;
+}
diff --git a/arch/mips/arc/misc.c b/arch/mips/arc/misc.c
new file mode 100644
index 0000000..84867de
--- /dev/null
+++ b/arch/mips/arc/misc.c
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ *
+ * Miscellaneous ARCS PROM routines.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+#include <asm/bcache.h>
+
+#include <asm/arc/types.h>
+#include <asm/sgialib.h>
+#include <asm/bootinfo.h>
+#include <asm/system.h>
+
+extern void *sgiwd93_host;
+extern void reset_wd33c93(void *instance);
+
+VOID
+ArcHalt(VOID)
+{
+	bc_disable();
+	local_irq_disable();
+#ifdef CONFIG_SCSI_SGIWD93
+	reset_wd33c93(sgiwd93_host);
+#endif
+	ARC_CALL0(halt);
+never:	goto never;
+}
+
+VOID
+ArcPowerDown(VOID)
+{
+	bc_disable();
+	local_irq_disable();
+#ifdef CONFIG_SCSI_SGIWD93
+	reset_wd33c93(sgiwd93_host);
+#endif
+	ARC_CALL0(pdown);
+never:	goto never;
+}
+
+/* XXX is this a soft reset basically? XXX */
+VOID
+ArcRestart(VOID)
+{
+	bc_disable();
+	local_irq_disable();
+#ifdef CONFIG_SCSI_SGIWD93
+	reset_wd33c93(sgiwd93_host);
+#endif
+	ARC_CALL0(restart);
+never:	goto never;
+}
+
+VOID
+ArcReboot(VOID)
+{
+	bc_disable();
+	local_irq_disable();
+#ifdef CONFIG_SCSI_SGIWD93
+	reset_wd33c93(sgiwd93_host);
+#endif
+	ARC_CALL0(reboot);
+never:	goto never;
+}
+
+VOID
+ArcEnterInteractiveMode(VOID)
+{
+	bc_disable();
+	local_irq_disable();
+#ifdef CONFIG_SCSI_SGIWD93
+	reset_wd33c93(sgiwd93_host);
+#endif
+	ARC_CALL0(imode);
+never:	goto never;
+}
+
+LONG
+ArcSaveConfiguration(VOID)
+{
+	return ARC_CALL0(cfg_save);
+}
+
+struct linux_sysid *
+ArcGetSystemId(VOID)
+{
+	return (struct linux_sysid *) ARC_CALL0(get_sysid);
+}
+
+VOID __init
+ArcFlushAllCaches(VOID)
+{
+	ARC_CALL0(cache_flush);
+}
+
+DISPLAY_STATUS * __init ArcGetDisplayStatus(ULONG FileID)
+{
+	return (DISPLAY_STATUS *) ARC_CALL1(GetDisplayStatus, FileID);
+}
diff --git a/arch/mips/arc/promlib.c b/arch/mips/arc/promlib.c
new file mode 100644
index 0000000..c508c00
--- /dev/null
+++ b/arch/mips/arc/promlib.c
@@ -0,0 +1,43 @@
+/*
+ * 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) 1996 David S. Miller (dm@sgi.com)
+ * Compability with board caches, Ulf Carlsson
+ */
+#include <linux/kernel.h>
+#include <asm/sgialib.h>
+#include <asm/bcache.h>
+
+/*
+ * IP22 boardcache is not compatible with board caches.  Thus we disable it
+ * during romvec action.  Since r4xx0.c is always compiled and linked with your
+ * kernel, this shouldn't cause any harm regardless what MIPS processor you
+ * have.
+ *
+ * The ARC write and read functions seem to interfere with the serial lines
+ * in some way. You should be careful with them.
+ */
+
+void prom_putchar(char c)
+{
+	ULONG cnt;
+	CHAR it = c;
+
+	bc_disable();
+	ArcWrite(1, &it, 1, &cnt);
+	bc_enable();
+}
+
+char prom_getchar(void)
+{
+	ULONG cnt;
+	CHAR c;
+
+	bc_disable();
+	ArcRead(0, &c, 1, &cnt);
+	bc_enable();
+
+	return c;
+}
diff --git a/arch/mips/arc/salone.c b/arch/mips/arc/salone.c
new file mode 100644
index 0000000..e6afb64
--- /dev/null
+++ b/arch/mips/arc/salone.c
@@ -0,0 +1,24 @@
+/*
+ * Routines to load into memory and execute stand-along program images using
+ * ARCS PROM firmware.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ */
+#include <linux/init.h>
+#include <asm/sgialib.h>
+
+LONG __init ArcLoad(CHAR *Path, ULONG TopAddr, ULONG *ExecAddr, ULONG *LowAddr)
+{
+	return ARC_CALL4(load, Path, TopAddr, ExecAddr, LowAddr);
+}
+
+LONG __init ArcInvoke(ULONG ExecAddr, ULONG StackAddr, ULONG Argc, CHAR *Argv[],
+	CHAR *Envp[])
+{
+	return ARC_CALL5(invoke, ExecAddr, StackAddr, Argc, Argv, Envp);
+}
+
+LONG __init ArcExecute(CHAR *Path, LONG Argc, CHAR *Argv[], CHAR *Envp[])
+{
+	return ARC_CALL4(exec, Path, Argc, Argv, Envp);
+}
diff --git a/arch/mips/arc/time.c b/arch/mips/arc/time.c
new file mode 100644
index 0000000..299ff2c
--- /dev/null
+++ b/arch/mips/arc/time.c
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ *
+ * Extracting time information from ARCS prom.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ */
+#include <linux/init.h>
+
+#include <asm/arc/types.h>
+#include <asm/sgialib.h>
+
+struct linux_tinfo * __init
+ArcGetTime(VOID)
+{
+	return (struct linux_tinfo *) ARC_CALL0(get_tinfo);
+}
+
+ULONG __init
+ArcGetRelativeTime(VOID)
+{
+	return ARC_CALL0(get_rtime);
+}
diff --git a/arch/mips/arc/tree.c b/arch/mips/arc/tree.c
new file mode 100644
index 0000000..2aedd4f
--- /dev/null
+++ b/arch/mips/arc/tree.c
@@ -0,0 +1,127 @@
+/*
+ * 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.
+ *
+ * PROM component device tree code.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/init.h>
+#include <asm/arc/types.h>
+#include <asm/sgialib.h>
+
+#undef DEBUG_PROM_TREE
+
+pcomponent * __init
+ArcGetPeer(pcomponent *Current)
+{
+	if (Current == PROM_NULL_COMPONENT)
+		return PROM_NULL_COMPONENT;
+
+	return (pcomponent *) ARC_CALL1(next_component, Current);
+}
+
+pcomponent * __init
+ArcGetChild(pcomponent *Current)
+{
+	return (pcomponent *) ARC_CALL1(child_component, Current);
+}
+
+pcomponent * __init
+ArcGetParent(pcomponent *Current)
+{
+	if (Current == PROM_NULL_COMPONENT)
+		return PROM_NULL_COMPONENT;
+
+	return (pcomponent *) ARC_CALL1(parent_component, Current);
+}
+
+LONG __init
+ArcGetConfigurationData(VOID *Buffer, pcomponent *Current)
+{
+	return ARC_CALL2(component_data, Buffer, Current);
+}
+
+pcomponent * __init
+ArcAddChild(pcomponent *Current, pcomponent *Template, VOID *ConfigurationData)
+{
+	return (pcomponent *)
+	       ARC_CALL3(child_add, Current, Template, ConfigurationData);
+}
+
+LONG __init
+ArcDeleteComponent(pcomponent *ComponentToDelete)
+{
+	return ARC_CALL1(comp_del, ComponentToDelete);
+}
+
+pcomponent * __init
+ArcGetComponent(CHAR *Path)
+{
+	return (pcomponent *)ARC_CALL1(component_by_path, Path);
+}
+
+#ifdef DEBUG_PROM_TREE
+
+static char *classes[] = {
+	"system", "processor", "cache", "adapter", "controller", "peripheral",
+	"memory"
+};
+
+static char *types[] = {
+	"arc", "cpu", "fpu", "picache", "pdcache", "sicache", "sdcache",
+	"sccache", "memdev", "eisa adapter", "tc adapter", "scsi adapter",
+	"dti adapter", "multi-func adapter", "disk controller",
+	"tp controller", "cdrom controller", "worm controller",
+	"serial controller", "net controller", "display controller",
+	"parallel controller", "pointer controller", "keyboard controller",
+	"audio controller", "misc controller", "disk peripheral",
+	"floppy peripheral", "tp peripheral", "modem peripheral",
+	"monitor peripheral", "printer peripheral", "pointer peripheral",
+	"keyboard peripheral", "terminal peripheral", "line peripheral",
+	"net peripheral", "misc peripheral", "anonymous"
+};
+
+static char *iflags[] = {
+	"bogus", "read only", "removable", "console in", "console out",
+	"input", "output"
+};
+
+static void __init
+dump_component(pcomponent *p)
+{
+	prom_printf("[%p]:class<%s>type<%s>flags<%s>ver<%d>rev<%d>",
+		    p, classes[p->class], types[p->type],
+		    iflags[p->iflags], p->vers, p->rev);
+	prom_printf("key<%08lx>\n\tamask<%08lx>cdsize<%d>ilen<%d>iname<%s>\n",
+		    p->key, p->amask, (int)p->cdsize, (int)p->ilen, p->iname);
+}
+
+static void __init
+traverse(pcomponent *p, int op)
+{
+	dump_component(p);
+	if(ArcGetChild(p))
+		traverse(ArcGetChild(p), 1);
+	if(ArcGetPeer(p) && op)
+		traverse(ArcGetPeer(p), 1);
+}
+
+void __init
+prom_testtree(void)
+{
+	pcomponent *p;
+
+	p = ArcGetChild(PROM_NULL_COMPONENT);
+	dump_component(p);
+	p = ArcGetChild(p);
+	while(p) {
+		dump_component(p);
+		p = ArcGetPeer(p);
+	}
+}
+
+#endif /* DEBUG_PROM_TREE  */
diff --git a/arch/mips/au1000/common/Makefile b/arch/mips/au1000/common/Makefile
new file mode 100644
index 0000000..594b75e
--- /dev/null
+++ b/arch/mips/au1000/common/Makefile
@@ -0,0 +1,15 @@
+#
+#  Copyright 2000 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc.
+#     	ppopov@mvista.com or source@mvista.com
+#
+# Makefile for the Alchemy Au1000 CPU, generic files.
+#
+
+obj-y += prom.o int-handler.o irq.o puts.o time.o reset.o \
+	au1xxx_irqmap.o clocks.o platform.o power.o setup.o \
+	sleeper.o cputable.o dma.o dbdma.o
+
+obj-$(CONFIG_AU1X00_USB_DEVICE)	+= usbdev.o
+obj-$(CONFIG_KGDB)		+= dbg_io.o
+obj-$(CONFIG_PCI)		+= pci.o
diff --git a/arch/mips/au1000/common/au1xxx_irqmap.c b/arch/mips/au1000/common/au1xxx_irqmap.c
new file mode 100644
index 0000000..8a0f39f
--- /dev/null
+++ b/arch/mips/au1000/common/au1xxx_irqmap.c
@@ -0,0 +1,224 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Au1xxx processor specific IRQ tables
+ *
+ * Copyright 2004 Embedded Edge, LLC
+ *	dan@embeddededge.com
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
+ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
+ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/mach-au1x00/au1000.h>
+
+/* The IC0 interrupt table.  This is processor, rather than
+ * board dependent, so no reason to keep this info in the board
+ * dependent files.
+ *
+ * Careful if you change match 2 request!
+ * The interrupt handler is called directly from the low level dispatch code.
+ */
+au1xxx_irq_map_t au1xxx_ic0_map[] = {
+
+#if defined(CONFIG_SOC_AU1000)
+	{ AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_UART1_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_UART2_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
+	{ AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
+
+#elif defined(CONFIG_SOC_AU1500)
+
+	{ AU1500_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_PCI_INTA, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1000_PCI_INTB, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1500_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_PCI_INTC, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1000_PCI_INTD, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
+	{ AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1500_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1500_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
+
+#elif defined(CONFIG_SOC_AU1100)
+
+	{ AU1100_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1100_UART1_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1100_SD_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1100_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
+	{ AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1100_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
+	/*{ AU1000_GPIO215_208_INT, INTC_INT_HIGH_LEVEL, 0},*/
+	{ AU1100_LCD_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
+
+#elif defined(CONFIG_SOC_AU1550)
+
+	{ AU1550_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1550_PCI_INTA, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1550_PCI_INTB, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1550_DDMA_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1550_CRYPTO_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1550_PCI_INTC, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1550_PCI_INTD, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1550_PCI_RST_INT, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1550_UART1_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1550_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1550_PSC0_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1550_PSC1_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1550_PSC2_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1550_PSC3_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1550_TOY_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1550_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1550_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1550_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
+	{ AU1550_RTC_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1550_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1550_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1550_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1550_NAND_INT, INTC_INT_RISE_EDGE, 0},
+	{ AU1550_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1550_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1550_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1550_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1550_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
+
+#elif defined(CONFIG_SOC_AU1200)
+
+	{ AU1200_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1200_SWT_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1200_SD_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1200_DDMA_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1200_MAE_BE_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1200_UART1_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1200_MAE_FE_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1200_PSC0_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1200_PSC1_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1200_AES_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1200_CAMERA_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1200_TOY_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1200_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1200_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1200_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
+	{ AU1200_RTC_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1200_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1200_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1200_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1200_NAND_INT, INTC_INT_RISE_EDGE, 0},
+	{ AU1200_USB_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1200_LCD_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1200_MAE_BOTH_INT, INTC_INT_HIGH_LEVEL, 0},
+
+#else
+#error "Error: Unknown Alchemy SOC"
+#endif
+
+};
+
+int au1xxx_ic0_nr_irqs = sizeof(au1xxx_ic0_map)/sizeof(au1xxx_irq_map_t);
+
diff --git a/arch/mips/au1000/common/clocks.c b/arch/mips/au1000/common/clocks.c
new file mode 100644
index 0000000..3ce6cac
--- /dev/null
+++ b/arch/mips/au1000/common/clocks.c
@@ -0,0 +1,96 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Simple Au1000 clocks routines.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *		ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
+ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
+ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <asm/mach-au1x00/au1000.h>
+
+static unsigned int au1x00_clock; // Hz
+static unsigned int lcd_clock;    // KHz
+static unsigned long uart_baud_base;
+
+/*
+ * Set the au1000_clock
+ */
+void set_au1x00_speed(unsigned int new_freq)
+{
+	au1x00_clock = new_freq;
+}
+
+unsigned int get_au1x00_speed(void)
+{
+	return au1x00_clock;
+}
+
+
+
+/*
+ * The UART baud base is not known at compile time ... if
+ * we want to be able to use the same code on different
+ * speed CPUs.
+ */
+unsigned long get_au1x00_uart_baud_base(void)
+{
+	return uart_baud_base;
+}
+
+void set_au1x00_uart_baud_base(unsigned long new_baud_base)
+{
+	uart_baud_base = new_baud_base;
+}
+
+/*
+ * Calculate the Au1x00's LCD clock based on the current
+ * cpu clock and the system bus clock, and try to keep it
+ * below 40 MHz (the Pb1000 board can lock-up if the LCD
+ * clock is over 40 MHz).
+ */
+void set_au1x00_lcd_clock(void)
+{
+	unsigned int static_cfg0;
+	unsigned int sys_busclk =
+		(get_au1x00_speed()/1000) /
+		((int)(au_readl(SYS_POWERCTRL)&0x03) + 2);
+
+	static_cfg0 = au_readl(MEM_STCFG0);
+
+	if (static_cfg0 & (1<<11))
+		lcd_clock = sys_busclk / 5; /* note: BCLK switching fails with D5 */
+	else
+		lcd_clock = sys_busclk / 4;
+
+	if (lcd_clock > 50000) /* Epson MAX */
+		printk("warning: LCD clock too high (%d KHz)\n", lcd_clock);
+}
+
+unsigned int get_au1x00_lcd_clock(void)
+{
+	return lcd_clock;
+}
+
+EXPORT_SYMBOL(get_au1x00_lcd_clock);
diff --git a/arch/mips/au1000/common/cputable.c b/arch/mips/au1000/common/cputable.c
new file mode 100644
index 0000000..f5521df
--- /dev/null
+++ b/arch/mips/au1000/common/cputable.c
@@ -0,0 +1,55 @@
+/*
+ *  arch/mips/au1000/common/cputable.c
+ *
+ *  Copyright (C) 2004 Dan Malek (dan@embeddededge.com)
+ *	Copied from PowerPC and updated for Alchemy Au1xxx processors.
+ *
+ *  Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/threads.h>
+#include <linux/init.h>
+#include <asm/mach-au1x00/au1000.h>
+
+struct cpu_spec* cur_cpu_spec[NR_CPUS];
+
+/* With some thought, we can probably use the mask to reduce the
+ * size of the table.
+ */
+struct cpu_spec	cpu_specs[] = {
+    { 0xffffffff, 0x00030100, "Au1000 DA", 1, 0 },
+    { 0xffffffff, 0x00030201, "Au1000 HA", 1, 0 },
+    { 0xffffffff, 0x00030202, "Au1000 HB", 1, 0 },
+    { 0xffffffff, 0x00030203, "Au1000 HC", 1, 1 },
+    { 0xffffffff, 0x00030204, "Au1000 HD", 1, 1 },
+    { 0xffffffff, 0x01030200, "Au1500 AB", 1, 1 },
+    { 0xffffffff, 0x01030201, "Au1500 AC", 0, 1 },
+    { 0xffffffff, 0x01030202, "Au1500 AD", 0, 1 },
+    { 0xffffffff, 0x02030200, "Au1100 AB", 1, 1 },
+    { 0xffffffff, 0x02030201, "Au1100 BA", 1, 1 },
+    { 0xffffffff, 0x02030202, "Au1100 BC", 1, 1 },
+    { 0xffffffff, 0x02030203, "Au1100 BD", 0, 1 },
+    { 0xffffffff, 0x02030204, "Au1100 BE", 0, 1 },
+    { 0xffffffff, 0x03030200, "Au1550 AA", 0, 1 },
+    { 0xffffffff, 0x04030200, "Au1200 AA", 0, 1 },
+    { 0x00000000, 0x00000000, "Unknown Au1xxx", 1, 0 },
+};
+
+void
+set_cpuspec(void)
+{
+	struct	cpu_spec *sp;
+	u32	prid;
+
+	prid = read_c0_prid();
+	sp = cpu_specs;
+	while ((prid & sp->prid_mask) != sp->prid_value)
+		sp++;
+	cur_cpu_spec[0] = sp;
+}
diff --git a/arch/mips/au1000/common/dbdma.c b/arch/mips/au1000/common/dbdma.c
new file mode 100644
index 0000000..adfc317
--- /dev/null
+++ b/arch/mips/au1000/common/dbdma.c
@@ -0,0 +1,836 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *      The Descriptor Based DMA channel manager that first appeared
+ *	on the Au1550.  I started with dma.c, but I think all that is
+ *	left is this initial comment :-)
+ *
+ * Copyright 2004 Embedded Edge, LLC
+ *	dan@embeddededge.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1xxx_dbdma.h>
+#include <asm/system.h>
+
+#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
+
+/*
+ * The Descriptor Based DMA supports up to 16 channels.
+ *
+ * There are 32 devices defined. We keep an internal structure
+ * of devices using these channels, along with additional
+ * information.
+ *
+ * We allocate the descriptors and allow access to them through various
+ * functions.  The drivers allocate the data buffers and assign them
+ * to the descriptors.
+ */
+static DEFINE_SPINLOCK(au1xxx_dbdma_spin_lock);
+
+/* I couldn't find a macro that did this......
+*/
+#define ALIGN_ADDR(x, a)	((((u32)(x)) + (a-1)) & ~(a-1))
+
+static volatile dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE;
+static int dbdma_initialized;
+static void au1xxx_dbdma_init(void);
+
+typedef struct dbdma_device_table {
+	u32		dev_id;
+	u32		dev_flags;
+	u32		dev_tsize;
+	u32		dev_devwidth;
+	u32		dev_physaddr;		/* If FIFO */
+	u32		dev_intlevel;
+	u32		dev_intpolarity;
+} dbdev_tab_t;
+
+typedef struct dbdma_chan_config {
+	u32			chan_flags;
+	u32			chan_index;
+	dbdev_tab_t		*chan_src;
+	dbdev_tab_t		*chan_dest;
+	au1x_dma_chan_t		*chan_ptr;
+	au1x_ddma_desc_t	*chan_desc_base;
+	au1x_ddma_desc_t	*get_ptr, *put_ptr, *cur_ptr;
+	void			*chan_callparam;
+	void (*chan_callback)(int, void *, struct pt_regs *);
+} chan_tab_t;
+
+#define	DEV_FLAGS_INUSE		(1 << 0)
+#define	DEV_FLAGS_ANYUSE	(1 << 1)
+#define DEV_FLAGS_OUT		(1 << 2)
+#define DEV_FLAGS_IN		(1 << 3)
+
+static dbdev_tab_t dbdev_tab[] = {
+#ifdef CONFIG_SOC_AU1550
+	/* UARTS */
+	{ DSCR_CMD0_UART0_TX, DEV_FLAGS_OUT, 0, 8, 0x11100004, 0, 0 },
+	{ DSCR_CMD0_UART0_RX, DEV_FLAGS_IN, 0, 8, 0x11100000, 0, 0 },
+	{ DSCR_CMD0_UART3_TX, DEV_FLAGS_OUT, 0, 8, 0x11400004, 0, 0 },
+	{ DSCR_CMD0_UART3_RX, DEV_FLAGS_IN, 0, 8, 0x11400000, 0, 0 },
+
+	/* EXT DMA */
+	{ DSCR_CMD0_DMA_REQ0, 0, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_DMA_REQ1, 0, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_DMA_REQ2, 0, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_DMA_REQ3, 0, 0, 0, 0x00000000, 0, 0 },
+
+	/* USB DEV */
+	{ DSCR_CMD0_USBDEV_RX0, DEV_FLAGS_IN, 4, 8, 0x10200000, 0, 0 },
+	{ DSCR_CMD0_USBDEV_TX0, DEV_FLAGS_OUT, 4, 8, 0x10200004, 0, 0 },
+	{ DSCR_CMD0_USBDEV_TX1, DEV_FLAGS_OUT, 4, 8, 0x10200008, 0, 0 },
+	{ DSCR_CMD0_USBDEV_TX2, DEV_FLAGS_OUT, 4, 8, 0x1020000c, 0, 0 },
+	{ DSCR_CMD0_USBDEV_RX3, DEV_FLAGS_IN, 4, 8, 0x10200010, 0, 0 },
+	{ DSCR_CMD0_USBDEV_RX4, DEV_FLAGS_IN, 4, 8, 0x10200014, 0, 0 },
+
+	/* PSC 0 */
+	{ DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 0, 0x11a0001c, 0, 0 },
+	{ DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 0, 0x11a0001c, 0, 0 },
+
+	/* PSC 1 */
+	{ DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 0, 0x11b0001c, 0, 0 },
+	{ DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 0, 0x11b0001c, 0, 0 },
+
+	/* PSC 2 */
+	{ DSCR_CMD0_PSC2_TX, DEV_FLAGS_OUT, 0, 0, 0x10a0001c, 0, 0 },
+	{ DSCR_CMD0_PSC2_RX, DEV_FLAGS_IN, 0, 0, 0x10a0001c, 0, 0 },
+
+	/* PSC 3 */
+	{ DSCR_CMD0_PSC3_TX, DEV_FLAGS_OUT, 0, 0, 0x10b0001c, 0, 0 },
+	{ DSCR_CMD0_PSC3_RX, DEV_FLAGS_IN, 0, 0, 0x10b0001c, 0, 0 },
+
+	{ DSCR_CMD0_PCI_WRITE, 0, 0, 0, 0x00000000, 0, 0 },	/* PCI */
+	{ DSCR_CMD0_NAND_FLASH, 0, 0, 0, 0x00000000, 0, 0 },	/* NAND */
+
+	/* MAC 0 */
+	{ DSCR_CMD0_MAC0_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_MAC0_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
+
+	/* MAC 1 */
+	{ DSCR_CMD0_MAC1_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_MAC1_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
+
+#endif /* CONFIG_SOC_AU1550 */
+
+#ifdef CONFIG_SOC_AU1200
+	{ DSCR_CMD0_UART0_TX, DEV_FLAGS_OUT, 0, 8, 0x11100004, 0, 0 },
+	{ DSCR_CMD0_UART0_RX, DEV_FLAGS_IN, 0, 8, 0x11100000, 0, 0 },
+	{ DSCR_CMD0_UART1_TX, DEV_FLAGS_OUT, 0, 8, 0x11200004, 0, 0 },
+	{ DSCR_CMD0_UART1_RX, DEV_FLAGS_IN, 0, 8, 0x11200000, 0, 0 },
+
+	{ DSCR_CMD0_DMA_REQ0, 0, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_DMA_REQ1, 0, 0, 0, 0x00000000, 0, 0 },
+
+	{ DSCR_CMD0_MAE_BE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_MAE_FE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_MAE_BOTH, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_LCD, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+
+	{ DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+
+	{ DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_AES_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+
+	{ DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 0, 0x11a0001c, 0, 0 },
+	{ DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 0, 0x11a0001c, 0, 0 },
+	{ DSCR_CMD0_PSC0_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+
+	{ DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 0, 0x11b0001c, 0, 0 },
+	{ DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 0, 0x11b0001c, 0, 0 },
+	{ DSCR_CMD0_PSC1_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+
+	{ DSCR_CMD0_CIM_RXA, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_CIM_RXB, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_CIM_RXC, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_CIM_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+
+	{ DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+
+#endif // CONFIG_SOC_AU1200
+
+	{ DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+};
+
+#define DBDEV_TAB_SIZE (sizeof(dbdev_tab) / sizeof(dbdev_tab_t))
+
+static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS];
+
+static dbdev_tab_t *
+find_dbdev_id (u32 id)
+{
+	int i;
+	dbdev_tab_t *p;
+	for (i = 0; i < DBDEV_TAB_SIZE; ++i) {
+		p = &dbdev_tab[i];
+		if (p->dev_id == id)
+			return p;
+	}
+	return NULL;
+}
+
+/* Allocate a channel and return a non-zero descriptor if successful.
+*/
+u32
+au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
+       void (*callback)(int, void *, struct pt_regs *), void *callparam)
+{
+	unsigned long   flags;
+	u32		used, chan, rv;
+	u32		dcp;
+	int		i;
+	dbdev_tab_t	*stp, *dtp;
+	chan_tab_t	*ctp;
+	volatile au1x_dma_chan_t *cp;
+
+	/* We do the intialization on the first channel allocation.
+	 * We have to wait because of the interrupt handler initialization
+	 * which can't be done successfully during board set up.
+	 */
+	if (!dbdma_initialized)
+		au1xxx_dbdma_init();
+	dbdma_initialized = 1;
+
+	if ((srcid > DSCR_NDEV_IDS) || (destid > DSCR_NDEV_IDS))
+		return 0;
+
+	if ((stp = find_dbdev_id(srcid)) == NULL) return 0;
+	if ((dtp = find_dbdev_id(destid)) == NULL) return 0;
+
+	used = 0;
+	rv = 0;
+
+	/* Check to see if we can get both channels.
+	*/
+	spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags);
+	if (!(stp->dev_flags & DEV_FLAGS_INUSE) ||
+	     (stp->dev_flags & DEV_FLAGS_ANYUSE)) {
+	     	/* Got source */
+		stp->dev_flags |= DEV_FLAGS_INUSE;
+		if (!(dtp->dev_flags & DEV_FLAGS_INUSE) ||
+		     (dtp->dev_flags & DEV_FLAGS_ANYUSE)) {
+			/* Got destination */
+			dtp->dev_flags |= DEV_FLAGS_INUSE;
+		}
+		else {
+			/* Can't get dest.  Release src.
+			*/
+			stp->dev_flags &= ~DEV_FLAGS_INUSE;
+			used++;
+		}
+	}
+	else {
+		used++;
+	}
+	spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags);
+
+	if (!used) {
+		/* Let's see if we can allocate a channel for it.
+		*/
+		ctp = NULL;
+		chan = 0;
+		spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags);
+		for (i=0; i<NUM_DBDMA_CHANS; i++) {
+			if (chan_tab_ptr[i] == NULL) {
+				/* If kmalloc fails, it is caught below same
+				 * as a channel not available.
+				 */
+				ctp = kmalloc(sizeof(chan_tab_t), GFP_KERNEL);
+				chan_tab_ptr[i] = ctp;
+				ctp->chan_index = chan = i;
+				break;
+			}
+		}
+		spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags);
+
+		if (ctp != NULL) {
+			memset(ctp, 0, sizeof(chan_tab_t));
+			dcp = DDMA_CHANNEL_BASE;
+			dcp += (0x0100 * chan);
+			ctp->chan_ptr = (au1x_dma_chan_t *)dcp;
+			cp = (volatile au1x_dma_chan_t *)dcp;
+			ctp->chan_src = stp;
+			ctp->chan_dest = dtp;
+			ctp->chan_callback = callback;
+			ctp->chan_callparam = callparam;
+
+			/* Initialize channel configuration.
+			*/
+			i = 0;
+			if (stp->dev_intlevel)
+				i |= DDMA_CFG_SED;
+			if (stp->dev_intpolarity)
+				i |= DDMA_CFG_SP;
+			if (dtp->dev_intlevel)
+				i |= DDMA_CFG_DED;
+			if (dtp->dev_intpolarity)
+				i |= DDMA_CFG_DP;
+			cp->ddma_cfg = i;
+			au_sync();
+
+			/* Return a non-zero value that can be used to
+			 * find the channel information in subsequent
+			 * operations.
+			 */
+			rv = (u32)(&chan_tab_ptr[chan]);
+		}
+		else {
+			/* Release devices.
+			*/
+			stp->dev_flags &= ~DEV_FLAGS_INUSE;
+			dtp->dev_flags &= ~DEV_FLAGS_INUSE;
+		}
+	}
+	return rv;
+}
+
+/* Set the device width if source or destination is a FIFO.
+ * Should be 8, 16, or 32 bits.
+ */
+u32
+au1xxx_dbdma_set_devwidth(u32 chanid, int bits)
+{
+	u32		rv;
+	chan_tab_t	*ctp;
+	dbdev_tab_t	*stp, *dtp;
+
+	ctp = *((chan_tab_t **)chanid);
+	stp = ctp->chan_src;
+	dtp = ctp->chan_dest;
+	rv = 0;
+
+	if (stp->dev_flags & DEV_FLAGS_IN) {	/* Source in fifo */
+		rv = stp->dev_devwidth;
+		stp->dev_devwidth = bits;
+	}
+	if (dtp->dev_flags & DEV_FLAGS_OUT) {	/* Destination out fifo */
+		rv = dtp->dev_devwidth;
+		dtp->dev_devwidth = bits;
+	}
+
+	return rv;
+}
+
+/* Allocate a descriptor ring, initializing as much as possible.
+*/
+u32
+au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
+{
+	int			i;
+	u32			desc_base, srcid, destid;
+	u32			cmd0, cmd1, src1, dest1;
+	u32			src0, dest0;
+	chan_tab_t		*ctp;
+	dbdev_tab_t		*stp, *dtp;
+	au1x_ddma_desc_t	*dp;
+
+	/* I guess we could check this to be within the
+	 * range of the table......
+	 */
+	ctp = *((chan_tab_t **)chanid);
+	stp = ctp->chan_src;
+	dtp = ctp->chan_dest;
+
+	/* The descriptors must be 32-byte aligned.  There is a
+	 * possibility the allocation will give us such an address,
+	 * and if we try that first we are likely to not waste larger
+	 * slabs of memory.
+	 */
+	desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t), GFP_KERNEL);
+	if (desc_base == 0)
+		return 0;
+
+	if (desc_base & 0x1f) {
+		/* Lost....do it again, allocate extra, and round
+		 * the address base.
+		 */
+		kfree((const void *)desc_base);
+		i = entries * sizeof(au1x_ddma_desc_t);
+		i += (sizeof(au1x_ddma_desc_t) - 1);
+		if ((desc_base = (u32)kmalloc(i, GFP_KERNEL)) == 0)
+			return 0;
+
+		desc_base = ALIGN_ADDR(desc_base, sizeof(au1x_ddma_desc_t));
+	}
+	dp = (au1x_ddma_desc_t *)desc_base;
+
+	/* Keep track of the base descriptor.
+	*/
+	ctp->chan_desc_base = dp;
+
+	/* Initialize the rings with as much information as we know.
+	 */
+	srcid = stp->dev_id;
+	destid = dtp->dev_id;
+
+	cmd0 = cmd1 = src1 = dest1 = 0;
+	src0 = dest0 = 0;
+
+	cmd0 |= DSCR_CMD0_SID(srcid);
+	cmd0 |= DSCR_CMD0_DID(destid);
+	cmd0 |= DSCR_CMD0_IE | DSCR_CMD0_CV;
+	cmd0 |= DSCR_CMD0_ST(DSCR_CMD0_ST_CURRENT);
+
+	switch (stp->dev_devwidth) {
+	case 8:
+		cmd0 |= DSCR_CMD0_SW(DSCR_CMD0_BYTE);
+		break;
+	case 16:
+		cmd0 |= DSCR_CMD0_SW(DSCR_CMD0_HALFWORD);
+		break;
+	case 32:
+	default:
+		cmd0 |= DSCR_CMD0_SW(DSCR_CMD0_WORD);
+		break;
+	}
+
+	switch (dtp->dev_devwidth) {
+	case 8:
+		cmd0 |= DSCR_CMD0_DW(DSCR_CMD0_BYTE);
+		break;
+	case 16:
+		cmd0 |= DSCR_CMD0_DW(DSCR_CMD0_HALFWORD);
+		break;
+	case 32:
+	default:
+		cmd0 |= DSCR_CMD0_DW(DSCR_CMD0_WORD);
+		break;
+	}
+
+	/* If the device is marked as an in/out FIFO, ensure it is
+	 * set non-coherent.
+	 */
+	if (stp->dev_flags & DEV_FLAGS_IN)
+		cmd0 |= DSCR_CMD0_SN;		/* Source in fifo */
+	if (dtp->dev_flags & DEV_FLAGS_OUT)
+		cmd0 |= DSCR_CMD0_DN;		/* Destination out fifo */
+
+	/* Set up source1.  For now, assume no stride and increment.
+	 * A channel attribute update can change this later.
+	 */
+	switch (stp->dev_tsize) {
+	case 1:
+		src1 |= DSCR_SRC1_STS(DSCR_xTS_SIZE1);
+		break;
+	case 2:
+		src1 |= DSCR_SRC1_STS(DSCR_xTS_SIZE2);
+		break;
+	case 4:
+		src1 |= DSCR_SRC1_STS(DSCR_xTS_SIZE4);
+		break;
+	case 8:
+	default:
+		src1 |= DSCR_SRC1_STS(DSCR_xTS_SIZE8);
+		break;
+	}
+
+	/* If source input is fifo, set static address.
+	*/
+	if (stp->dev_flags & DEV_FLAGS_IN) {
+		src0 = stp->dev_physaddr;
+		src1 |= DSCR_SRC1_SAM(DSCR_xAM_STATIC);
+	}
+
+	/* Set up dest1.  For now, assume no stride and increment.
+	 * A channel attribute update can change this later.
+	 */
+	switch (dtp->dev_tsize) {
+	case 1:
+		dest1 |= DSCR_DEST1_DTS(DSCR_xTS_SIZE1);
+		break;
+	case 2:
+		dest1 |= DSCR_DEST1_DTS(DSCR_xTS_SIZE2);
+		break;
+	case 4:
+		dest1 |= DSCR_DEST1_DTS(DSCR_xTS_SIZE4);
+		break;
+	case 8:
+	default:
+		dest1 |= DSCR_DEST1_DTS(DSCR_xTS_SIZE8);
+		break;
+	}
+
+	/* If destination output is fifo, set static address.
+	*/
+	if (dtp->dev_flags & DEV_FLAGS_OUT) {
+		dest0 = dtp->dev_physaddr;
+		dest1 |= DSCR_DEST1_DAM(DSCR_xAM_STATIC);
+	}
+
+	for (i=0; i<entries; i++) {
+		dp->dscr_cmd0 = cmd0;
+		dp->dscr_cmd1 = cmd1;
+		dp->dscr_source0 = src0;
+		dp->dscr_source1 = src1;
+		dp->dscr_dest0 = dest0;
+		dp->dscr_dest1 = dest1;
+		dp->dscr_stat = 0;
+		dp->dscr_nxtptr = DSCR_NXTPTR(virt_to_phys(dp + 1));
+		dp++;
+	}
+
+	/* Make last descrptor point to the first.
+	*/
+	dp--;
+	dp->dscr_nxtptr = DSCR_NXTPTR(virt_to_phys(ctp->chan_desc_base));
+	ctp->get_ptr = ctp->put_ptr = ctp->cur_ptr = ctp->chan_desc_base;
+
+	return (u32)(ctp->chan_desc_base);
+}
+
+/* Put a source buffer into the DMA ring.
+ * This updates the source pointer and byte count.  Normally used
+ * for memory to fifo transfers.
+ */
+u32
+au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes)
+{
+	chan_tab_t		*ctp;
+	au1x_ddma_desc_t	*dp;
+
+	/* I guess we could check this to be within the
+	 * range of the table......
+	 */
+	ctp = *((chan_tab_t **)chanid);
+
+	/* We should have multiple callers for a particular channel,
+	 * an interrupt doesn't affect this pointer nor the descriptor,
+	 * so no locking should be needed.
+	 */
+	dp = ctp->put_ptr;
+
+	/* If the descriptor is valid, we are way ahead of the DMA
+	 * engine, so just return an error condition.
+	 */
+	if (dp->dscr_cmd0 & DSCR_CMD0_V) {
+		return 0;
+	}
+
+	/* Load up buffer address and byte count.
+	*/
+	dp->dscr_source0 = virt_to_phys(buf);
+	dp->dscr_cmd1 = nbytes;
+	dp->dscr_cmd0 |= DSCR_CMD0_V;	/* Let it rip */
+	ctp->chan_ptr->ddma_dbell = 0xffffffff;	/* Make it go */
+
+	/* Get next descriptor pointer.
+	*/
+	ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+
+	/* return something not zero.
+	*/
+	return nbytes;
+}
+
+/* Put a destination buffer into the DMA ring.
+ * This updates the destination pointer and byte count.  Normally used
+ * to place an empty buffer into the ring for fifo to memory transfers.
+ */
+u32
+au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes)
+{
+	chan_tab_t		*ctp;
+	au1x_ddma_desc_t	*dp;
+
+	/* I guess we could check this to be within the
+	 * range of the table......
+	 */
+	ctp = *((chan_tab_t **)chanid);
+
+	/* We should have multiple callers for a particular channel,
+	 * an interrupt doesn't affect this pointer nor the descriptor,
+	 * so no locking should be needed.
+	 */
+	dp = ctp->put_ptr;
+
+	/* If the descriptor is valid, we are way ahead of the DMA
+	 * engine, so just return an error condition.
+	 */
+	if (dp->dscr_cmd0 & DSCR_CMD0_V)
+		return 0;
+
+	/* Load up buffer address and byte count.
+	*/
+	dp->dscr_dest0 = virt_to_phys(buf);
+	dp->dscr_cmd1 = nbytes;
+	dp->dscr_cmd0 |= DSCR_CMD0_V;	/* Let it rip */
+
+	/* Get next descriptor pointer.
+	*/
+	ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+
+	/* return something not zero.
+	*/
+	return nbytes;
+}
+
+/* Get a destination buffer into the DMA ring.
+ * Normally used to get a full buffer from the ring during fifo
+ * to memory transfers.  This does not set the valid bit, you will
+ * have to put another destination buffer to keep the DMA going.
+ */
+u32
+au1xxx_dbdma_get_dest(u32 chanid, void **buf, int *nbytes)
+{
+	chan_tab_t		*ctp;
+	au1x_ddma_desc_t	*dp;
+	u32			rv;
+
+	/* I guess we could check this to be within the
+	 * range of the table......
+	 */
+	ctp = *((chan_tab_t **)chanid);
+
+	/* We should have multiple callers for a particular channel,
+	 * an interrupt doesn't affect this pointer nor the descriptor,
+	 * so no locking should be needed.
+	 */
+	dp = ctp->get_ptr;
+
+	/* If the descriptor is valid, we are way ahead of the DMA
+	 * engine, so just return an error condition.
+	 */
+	if (dp->dscr_cmd0 & DSCR_CMD0_V)
+		return 0;
+
+	/* Return buffer address and byte count.
+	*/
+	*buf = (void *)(phys_to_virt(dp->dscr_dest0));
+	*nbytes = dp->dscr_cmd1;
+	rv = dp->dscr_stat;
+
+	/* Get next descriptor pointer.
+	*/
+	ctp->get_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+
+	/* return something not zero.
+	*/
+	return rv;
+}
+
+void
+au1xxx_dbdma_stop(u32 chanid)
+{
+	chan_tab_t	*ctp;
+	volatile au1x_dma_chan_t *cp;
+	int halt_timeout = 0;
+
+	ctp = *((chan_tab_t **)chanid);
+
+	cp = ctp->chan_ptr;
+	cp->ddma_cfg &= ~DDMA_CFG_EN;	/* Disable channel */
+	au_sync();
+	while (!(cp->ddma_stat & DDMA_STAT_H)) {
+		udelay(1);
+		halt_timeout++;
+		if (halt_timeout > 100) {
+			printk("warning: DMA channel won't halt\n");
+			break;
+		}
+	}
+	/* clear current desc valid and doorbell */
+	cp->ddma_stat |= (DDMA_STAT_DB | DDMA_STAT_V);
+	au_sync();
+}
+
+/* Start using the current descriptor pointer.  If the dbdma encounters
+ * a not valid descriptor, it will stop.  In this case, we can just
+ * continue by adding a buffer to the list and starting again.
+ */
+void
+au1xxx_dbdma_start(u32 chanid)
+{
+	chan_tab_t	*ctp;
+	volatile au1x_dma_chan_t *cp;
+
+	ctp = *((chan_tab_t **)chanid);
+
+	cp = ctp->chan_ptr;
+	cp->ddma_desptr = virt_to_phys(ctp->cur_ptr);
+	cp->ddma_cfg |= DDMA_CFG_EN;	/* Enable channel */
+	au_sync();
+	cp->ddma_dbell = 0xffffffff;	/* Make it go */
+	au_sync();
+}
+
+void
+au1xxx_dbdma_reset(u32 chanid)
+{
+	chan_tab_t		*ctp;
+	au1x_ddma_desc_t	*dp;
+
+	au1xxx_dbdma_stop(chanid);
+
+	ctp = *((chan_tab_t **)chanid);
+	ctp->get_ptr = ctp->put_ptr = ctp->cur_ptr = ctp->chan_desc_base;
+
+	/* Run through the descriptors and reset the valid indicator.
+	*/
+	dp = ctp->chan_desc_base;
+
+	do {
+		dp->dscr_cmd0 &= ~DSCR_CMD0_V;
+		dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+	} while (dp != ctp->chan_desc_base);
+}
+
+u32
+au1xxx_get_dma_residue(u32 chanid)
+{
+	chan_tab_t	*ctp;
+	volatile au1x_dma_chan_t *cp;
+	u32		rv;
+
+	ctp = *((chan_tab_t **)chanid);
+	cp = ctp->chan_ptr;
+
+	/* This is only valid if the channel is stopped.
+	*/
+	rv = cp->ddma_bytecnt;
+	au_sync();
+
+	return rv;
+}
+
+void
+au1xxx_dbdma_chan_free(u32 chanid)
+{
+	chan_tab_t	*ctp;
+	dbdev_tab_t	*stp, *dtp;
+
+	ctp = *((chan_tab_t **)chanid);
+	stp = ctp->chan_src;
+	dtp = ctp->chan_dest;
+
+	au1xxx_dbdma_stop(chanid);
+
+	if (ctp->chan_desc_base != NULL)
+		kfree(ctp->chan_desc_base);
+
+	stp->dev_flags &= ~DEV_FLAGS_INUSE;
+	dtp->dev_flags &= ~DEV_FLAGS_INUSE;
+	chan_tab_ptr[ctp->chan_index] = NULL;
+
+	kfree(ctp);
+}
+
+static irqreturn_t
+dbdma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	u32	intstat;
+	u32	chan_index;
+	chan_tab_t		*ctp;
+	au1x_ddma_desc_t	*dp;
+	volatile au1x_dma_chan_t *cp;
+
+	intstat = dbdma_gptr->ddma_intstat;
+	au_sync();
+	chan_index = au_ffs(intstat) - 1;
+
+	ctp = chan_tab_ptr[chan_index];
+	cp = ctp->chan_ptr;
+	dp = ctp->cur_ptr;
+
+	/* Reset interrupt.
+	*/
+	cp->ddma_irq = 0;
+	au_sync();
+
+	if (ctp->chan_callback)
+		(ctp->chan_callback)(irq, ctp->chan_callparam, regs);
+
+	ctp->cur_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+
+	return IRQ_HANDLED;
+}
+
+static void
+au1xxx_dbdma_init(void)
+{
+	dbdma_gptr->ddma_config = 0;
+	dbdma_gptr->ddma_throttle = 0;
+	dbdma_gptr->ddma_inten = 0xffff;
+	au_sync();
+
+	if (request_irq(AU1550_DDMA_INT, dbdma_interrupt, SA_INTERRUPT,
+			"Au1xxx dbdma", (void *)dbdma_gptr))
+		printk("Can't get 1550 dbdma irq");
+}
+
+void
+au1xxx_dbdma_dump(u32 chanid)
+{
+	chan_tab_t		*ctp;
+	au1x_ddma_desc_t	*dp;
+	dbdev_tab_t		*stp, *dtp;
+	volatile au1x_dma_chan_t *cp;
+
+	ctp = *((chan_tab_t **)chanid);
+	stp = ctp->chan_src;
+	dtp = ctp->chan_dest;
+	cp = ctp->chan_ptr;
+
+	printk("Chan %x, stp %x (dev %d)  dtp %x (dev %d) \n",
+		(u32)ctp, (u32)stp, stp - dbdev_tab, (u32)dtp, dtp - dbdev_tab);
+	printk("desc base %x, get %x, put %x, cur %x\n",
+		(u32)(ctp->chan_desc_base), (u32)(ctp->get_ptr),
+		(u32)(ctp->put_ptr), (u32)(ctp->cur_ptr));
+
+	printk("dbdma chan %x\n", (u32)cp);
+	printk("cfg %08x, desptr %08x, statptr %08x\n",
+		cp->ddma_cfg, cp->ddma_desptr, cp->ddma_statptr);
+	printk("dbell %08x, irq %08x, stat %08x, bytecnt %08x\n",
+		cp->ddma_dbell, cp->ddma_irq, cp->ddma_stat, cp->ddma_bytecnt);
+
+
+	/* Run through the descriptors
+	*/
+	dp = ctp->chan_desc_base;
+
+	do {
+		printk("dp %08x, cmd0 %08x, cmd1 %08x\n",
+			(u32)dp, dp->dscr_cmd0, dp->dscr_cmd1);
+		printk("src0 %08x, src1 %08x, dest0 %08x\n",
+			dp->dscr_source0, dp->dscr_source1, dp->dscr_dest0);
+		printk("dest1 %08x, stat %08x, nxtptr %08x\n",
+			dp->dscr_dest1, dp->dscr_stat, dp->dscr_nxtptr);
+		dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+	} while (dp != ctp->chan_desc_base);
+}
+
+#endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */
+
diff --git a/arch/mips/au1000/common/dbg_io.c b/arch/mips/au1000/common/dbg_io.c
new file mode 100644
index 0000000..7bc768e
--- /dev/null
+++ b/arch/mips/au1000/common/dbg_io.c
@@ -0,0 +1,122 @@
+
+#include <linux/config.h>
+#include <asm/io.h>
+#include <asm/mach-au1x00/au1000.h>
+
+#ifdef CONFIG_KGDB
+
+/*
+ * FIXME the user should be able to select the
+ * uart to be used for debugging.
+ */
+#define DEBUG_BASE  UART_DEBUG_BASE
+/**/
+
+/* we need uint32 uint8 */
+/* #include "types.h" */
+typedef         unsigned char uint8;
+typedef         unsigned int  uint32;
+
+#define         UART16550_BAUD_2400             2400
+#define         UART16550_BAUD_4800             4800
+#define         UART16550_BAUD_9600             9600
+#define         UART16550_BAUD_19200            19200
+#define         UART16550_BAUD_38400            38400
+#define         UART16550_BAUD_57600            57600
+#define         UART16550_BAUD_115200           115200
+
+#define         UART16550_PARITY_NONE           0
+#define         UART16550_PARITY_ODD            0x08
+#define         UART16550_PARITY_EVEN           0x18
+#define         UART16550_PARITY_MARK           0x28
+#define         UART16550_PARITY_SPACE          0x38
+
+#define         UART16550_DATA_5BIT             0x0
+#define         UART16550_DATA_6BIT             0x1
+#define         UART16550_DATA_7BIT             0x2
+#define         UART16550_DATA_8BIT             0x3
+
+#define         UART16550_STOP_1BIT             0x0
+#define         UART16550_STOP_2BIT             0x4
+
+
+#define UART_RX		0	/* Receive buffer */
+#define UART_TX		4	/* Transmit buffer */
+#define UART_IER	8	/* Interrupt Enable Register */
+#define UART_IIR	0xC	/* Interrupt ID Register */
+#define UART_FCR	0x10	/* FIFO Control Register */
+#define UART_LCR	0x14	/* Line Control Register */
+#define UART_MCR	0x18	/* Modem Control Register */
+#define UART_LSR	0x1C	/* Line Status Register */
+#define UART_MSR	0x20	/* Modem Status Register */
+#define UART_CLK	0x28	/* Baud Rat4e Clock Divider */
+#define UART_MOD_CNTRL	0x100	/* Module Control */
+
+/* memory-mapped read/write of the port */
+#define UART16550_READ(y)    (au_readl(DEBUG_BASE + y) & 0xff)
+#define UART16550_WRITE(y,z) (au_writel(z&0xff, DEBUG_BASE + y))
+
+extern unsigned long get_au1x00_uart_baud_base(void);
+extern unsigned long cal_r4koff(void);
+
+void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
+{
+
+	if (UART16550_READ(UART_MOD_CNTRL) != 0x3) {
+		UART16550_WRITE(UART_MOD_CNTRL, 3);
+	}
+	cal_r4koff();
+
+	/* disable interrupts */
+	UART16550_WRITE(UART_IER, 0);
+
+	/* set up baud rate */
+	{
+		uint32 divisor;
+
+		/* set divisor */
+		divisor = get_au1x00_uart_baud_base() / baud;
+		UART16550_WRITE(UART_CLK, divisor & 0xffff);
+	}
+
+	/* set data format */
+	UART16550_WRITE(UART_LCR, (data | parity | stop));
+}
+
+static int remoteDebugInitialized = 0;
+
+uint8 getDebugChar(void)
+{
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(UART16550_BAUD_115200,
+			  UART16550_DATA_8BIT,
+			  UART16550_PARITY_NONE,
+			  UART16550_STOP_1BIT);
+	}
+
+	while((UART16550_READ(UART_LSR) & 0x1) == 0);
+	return UART16550_READ(UART_RX);
+}
+
+
+int putDebugChar(uint8 byte)
+{
+//	int i;
+
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(UART16550_BAUD_115200,
+			  UART16550_DATA_8BIT,
+			  UART16550_PARITY_NONE,
+			  UART16550_STOP_1BIT);
+	}
+
+	while ((UART16550_READ(UART_LSR)&0x40) == 0);
+	UART16550_WRITE(UART_TX, byte);
+	//for (i=0;i<0xfff;i++);
+
+	return 1;
+}
+
+#endif
diff --git a/arch/mips/au1000/common/dma.c b/arch/mips/au1000/common/dma.c
new file mode 100644
index 0000000..372c33f
--- /dev/null
+++ b/arch/mips/au1000/common/dma.c
@@ -0,0 +1,243 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *      A DMA channel allocator for Au1000. API is modeled loosely off of
+ *      linux/kernel/dma.c.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	stevel@mvista.com or source@mvista.com
+ * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <asm/system.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1000_dma.h>
+
+#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1100)
+/*
+ * A note on resource allocation:
+ *
+ * All drivers needing DMA channels, should allocate and release them
+ * through the public routines `request_dma()' and `free_dma()'.
+ *
+ * In order to avoid problems, all processes should allocate resources in
+ * the same sequence and release them in the reverse order.
+ *
+ * So, when allocating DMAs and IRQs, first allocate the DMA, then the IRQ.
+ * When releasing them, first release the IRQ, then release the DMA. The
+ * main reason for this order is that, if you are requesting the DMA buffer
+ * done interrupt, you won't know the irq number until the DMA channel is
+ * returned from request_dma.
+ */
+
+
+DEFINE_SPINLOCK(au1000_dma_spin_lock);
+
+struct dma_chan au1000_dma_table[NUM_AU1000_DMA_CHANNELS] = {
+      {.dev_id = -1,},
+      {.dev_id = -1,},
+      {.dev_id = -1,},
+      {.dev_id = -1,},
+      {.dev_id = -1,},
+      {.dev_id = -1,},
+      {.dev_id = -1,},
+      {.dev_id = -1,}
+};
+EXPORT_SYMBOL(au1000_dma_table);
+
+// Device FIFO addresses and default DMA modes
+static const struct dma_dev {
+	unsigned int fifo_addr;
+	unsigned int dma_mode;
+} dma_dev_table[DMA_NUM_DEV] = {
+	{UART0_ADDR + UART_TX, 0},
+	{UART0_ADDR + UART_RX, 0},
+	{0, 0},
+	{0, 0},
+	{AC97C_DATA, DMA_DW16 },          // coherent
+	{AC97C_DATA, DMA_DR | DMA_DW16 }, // coherent
+	{UART3_ADDR + UART_TX, DMA_DW8 | DMA_NC},
+	{UART3_ADDR + UART_RX, DMA_DR | DMA_DW8 | DMA_NC},
+	{USBD_EP0RD, DMA_DR | DMA_DW8 | DMA_NC},
+	{USBD_EP0WR, DMA_DW8 | DMA_NC},
+	{USBD_EP2WR, DMA_DW8 | DMA_NC},
+	{USBD_EP3WR, DMA_DW8 | DMA_NC},
+	{USBD_EP4RD, DMA_DR | DMA_DW8 | DMA_NC},
+	{USBD_EP5RD, DMA_DR | DMA_DW8 | DMA_NC},
+	{I2S_DATA, DMA_DW32 | DMA_NC},
+	{I2S_DATA, DMA_DR | DMA_DW32 | DMA_NC}
+};
+
+int au1000_dma_read_proc(char *buf, char **start, off_t fpos,
+			 int length, int *eof, void *data)
+{
+	int i, len = 0;
+	struct dma_chan *chan;
+
+	for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) {
+		if ((chan = get_dma_chan(i)) != NULL) {
+			len += sprintf(buf + len, "%2d: %s\n",
+				       i, chan->dev_str);
+		}
+	}
+
+	if (fpos >= len) {
+		*start = buf;
+		*eof = 1;
+		return 0;
+	}
+	*start = buf + fpos;
+	if ((len -= fpos) > length)
+		return length;
+	*eof = 1;
+	return len;
+}
+
+// Device FIFO addresses and default DMA modes - 2nd bank
+static const struct dma_dev dma_dev_table_bank2[DMA_NUM_DEV_BANK2] = {
+	{SD0_XMIT_FIFO, DMA_DS | DMA_DW8},		// coherent
+	{SD0_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8},	// coherent
+	{SD1_XMIT_FIFO, DMA_DS | DMA_DW8},		// coherent
+	{SD1_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8}	// coherent
+};
+
+void dump_au1000_dma_channel(unsigned int dmanr)
+{
+	struct dma_chan *chan;
+
+	if (dmanr >= NUM_AU1000_DMA_CHANNELS)
+		return;
+	chan = &au1000_dma_table[dmanr];
+
+	printk(KERN_INFO "Au1000 DMA%d Register Dump:\n", dmanr);
+	printk(KERN_INFO "  mode = 0x%08x\n",
+	       au_readl(chan->io + DMA_MODE_SET));
+	printk(KERN_INFO "  addr = 0x%08x\n",
+	       au_readl(chan->io + DMA_PERIPHERAL_ADDR));
+	printk(KERN_INFO "  start0 = 0x%08x\n",
+	       au_readl(chan->io + DMA_BUFFER0_START));
+	printk(KERN_INFO "  start1 = 0x%08x\n",
+	       au_readl(chan->io + DMA_BUFFER1_START));
+	printk(KERN_INFO "  count0 = 0x%08x\n",
+	       au_readl(chan->io + DMA_BUFFER0_COUNT));
+	printk(KERN_INFO "  count1 = 0x%08x\n",
+	       au_readl(chan->io + DMA_BUFFER1_COUNT));
+}
+
+
+/*
+ * Finds a free channel, and binds the requested device to it.
+ * Returns the allocated channel number, or negative on error.
+ * Requests the DMA done IRQ if irqhandler != NULL.
+ */
+int request_au1000_dma(int dev_id, const char *dev_str,
+		       irqreturn_t (*irqhandler)(int, void *, struct pt_regs *),
+		       unsigned long irqflags,
+		       void *irq_dev_id)
+{
+	struct dma_chan *chan;
+	const struct dma_dev *dev;
+	int i, ret;
+
+#if defined(CONFIG_SOC_AU1100)
+	if (dev_id < 0 || dev_id >= (DMA_NUM_DEV + DMA_NUM_DEV_BANK2))
+		return -EINVAL;
+#else
+ 	if (dev_id < 0 || dev_id >= DMA_NUM_DEV)
+ 		return -EINVAL;
+#endif
+
+	for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) {
+		if (au1000_dma_table[i].dev_id < 0)
+			break;
+	}
+	if (i == NUM_AU1000_DMA_CHANNELS)
+		return -ENODEV;
+
+	chan = &au1000_dma_table[i];
+
+	if (dev_id >= DMA_NUM_DEV) {
+		dev_id -= DMA_NUM_DEV;
+		dev = &dma_dev_table_bank2[dev_id];
+	} else {
+		dev = &dma_dev_table[dev_id];
+	}
+
+	if (irqhandler) {
+		chan->irq = AU1000_DMA_INT_BASE + i;
+		chan->irq_dev = irq_dev_id;
+		if ((ret = request_irq(chan->irq, irqhandler, irqflags,
+				       dev_str, chan->irq_dev))) {
+			chan->irq = 0;
+			chan->irq_dev = NULL;
+			return ret;
+		}
+	} else {
+		chan->irq = 0;
+		chan->irq_dev = NULL;
+	}
+
+	// fill it in
+	chan->io = DMA_CHANNEL_BASE + i * DMA_CHANNEL_LEN;
+	chan->dev_id = dev_id;
+	chan->dev_str = dev_str;
+	chan->fifo_addr = dev->fifo_addr;
+	chan->mode = dev->dma_mode;
+
+	/* initialize the channel before returning */
+	init_dma(i);
+
+	return i;
+}
+EXPORT_SYMBOL(request_au1000_dma);
+
+void free_au1000_dma(unsigned int dmanr)
+{
+	struct dma_chan *chan = get_dma_chan(dmanr);
+	if (!chan) {
+		printk("Trying to free DMA%d\n", dmanr);
+		return;
+	}
+
+	disable_dma(dmanr);
+	if (chan->irq)
+		free_irq(chan->irq, chan->irq_dev);
+
+	chan->irq = 0;
+	chan->irq_dev = NULL;
+	chan->dev_id = -1;
+}
+EXPORT_SYMBOL(free_au1000_dma);
+
+#endif // AU1000 AU1500 AU1100
diff --git a/arch/mips/au1000/common/int-handler.S b/arch/mips/au1000/common/int-handler.S
new file mode 100644
index 0000000..1c4ca88
--- /dev/null
+++ b/arch/mips/au1000/common/int-handler.S
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: ppopov@mvista.com
+ *
+ * Interrupt dispatcher for Au1000 boards.
+ *
+ * This program is free software; you can redistribute	it and/or modify it
+ * under  the terms of	the GNU General	 Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+	.text
+	.set	macro
+	.set	noat
+	.align	5
+
+NESTED(au1000_IRQ, PT_SIZE, sp)
+	SAVE_ALL
+	CLI				# Important: mark KERNEL mode !
+
+	mfc0	t0,CP0_CAUSE		# get pending interrupts
+	mfc0	t1,CP0_STATUS		# get enabled interrupts
+	and	t0,t1			# isolate allowed ones
+
+	andi	t0,0xff00		# isolate pending bits
+	beqz	t0, 3f			# spurious interrupt
+
+	andi	a0, t0, CAUSEF_IP7
+	beq	a0, zero, 1f
+	move	a0, sp
+	jal	mips_timer_interrupt
+	j	ret_from_irq
+
+1:
+	andi	a0, t0, CAUSEF_IP2	# Interrupt Controller 0, Request 0
+	beq	a0, zero, 2f
+	move	a0,sp
+	jal	intc0_req0_irqdispatch
+	j	ret_from_irq
+2:
+	andi	a0, t0, CAUSEF_IP3	# Interrupt Controller 0, Request 1
+	beq	a0, zero, 3f
+	move	a0,sp
+	jal	intc0_req1_irqdispatch
+	j	ret_from_irq
+3:
+	andi	a0, t0, CAUSEF_IP4	# Interrupt Controller 1, Request 0
+	beq	a0, zero, 4f
+	move	a0,sp
+	jal	intc1_req0_irqdispatch
+	j	ret_from_irq
+4:
+	andi	a0, t0, CAUSEF_IP5	# Interrupt Controller 1, Request 1
+	beq	a0, zero, 5f
+	move	a0, sp
+	jal	intc1_req1_irqdispatch
+	j	ret_from_irq
+
+5:
+	move	a0, sp
+	j	spurious_interrupt
+END(au1000_IRQ)
diff --git a/arch/mips/au1000/common/irq.c b/arch/mips/au1000/common/irq.c
new file mode 100644
index 0000000..d1eb5a4
--- /dev/null
+++ b/arch/mips/au1000/common/irq.c
@@ -0,0 +1,654 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Au1000 interrupt routines.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *		ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
+ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
+ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/mach-au1x00/au1000.h>
+#ifdef CONFIG_MIPS_PB1000
+#include <asm/mach-pb1x00/pb1000.h>
+#endif
+
+#undef DEBUG_IRQ
+#ifdef DEBUG_IRQ
+/* note: prints function name for you */
+#define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+#define EXT_INTC0_REQ0 2 /* IP 2 */
+#define EXT_INTC0_REQ1 3 /* IP 3 */
+#define EXT_INTC1_REQ0 4 /* IP 4 */
+#define EXT_INTC1_REQ1 5 /* IP 5 */
+#define MIPS_TIMER_IP  7 /* IP 7 */
+
+extern asmlinkage void au1000_IRQ(void);
+extern void set_debug_traps(void);
+extern irq_cpustat_t irq_stat [NR_CPUS];
+
+static void setup_local_irq(unsigned int irq, int type, int int_req);
+static unsigned int startup_irq(unsigned int irq);
+static void end_irq(unsigned int irq_nr);
+static inline void mask_and_ack_level_irq(unsigned int irq_nr);
+static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr);
+static inline void mask_and_ack_fall_edge_irq(unsigned int irq_nr);
+static inline void mask_and_ack_either_edge_irq(unsigned int irq_nr);
+inline void local_enable_irq(unsigned int irq_nr);
+inline void local_disable_irq(unsigned int irq_nr);
+
+void	(*board_init_irq)(void);
+
+#ifdef CONFIG_PM
+extern void counter0_irq(int irq, void *dev_id, struct pt_regs *regs);
+#endif
+
+static DEFINE_SPINLOCK(irq_lock);
+
+
+static unsigned int startup_irq(unsigned int irq_nr)
+{
+	local_enable_irq(irq_nr);
+	return 0;
+}
+
+
+static void shutdown_irq(unsigned int irq_nr)
+{
+	local_disable_irq(irq_nr);
+	return;
+}
+
+
+inline void local_enable_irq(unsigned int irq_nr)
+{
+	if (irq_nr > AU1000_LAST_INTC0_INT) {
+		au_writel(1<<(irq_nr-32), IC1_MASKSET);
+		au_writel(1<<(irq_nr-32), IC1_WAKESET);
+	}
+	else {
+		au_writel(1<<irq_nr, IC0_MASKSET);
+		au_writel(1<<irq_nr, IC0_WAKESET);
+	}
+	au_sync();
+}
+
+
+inline void local_disable_irq(unsigned int irq_nr)
+{
+	if (irq_nr > AU1000_LAST_INTC0_INT) {
+		au_writel(1<<(irq_nr-32), IC1_MASKCLR);
+		au_writel(1<<(irq_nr-32), IC1_WAKECLR);
+	}
+	else {
+		au_writel(1<<irq_nr, IC0_MASKCLR);
+		au_writel(1<<irq_nr, IC0_WAKECLR);
+	}
+	au_sync();
+}
+
+
+static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr)
+{
+	if (irq_nr > AU1000_LAST_INTC0_INT) {
+		au_writel(1<<(irq_nr-32), IC1_RISINGCLR);
+		au_writel(1<<(irq_nr-32), IC1_MASKCLR);
+	}
+	else {
+		au_writel(1<<irq_nr, IC0_RISINGCLR);
+		au_writel(1<<irq_nr, IC0_MASKCLR);
+	}
+	au_sync();
+}
+
+
+static inline void mask_and_ack_fall_edge_irq(unsigned int irq_nr)
+{
+	if (irq_nr > AU1000_LAST_INTC0_INT) {
+		au_writel(1<<(irq_nr-32), IC1_FALLINGCLR);
+		au_writel(1<<(irq_nr-32), IC1_MASKCLR);
+	}
+	else {
+		au_writel(1<<irq_nr, IC0_FALLINGCLR);
+		au_writel(1<<irq_nr, IC0_MASKCLR);
+	}
+	au_sync();
+}
+
+
+static inline void mask_and_ack_either_edge_irq(unsigned int irq_nr)
+{
+	/* This may assume that we don't get interrupts from
+	 * both edges at once, or if we do, that we don't care.
+	 */
+	if (irq_nr > AU1000_LAST_INTC0_INT) {
+		au_writel(1<<(irq_nr-32), IC1_FALLINGCLR);
+		au_writel(1<<(irq_nr-32), IC1_RISINGCLR);
+		au_writel(1<<(irq_nr-32), IC1_MASKCLR);
+	}
+	else {
+		au_writel(1<<irq_nr, IC0_FALLINGCLR);
+		au_writel(1<<irq_nr, IC0_RISINGCLR);
+		au_writel(1<<irq_nr, IC0_MASKCLR);
+	}
+	au_sync();
+}
+
+
+static inline void mask_and_ack_level_irq(unsigned int irq_nr)
+{
+
+	local_disable_irq(irq_nr);
+	au_sync();
+#if defined(CONFIG_MIPS_PB1000)
+	if (irq_nr == AU1000_GPIO_15) {
+		au_writel(0x8000, PB1000_MDR); /* ack int */
+		au_sync();
+	}
+#endif
+	return;
+}
+
+
+static void end_irq(unsigned int irq_nr)
+{
+	if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
+		local_enable_irq(irq_nr);
+	}
+#if defined(CONFIG_MIPS_PB1000)
+	if (irq_nr == AU1000_GPIO_15) {
+		au_writel(0x4000, PB1000_MDR); /* enable int */
+		au_sync();
+	}
+#endif
+}
+
+unsigned long save_local_and_disable(int controller)
+{
+	int i;
+	unsigned long flags, mask;
+
+	spin_lock_irqsave(&irq_lock, flags);
+	if (controller) {
+		mask = au_readl(IC1_MASKSET);
+		for (i=32; i<64; i++) {
+			local_disable_irq(i);
+		}
+	}
+	else {
+		mask = au_readl(IC0_MASKSET);
+		for (i=0; i<32; i++) {
+			local_disable_irq(i);
+		}
+	}
+	spin_unlock_irqrestore(&irq_lock, flags);
+
+	return mask;
+}
+
+void restore_local_and_enable(int controller, unsigned long mask)
+{
+	int i;
+	unsigned long flags, new_mask;
+
+	spin_lock_irqsave(&irq_lock, flags);
+	for (i=0; i<32; i++) {
+		if (mask & (1<<i)) {
+			if (controller)
+				local_enable_irq(i+32);
+			else
+				local_enable_irq(i);
+		}
+	}
+	if (controller)
+		new_mask = au_readl(IC1_MASKSET);
+	else
+		new_mask = au_readl(IC0_MASKSET);
+
+	spin_unlock_irqrestore(&irq_lock, flags);
+}
+
+
+static struct hw_interrupt_type rise_edge_irq_type = {
+	"Au1000 Rise Edge",
+	startup_irq,
+	shutdown_irq,
+	local_enable_irq,
+	local_disable_irq,
+	mask_and_ack_rise_edge_irq,
+	end_irq,
+	NULL
+};
+
+static struct hw_interrupt_type fall_edge_irq_type = {
+	"Au1000 Fall Edge",
+	startup_irq,
+	shutdown_irq,
+	local_enable_irq,
+	local_disable_irq,
+	mask_and_ack_fall_edge_irq,
+	end_irq,
+	NULL
+};
+
+static struct hw_interrupt_type either_edge_irq_type = {
+	"Au1000 Rise or Fall Edge",
+	startup_irq,
+	shutdown_irq,
+	local_enable_irq,
+	local_disable_irq,
+	mask_and_ack_either_edge_irq,
+	end_irq,
+	NULL
+};
+
+static struct hw_interrupt_type level_irq_type = {
+	"Au1000 Level",
+	startup_irq,
+	shutdown_irq,
+	local_enable_irq,
+	local_disable_irq,
+	mask_and_ack_level_irq,
+	end_irq,
+	NULL
+};
+
+#ifdef CONFIG_PM
+void startup_match20_interrupt(void)
+{
+	local_enable_irq(AU1000_TOY_MATCH2_INT);
+}
+#endif
+
+static void setup_local_irq(unsigned int irq_nr, int type, int int_req)
+{
+	if (irq_nr > AU1000_MAX_INTR) return;
+	/* Config2[n], Config1[n], Config0[n] */
+	if (irq_nr > AU1000_LAST_INTC0_INT) {
+		switch (type) {
+			case INTC_INT_RISE_EDGE: /* 0:0:1 */
+				au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG0SET);
+				irq_desc[irq_nr].handler = &rise_edge_irq_type;
+				break;
+			case INTC_INT_FALL_EDGE: /* 0:1:0 */
+				au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG1SET);
+				au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
+				irq_desc[irq_nr].handler = &fall_edge_irq_type;
+				break;
+			case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */
+				au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG1SET);
+				au_writel(1<<(irq_nr-32), IC1_CFG0SET);
+				irq_desc[irq_nr].handler = &either_edge_irq_type;
+				break;
+			case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
+				au_writel(1<<(irq_nr-32), IC1_CFG2SET);
+				au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG0SET);
+				irq_desc[irq_nr].handler = &level_irq_type;
+				break;
+			case INTC_INT_LOW_LEVEL: /* 1:1:0 */
+				au_writel(1<<(irq_nr-32), IC1_CFG2SET);
+				au_writel(1<<(irq_nr-32), IC1_CFG1SET);
+				au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
+				irq_desc[irq_nr].handler = &level_irq_type;
+				break;
+			case INTC_INT_DISABLED: /* 0:0:0 */
+				au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
+				break;
+			default: /* disable the interrupt */
+				printk("unexpected int type %d (irq %d)\n", type, irq_nr);
+				au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
+				return;
+		}
+		if (int_req) /* assign to interrupt request 1 */
+			au_writel(1<<(irq_nr-32), IC1_ASSIGNCLR);
+		else	     /* assign to interrupt request 0 */
+			au_writel(1<<(irq_nr-32), IC1_ASSIGNSET);
+		au_writel(1<<(irq_nr-32), IC1_SRCSET);
+		au_writel(1<<(irq_nr-32), IC1_MASKCLR);
+		au_writel(1<<(irq_nr-32), IC1_WAKECLR);
+	}
+	else {
+		switch (type) {
+			case INTC_INT_RISE_EDGE: /* 0:0:1 */
+				au_writel(1<<irq_nr, IC0_CFG2CLR);
+				au_writel(1<<irq_nr, IC0_CFG1CLR);
+				au_writel(1<<irq_nr, IC0_CFG0SET);
+				irq_desc[irq_nr].handler = &rise_edge_irq_type;
+				break;
+			case INTC_INT_FALL_EDGE: /* 0:1:0 */
+				au_writel(1<<irq_nr, IC0_CFG2CLR);
+				au_writel(1<<irq_nr, IC0_CFG1SET);
+				au_writel(1<<irq_nr, IC0_CFG0CLR);
+				irq_desc[irq_nr].handler = &fall_edge_irq_type;
+				break;
+			case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */
+				au_writel(1<<irq_nr, IC0_CFG2CLR);
+				au_writel(1<<irq_nr, IC0_CFG1SET);
+				au_writel(1<<irq_nr, IC0_CFG0SET);
+				irq_desc[irq_nr].handler = &either_edge_irq_type;
+				break;
+			case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
+				au_writel(1<<irq_nr, IC0_CFG2SET);
+				au_writel(1<<irq_nr, IC0_CFG1CLR);
+				au_writel(1<<irq_nr, IC0_CFG0SET);
+				irq_desc[irq_nr].handler = &level_irq_type;
+				break;
+			case INTC_INT_LOW_LEVEL: /* 1:1:0 */
+				au_writel(1<<irq_nr, IC0_CFG2SET);
+				au_writel(1<<irq_nr, IC0_CFG1SET);
+				au_writel(1<<irq_nr, IC0_CFG0CLR);
+				irq_desc[irq_nr].handler = &level_irq_type;
+				break;
+			case INTC_INT_DISABLED: /* 0:0:0 */
+				au_writel(1<<irq_nr, IC0_CFG0CLR);
+				au_writel(1<<irq_nr, IC0_CFG1CLR);
+				au_writel(1<<irq_nr, IC0_CFG2CLR);
+				break;
+			default: /* disable the interrupt */
+				printk("unexpected int type %d (irq %d)\n", type, irq_nr);
+				au_writel(1<<irq_nr, IC0_CFG0CLR);
+				au_writel(1<<irq_nr, IC0_CFG1CLR);
+				au_writel(1<<irq_nr, IC0_CFG2CLR);
+				return;
+		}
+		if (int_req) /* assign to interrupt request 1 */
+			au_writel(1<<irq_nr, IC0_ASSIGNCLR);
+		else	     /* assign to interrupt request 0 */
+			au_writel(1<<irq_nr, IC0_ASSIGNSET);
+		au_writel(1<<irq_nr, IC0_SRCSET);
+		au_writel(1<<irq_nr, IC0_MASKCLR);
+		au_writel(1<<irq_nr, IC0_WAKECLR);
+	}
+	au_sync();
+}
+
+
+void __init arch_init_irq(void)
+{
+	int i;
+	unsigned long cp0_status;
+	au1xxx_irq_map_t *imp;
+	extern au1xxx_irq_map_t au1xxx_irq_map[];
+	extern au1xxx_irq_map_t au1xxx_ic0_map[];
+	extern int au1xxx_nr_irqs;
+	extern int au1xxx_ic0_nr_irqs;
+
+	cp0_status = read_c0_status();
+	memset(irq_desc, 0, sizeof(irq_desc));
+	set_except_vector(0, au1000_IRQ);
+
+	/* Initialize interrupt controllers to a safe state.
+	*/
+	au_writel(0xffffffff, IC0_CFG0CLR);
+	au_writel(0xffffffff, IC0_CFG1CLR);
+	au_writel(0xffffffff, IC0_CFG2CLR);
+	au_writel(0xffffffff, IC0_MASKCLR);
+	au_writel(0xffffffff, IC0_ASSIGNSET);
+	au_writel(0xffffffff, IC0_WAKECLR);
+	au_writel(0xffffffff, IC0_SRCSET);
+	au_writel(0xffffffff, IC0_FALLINGCLR);
+	au_writel(0xffffffff, IC0_RISINGCLR);
+	au_writel(0x00000000, IC0_TESTBIT);
+
+	au_writel(0xffffffff, IC1_CFG0CLR);
+	au_writel(0xffffffff, IC1_CFG1CLR);
+	au_writel(0xffffffff, IC1_CFG2CLR);
+	au_writel(0xffffffff, IC1_MASKCLR);
+	au_writel(0xffffffff, IC1_ASSIGNSET);
+	au_writel(0xffffffff, IC1_WAKECLR);
+	au_writel(0xffffffff, IC1_SRCSET);
+	au_writel(0xffffffff, IC1_FALLINGCLR);
+	au_writel(0xffffffff, IC1_RISINGCLR);
+	au_writel(0x00000000, IC1_TESTBIT);
+
+	/* Initialize IC0, which is fixed per processor.
+	*/
+	imp = au1xxx_ic0_map;
+	for (i=0; i<au1xxx_ic0_nr_irqs; i++) {
+		setup_local_irq(imp->im_irq, imp->im_type, imp->im_request);
+		imp++;
+	}
+
+	/* Now set up the irq mapping for the board.
+	*/
+	imp = au1xxx_irq_map;
+	for (i=0; i<au1xxx_nr_irqs; i++) {
+		setup_local_irq(imp->im_irq, imp->im_type, imp->im_request);
+		imp++;
+	}
+
+	set_c0_status(ALLINTS);
+
+	/* Board specific IRQ initialization.
+	*/
+	if (board_init_irq)
+		(*board_init_irq)();
+}
+
+
+/*
+ * Interrupts are nested. Even if an interrupt handler is registered
+ * as "fast", we might get another interrupt before we return from
+ * intcX_reqX_irqdispatch().
+ */
+
+void intc0_req0_irqdispatch(struct pt_regs *regs)
+{
+	int irq = 0;
+	static unsigned long intc0_req0 = 0;
+
+	intc0_req0 |= au_readl(IC0_REQ0INT);
+
+	if (!intc0_req0) return;
+
+	/*
+	 * Because of the tight timing of SETUP token to reply
+	 * transactions, the USB devices-side packet complete
+	 * interrupt needs the highest priority.
+	 */
+	if ((intc0_req0 & (1<<AU1000_USB_DEV_REQ_INT))) {
+		intc0_req0 &= ~(1<<AU1000_USB_DEV_REQ_INT);
+		do_IRQ(AU1000_USB_DEV_REQ_INT, regs);
+		return;
+	}
+
+	irq = au_ffs(intc0_req0) - 1;
+	intc0_req0 &= ~(1<<irq);
+	do_IRQ(irq, regs);
+}
+
+
+void intc0_req1_irqdispatch(struct pt_regs *regs)
+{
+	int irq = 0;
+	static unsigned long intc0_req1 = 0;
+
+	intc0_req1 |= au_readl(IC0_REQ1INT);
+
+	if (!intc0_req1) return;
+
+	irq = au_ffs(intc0_req1) - 1;
+	intc0_req1 &= ~(1<<irq);
+#ifdef CONFIG_PM
+	if (irq == AU1000_TOY_MATCH2_INT) {
+		mask_and_ack_rise_edge_irq(irq);
+		counter0_irq(irq, NULL, regs);
+		local_enable_irq(irq);
+	}
+	else
+#endif
+	{
+		do_IRQ(irq, regs);
+	}
+}
+
+
+/*
+ * Interrupt Controller 1:
+ * interrupts 32 - 63
+ */
+void intc1_req0_irqdispatch(struct pt_regs *regs)
+{
+	int irq = 0;
+	static unsigned long intc1_req0 = 0;
+
+	intc1_req0 |= au_readl(IC1_REQ0INT);
+
+	if (!intc1_req0) return;
+
+	irq = au_ffs(intc1_req0) - 1;
+	intc1_req0 &= ~(1<<irq);
+	irq += 32;
+	do_IRQ(irq, regs);
+}
+
+
+void intc1_req1_irqdispatch(struct pt_regs *regs)
+{
+	int irq = 0;
+	static unsigned long intc1_req1 = 0;
+
+	intc1_req1 |= au_readl(IC1_REQ1INT);
+
+	if (!intc1_req1) return;
+
+	irq = au_ffs(intc1_req1) - 1;
+	intc1_req1 &= ~(1<<irq);
+	irq += 32;
+	do_IRQ(irq, regs);
+}
+
+#ifdef CONFIG_PM
+
+/* Save/restore the interrupt controller state.
+ * Called from the save/restore core registers as part of the
+ * au_sleep function in power.c.....maybe I should just pm_register()
+ * them instead?
+ */
+static uint	sleep_intctl_config0[2];
+static uint	sleep_intctl_config1[2];
+static uint	sleep_intctl_config2[2];
+static uint	sleep_intctl_src[2];
+static uint	sleep_intctl_assign[2];
+static uint	sleep_intctl_wake[2];
+static uint	sleep_intctl_mask[2];
+
+void
+save_au1xxx_intctl(void)
+{
+	sleep_intctl_config0[0] = au_readl(IC0_CFG0RD);
+	sleep_intctl_config1[0] = au_readl(IC0_CFG1RD);
+	sleep_intctl_config2[0] = au_readl(IC0_CFG2RD);
+	sleep_intctl_src[0] = au_readl(IC0_SRCRD);
+	sleep_intctl_assign[0] = au_readl(IC0_ASSIGNRD);
+	sleep_intctl_wake[0] = au_readl(IC0_WAKERD);
+	sleep_intctl_mask[0] = au_readl(IC0_MASKRD);
+
+	sleep_intctl_config0[1] = au_readl(IC1_CFG0RD);
+	sleep_intctl_config1[1] = au_readl(IC1_CFG1RD);
+	sleep_intctl_config2[1] = au_readl(IC1_CFG2RD);
+	sleep_intctl_src[1] = au_readl(IC1_SRCRD);
+	sleep_intctl_assign[1] = au_readl(IC1_ASSIGNRD);
+	sleep_intctl_wake[1] = au_readl(IC1_WAKERD);
+	sleep_intctl_mask[1] = au_readl(IC1_MASKRD);
+}
+
+/* For most restore operations, we clear the entire register and
+ * then set the bits we found during the save.
+ */
+void
+restore_au1xxx_intctl(void)
+{
+	au_writel(0xffffffff, IC0_MASKCLR); au_sync();
+
+	au_writel(0xffffffff, IC0_CFG0CLR); au_sync();
+	au_writel(sleep_intctl_config0[0], IC0_CFG0SET); au_sync();
+	au_writel(0xffffffff, IC0_CFG1CLR); au_sync();
+	au_writel(sleep_intctl_config1[0], IC0_CFG1SET); au_sync();
+	au_writel(0xffffffff, IC0_CFG2CLR); au_sync();
+	au_writel(sleep_intctl_config2[0], IC0_CFG2SET); au_sync();
+	au_writel(0xffffffff, IC0_SRCCLR); au_sync();
+	au_writel(sleep_intctl_src[0], IC0_SRCSET); au_sync();
+	au_writel(0xffffffff, IC0_ASSIGNCLR); au_sync();
+	au_writel(sleep_intctl_assign[0], IC0_ASSIGNSET); au_sync();
+	au_writel(0xffffffff, IC0_WAKECLR); au_sync();
+	au_writel(sleep_intctl_wake[0], IC0_WAKESET); au_sync();
+	au_writel(0xffffffff, IC0_RISINGCLR); au_sync();
+	au_writel(0xffffffff, IC0_FALLINGCLR); au_sync();
+	au_writel(0x00000000, IC0_TESTBIT); au_sync();
+
+	au_writel(0xffffffff, IC1_MASKCLR); au_sync();
+
+	au_writel(0xffffffff, IC1_CFG0CLR); au_sync();
+	au_writel(sleep_intctl_config0[1], IC1_CFG0SET); au_sync();
+	au_writel(0xffffffff, IC1_CFG1CLR); au_sync();
+	au_writel(sleep_intctl_config1[1], IC1_CFG1SET); au_sync();
+	au_writel(0xffffffff, IC1_CFG2CLR); au_sync();
+	au_writel(sleep_intctl_config2[1], IC1_CFG2SET); au_sync();
+	au_writel(0xffffffff, IC1_SRCCLR); au_sync();
+	au_writel(sleep_intctl_src[1], IC1_SRCSET); au_sync();
+	au_writel(0xffffffff, IC1_ASSIGNCLR); au_sync();
+	au_writel(sleep_intctl_assign[1], IC1_ASSIGNSET); au_sync();
+	au_writel(0xffffffff, IC1_WAKECLR); au_sync();
+	au_writel(sleep_intctl_wake[1], IC1_WAKESET); au_sync();
+	au_writel(0xffffffff, IC1_RISINGCLR); au_sync();
+	au_writel(0xffffffff, IC1_FALLINGCLR); au_sync();
+	au_writel(0x00000000, IC1_TESTBIT); au_sync();
+
+	au_writel(sleep_intctl_mask[1], IC1_MASKSET); au_sync();
+
+	au_writel(sleep_intctl_mask[0], IC0_MASKSET); au_sync();
+}
+#endif /* CONFIG_PM */
diff --git a/arch/mips/au1000/common/pci.c b/arch/mips/au1000/common/pci.c
new file mode 100644
index 0000000..533721e
--- /dev/null
+++ b/arch/mips/au1000/common/pci.c
@@ -0,0 +1,97 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Alchemy/AMD Au1x00 pci support.
+ *
+ * Copyright 2001,2002,2003 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ *  Support for all devices (greater than 16) added by David Gathright.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/mach-au1x00/au1000.h>
+
+/* TBD */
+static struct resource pci_io_resource = {
+	"pci IO space", 
+	(u32)PCI_IO_START,
+	(u32)PCI_IO_END,
+	IORESOURCE_IO
+};
+
+static struct resource pci_mem_resource = {
+	"pci memory space", 
+	(u32)PCI_MEM_START,
+	(u32)PCI_MEM_END,
+	IORESOURCE_MEM
+};
+
+extern struct pci_ops au1x_pci_ops;
+
+static struct pci_controller au1x_controller = {
+	.pci_ops	= &au1x_pci_ops,
+	.io_resource	= &pci_io_resource,
+	.mem_resource	= &pci_mem_resource,
+};
+
+#if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)
+static unsigned long virt_io_addr;
+#endif
+
+static int __init au1x_pci_setup(void)
+{
+#if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)
+	virt_io_addr = (unsigned long)ioremap(Au1500_PCI_IO_START, 
+			Au1500_PCI_IO_END - Au1500_PCI_IO_START + 1);
+
+	if (!virt_io_addr) {
+		printk(KERN_ERR "Unable to ioremap pci space\n");
+		return 1;
+	}
+
+#ifdef CONFIG_DMA_NONCOHERENT
+	/* 
+         *  Set the NC bit in controller for Au1500 pre-AC silicon
+	 */
+	u32 prid = read_c0_prid();
+	if ( (prid & 0xFF000000) == 0x01000000 && prid < 0x01030202) {
+	       au_writel( 1<<16 | au_readl(Au1500_PCI_CFG), Au1500_PCI_CFG);
+	       printk("Non-coherent PCI accesses enabled\n");
+	}
+#endif
+
+	set_io_port_base(virt_io_addr);
+#endif
+
+	register_pci_controller(&au1x_controller);
+	return 0;
+}
+
+arch_initcall(au1x_pci_setup);
diff --git a/arch/mips/au1000/common/platform.c b/arch/mips/au1000/common/platform.c
new file mode 100644
index 0000000..0776b2d
--- /dev/null
+++ b/arch/mips/au1000/common/platform.c
@@ -0,0 +1,53 @@
+/*
+ * Platform device support for Au1x00 SoCs.
+ *
+ * Copyright 2004, Matt Porter <mporter@kernel.crashing.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/resource.h>
+
+#include <asm/mach-au1x00/au1000.h>
+
+static struct resource au1xxx_usb_ohci_resources[] = {
+	[0] = {
+		.start		= USB_OHCI_BASE,
+		.end		= USB_OHCI_BASE + USB_OHCI_LEN,
+		.flags		= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start		= AU1000_USB_HOST_INT,
+		.end		= AU1000_USB_HOST_INT,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+/* The dmamask must be set for OHCI to work */
+static u64 ohci_dmamask = ~(u32)0;
+
+static struct platform_device au1xxx_usb_ohci_device = {
+	.name		= "au1xxx-ohci",
+	.id		= 0,
+	.dev = {
+		.dma_mask		= &ohci_dmamask,
+		.coherent_dma_mask	= 0xffffffff,
+	},
+	.num_resources	= ARRAY_SIZE(au1xxx_usb_ohci_resources),
+	.resource	= au1xxx_usb_ohci_resources,
+};
+
+static struct platform_device *au1xxx_platform_devices[] __initdata = {
+	&au1xxx_usb_ohci_device,
+};
+
+int au1xxx_platform_init(void)
+{
+	return platform_add_devices(au1xxx_platform_devices, ARRAY_SIZE(au1xxx_platform_devices));
+}
+
+arch_initcall(au1xxx_platform_init);
diff --git a/arch/mips/au1000/common/power.c b/arch/mips/au1000/common/power.c
new file mode 100644
index 0000000..c40dacc
--- /dev/null
+++ b/arch/mips/au1000/common/power.c
@@ -0,0 +1,493 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Au1000 Power Management routines.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *		ppopov@mvista.com or source@mvista.com
+ *
+ *  Some of the routines are right out of init/main.c, whose
+ *  copyrights apply here.
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
+ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
+ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <linux/slab.h>
+#include <linux/sysctl.h>
+
+#include <asm/string.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/mach-au1x00/au1000.h>
+
+#ifdef CONFIG_PM
+
+#define DEBUG 1
+#ifdef DEBUG
+#  define DPRINTK(fmt, args...)	printk("%s: " fmt, __FUNCTION__ , ## args)
+#else
+#  define DPRINTK(fmt, args...)
+#endif
+
+static void calibrate_delay(void);
+
+extern void set_au1x00_speed(unsigned int new_freq);
+extern unsigned int get_au1x00_speed(void);
+extern unsigned long get_au1x00_uart_baud_base(void);
+extern void set_au1x00_uart_baud_base(unsigned long new_baud_base);
+extern unsigned long save_local_and_disable(int controller);
+extern void restore_local_and_enable(int controller, unsigned long mask);
+extern void local_enable_irq(unsigned int irq_nr);
+
+/* Quick acpi hack. This will have to change! */
+#define	CTL_ACPI 9999
+#define	ACPI_S1_SLP_TYP 19
+#define	ACPI_SLEEP 21
+
+
+static DEFINE_SPINLOCK(pm_lock);
+
+/* We need to save/restore a bunch of core registers that are
+ * either volatile or reset to some state across a processor sleep.
+ * If reading a register doesn't provide a proper result for a
+ * later restore, we have to provide a function for loading that
+ * register and save a copy.
+ *
+ * We only have to save/restore registers that aren't otherwise
+ * done as part of a driver pm_* function.
+ */
+static uint	sleep_aux_pll_cntrl;
+static uint	sleep_cpu_pll_cntrl;
+static uint	sleep_pin_function;
+static uint	sleep_uart0_inten;
+static uint	sleep_uart0_fifoctl;
+static uint	sleep_uart0_linectl;
+static uint	sleep_uart0_clkdiv;
+static uint	sleep_uart0_enable;
+static uint	sleep_usbhost_enable;
+static uint	sleep_usbdev_enable;
+static uint	sleep_static_memctlr[4][3];
+
+/* Define this to cause the value you write to /proc/sys/pm/sleep to
+ * set the TOY timer for the amount of time you want to sleep.
+ * This is done mainly for testing, but may be useful in other cases.
+ * The value is number of 32KHz ticks to sleep.
+ */
+#define SLEEP_TEST_TIMEOUT 1
+#ifdef SLEEP_TEST_TIMEOUT
+static	int	sleep_ticks;
+void wakeup_counter0_set(int ticks);
+#endif
+
+static void
+save_core_regs(void)
+{
+	extern void save_au1xxx_intctl(void);
+	extern void pm_eth0_shutdown(void);
+
+	/* Do the serial ports.....these really should be a pm_*
+	 * registered function by the driver......but of course the
+	 * standard serial driver doesn't understand our Au1xxx
+	 * unique registers.
+	 */
+	sleep_uart0_inten = au_readl(UART0_ADDR + UART_IER);
+	sleep_uart0_fifoctl = au_readl(UART0_ADDR + UART_FCR);
+	sleep_uart0_linectl = au_readl(UART0_ADDR + UART_LCR);
+	sleep_uart0_clkdiv = au_readl(UART0_ADDR + UART_CLK);
+	sleep_uart0_enable = au_readl(UART0_ADDR + UART_MOD_CNTRL);
+
+	/* Shutdown USB host/device.
+	*/
+	sleep_usbhost_enable = au_readl(USB_HOST_CONFIG);
+
+	/* There appears to be some undocumented reset register....
+	*/
+	au_writel(0, 0xb0100004); au_sync();
+	au_writel(0, USB_HOST_CONFIG); au_sync();
+
+	sleep_usbdev_enable = au_readl(USBD_ENABLE);
+	au_writel(0, USBD_ENABLE); au_sync();
+
+	/* Save interrupt controller state.
+	*/
+	save_au1xxx_intctl();
+
+	/* Clocks and PLLs.
+	*/
+	sleep_aux_pll_cntrl = au_readl(SYS_AUXPLL);
+
+	/* We don't really need to do this one, but unless we
+	 * write it again it won't have a valid value if we
+	 * happen to read it.
+	 */
+	sleep_cpu_pll_cntrl = au_readl(SYS_CPUPLL);
+
+	sleep_pin_function = au_readl(SYS_PINFUNC);
+
+	/* Save the static memory controller configuration.
+	*/
+	sleep_static_memctlr[0][0] = au_readl(MEM_STCFG0);
+	sleep_static_memctlr[0][1] = au_readl(MEM_STTIME0);
+	sleep_static_memctlr[0][2] = au_readl(MEM_STADDR0);
+	sleep_static_memctlr[1][0] = au_readl(MEM_STCFG1);
+	sleep_static_memctlr[1][1] = au_readl(MEM_STTIME1);
+	sleep_static_memctlr[1][2] = au_readl(MEM_STADDR1);
+	sleep_static_memctlr[2][0] = au_readl(MEM_STCFG2);
+	sleep_static_memctlr[2][1] = au_readl(MEM_STTIME2);
+	sleep_static_memctlr[2][2] = au_readl(MEM_STADDR2);
+	sleep_static_memctlr[3][0] = au_readl(MEM_STCFG3);
+	sleep_static_memctlr[3][1] = au_readl(MEM_STTIME3);
+	sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3);
+}
+
+static void
+restore_core_regs(void)
+{
+	extern void restore_au1xxx_intctl(void);
+	extern void wakeup_counter0_adjust(void);
+
+	au_writel(sleep_aux_pll_cntrl, SYS_AUXPLL); au_sync();
+	au_writel(sleep_cpu_pll_cntrl, SYS_CPUPLL); au_sync();
+	au_writel(sleep_pin_function, SYS_PINFUNC); au_sync();
+
+	/* Restore the static memory controller configuration.
+	*/
+	au_writel(sleep_static_memctlr[0][0], MEM_STCFG0);
+	au_writel(sleep_static_memctlr[0][1], MEM_STTIME0);
+	au_writel(sleep_static_memctlr[0][2], MEM_STADDR0);
+	au_writel(sleep_static_memctlr[1][0], MEM_STCFG1);
+	au_writel(sleep_static_memctlr[1][1], MEM_STTIME1);
+	au_writel(sleep_static_memctlr[1][2], MEM_STADDR1);
+	au_writel(sleep_static_memctlr[2][0], MEM_STCFG2);
+	au_writel(sleep_static_memctlr[2][1], MEM_STTIME2);
+	au_writel(sleep_static_memctlr[2][2], MEM_STADDR2);
+	au_writel(sleep_static_memctlr[3][0], MEM_STCFG3);
+	au_writel(sleep_static_memctlr[3][1], MEM_STTIME3);
+	au_writel(sleep_static_memctlr[3][2], MEM_STADDR3);
+
+	/* Enable the UART if it was enabled before sleep.
+	 * I guess I should define module control bits........
+	 */
+	if (sleep_uart0_enable & 0x02) {
+		au_writel(0, UART0_ADDR + UART_MOD_CNTRL); au_sync();
+		au_writel(1, UART0_ADDR + UART_MOD_CNTRL); au_sync();
+		au_writel(3, UART0_ADDR + UART_MOD_CNTRL); au_sync();
+		au_writel(sleep_uart0_inten, UART0_ADDR + UART_IER); au_sync();
+		au_writel(sleep_uart0_fifoctl, UART0_ADDR + UART_FCR); au_sync();
+		au_writel(sleep_uart0_linectl, UART0_ADDR + UART_LCR); au_sync();
+		au_writel(sleep_uart0_clkdiv, UART0_ADDR + UART_CLK); au_sync();
+	}
+
+	restore_au1xxx_intctl();
+	wakeup_counter0_adjust();
+}
+
+unsigned long suspend_mode;
+
+void wakeup_from_suspend(void)
+{
+	suspend_mode = 0;
+}
+
+int au_sleep(void)
+{
+	unsigned long wakeup, flags;
+	extern	void	save_and_sleep(void);
+
+	spin_lock_irqsave(&pm_lock,flags);
+
+	save_core_regs();
+
+	flush_cache_all();
+
+	/** The code below is all system dependent and we should probably
+	 ** have a function call out of here to set this up.  You need
+	 ** to configure the GPIO or timer interrupts that will bring
+	 ** you out of sleep.
+	 ** For testing, the TOY counter wakeup is useful.
+	 **/
+
+#if 0
+	au_writel(au_readl(SYS_PINSTATERD) & ~(1 << 11), SYS_PINSTATERD);
+
+	/* gpio 6 can cause a wake up event */
+	wakeup = au_readl(SYS_WAKEMSK);
+	wakeup &= ~(1 << 8);	/* turn off match20 wakeup */
+	wakeup |= 1 << 6;	/* turn on gpio 6 wakeup   */
+#else
+	/* For testing, allow match20 to wake us up.
+	*/
+#ifdef SLEEP_TEST_TIMEOUT
+	wakeup_counter0_set(sleep_ticks);
+#endif
+	wakeup = 1 << 8;	/* turn on match20 wakeup   */
+	wakeup = 0;
+#endif
+	au_writel(1, SYS_WAKESRC);	/* clear cause */
+	au_sync();
+	au_writel(wakeup, SYS_WAKEMSK);
+	au_sync();
+
+	save_and_sleep();
+
+	/* after a wakeup, the cpu vectors back to 0x1fc00000 so
+	 * it's up to the boot code to get us back here.
+	 */
+	restore_core_regs();
+	spin_unlock_irqrestore(&pm_lock, flags);
+	return 0;
+}
+
+static int pm_do_sleep(ctl_table * ctl, int write, struct file *file,
+		       void *buffer, size_t * len)
+{
+	int retval = 0;
+#ifdef SLEEP_TEST_TIMEOUT
+#define TMPBUFLEN2 16
+	char buf[TMPBUFLEN2], *p;
+#endif
+
+	if (!write) {
+		*len = 0;
+	} else {
+#ifdef SLEEP_TEST_TIMEOUT
+		if (*len > TMPBUFLEN2 - 1) {
+			return -EFAULT;
+		}
+		if (copy_from_user(buf, buffer, *len)) {
+			return -EFAULT;
+		}
+		buf[*len] = 0;
+		p = buf;
+		sleep_ticks = simple_strtoul(p, &p, 0);
+#endif
+		retval = pm_send_all(PM_SUSPEND, (void *) 2);
+
+		if (retval)
+			return retval;
+
+		au_sleep();
+		retval = pm_send_all(PM_RESUME, (void *) 0);
+	}
+	return retval;
+}
+
+static int pm_do_suspend(ctl_table * ctl, int write, struct file *file,
+			 void *buffer, size_t * len)
+{
+	int retval = 0;
+	void	au1k_wait(void);
+
+	if (!write) {
+		*len = 0;
+	} else {
+		retval = pm_send_all(PM_SUSPEND, (void *) 2);
+		if (retval)
+			return retval;
+		suspend_mode = 1;
+		au1k_wait();
+		retval = pm_send_all(PM_RESUME, (void *) 0);
+	}
+	return retval;
+}
+
+
+static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
+		      void *buffer, size_t * len)
+{
+	int retval = 0, i;
+	unsigned long val, pll;
+#define TMPBUFLEN 64
+#define MAX_CPU_FREQ 396
+	char buf[TMPBUFLEN], *p;
+	unsigned long flags, intc0_mask, intc1_mask;
+	unsigned long old_baud_base, old_cpu_freq, baud_rate, old_clk,
+	    old_refresh;
+	unsigned long new_baud_base, new_cpu_freq, new_clk, new_refresh;
+
+	spin_lock_irqsave(&pm_lock, flags);
+	if (!write) {
+		*len = 0;
+	} else {
+		/* Parse the new frequency */
+		if (*len > TMPBUFLEN - 1) {
+			spin_unlock_irqrestore(&pm_lock, flags);
+			return -EFAULT;
+		}
+		if (copy_from_user(buf, buffer, *len)) {
+			spin_unlock_irqrestore(&pm_lock, flags);
+			return -EFAULT;
+		}
+		buf[*len] = 0;
+		p = buf;
+		val = simple_strtoul(p, &p, 0);
+		if (val > MAX_CPU_FREQ) {
+			spin_unlock_irqrestore(&pm_lock, flags);
+			return -EFAULT;
+		}
+
+		pll = val / 12;
+		if ((pll > 33) || (pll < 7)) {	/* 396 MHz max, 84 MHz min */
+			/* revisit this for higher speed cpus */
+			spin_unlock_irqrestore(&pm_lock, flags);
+			return -EFAULT;
+		}
+
+		old_baud_base = get_au1x00_uart_baud_base();
+		old_cpu_freq = get_au1x00_speed();
+
+		new_cpu_freq = pll * 12 * 1000000;
+	        new_baud_base =  (new_cpu_freq / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16));
+		set_au1x00_speed(new_cpu_freq);
+		set_au1x00_uart_baud_base(new_baud_base);
+
+		old_refresh = au_readl(MEM_SDREFCFG) & 0x1ffffff;
+		new_refresh =
+		    ((old_refresh * new_cpu_freq) /
+		     old_cpu_freq) | (au_readl(MEM_SDREFCFG) & ~0x1ffffff);
+
+		au_writel(pll, SYS_CPUPLL);
+		au_sync_delay(1);
+		au_writel(new_refresh, MEM_SDREFCFG);
+		au_sync_delay(1);
+
+		for (i = 0; i < 4; i++) {
+			if (au_readl
+			    (UART_BASE + UART_MOD_CNTRL +
+			     i * 0x00100000) == 3) {
+				old_clk =
+				    au_readl(UART_BASE + UART_CLK +
+					  i * 0x00100000);
+				// baud_rate = baud_base/clk
+				baud_rate = old_baud_base / old_clk;
+				/* we won't get an exact baud rate and the error
+				 * could be significant enough that our new
+				 * calculation will result in a clock that will
+				 * give us a baud rate that's too far off from
+				 * what we really want.
+				 */
+				if (baud_rate > 100000)
+					baud_rate = 115200;
+				else if (baud_rate > 50000)
+					baud_rate = 57600;
+				else if (baud_rate > 30000)
+					baud_rate = 38400;
+				else if (baud_rate > 17000)
+					baud_rate = 19200;
+				else
+					(baud_rate = 9600);
+				// new_clk = new_baud_base/baud_rate
+				new_clk = new_baud_base / baud_rate;
+				au_writel(new_clk,
+				       UART_BASE + UART_CLK +
+				       i * 0x00100000);
+				au_sync_delay(10);
+			}
+		}
+	}
+
+
+	/* We don't want _any_ interrupts other than
+	 * match20. Otherwise our calibrate_delay()
+	 * calculation will be off, potentially a lot.
+	 */
+	intc0_mask = save_local_and_disable(0);
+	intc1_mask = save_local_and_disable(1);
+	local_enable_irq(AU1000_TOY_MATCH2_INT);
+	spin_unlock_irqrestore(&pm_lock, flags);
+	calibrate_delay();
+	restore_local_and_enable(0, intc0_mask);
+	restore_local_and_enable(1, intc1_mask);
+	return retval;
+}
+
+
+static struct ctl_table pm_table[] = {
+	{ACPI_S1_SLP_TYP, "suspend", NULL, 0, 0600, NULL, &pm_do_suspend},
+	{ACPI_SLEEP, "sleep", NULL, 0, 0600, NULL, &pm_do_sleep},
+	{CTL_ACPI, "freq", NULL, 0, 0600, NULL, &pm_do_freq},
+	{0}
+};
+
+static struct ctl_table pm_dir_table[] = {
+	{CTL_ACPI, "pm", NULL, 0, 0555, pm_table},
+	{0}
+};
+
+/*
+ * Initialize power interface
+ */
+static int __init pm_init(void)
+{
+	register_sysctl_table(pm_dir_table, 1);
+	return 0;
+}
+
+__initcall(pm_init);
+
+
+/*
+ * This is right out of init/main.c
+ */
+
+/* This is the number of bits of precision for the loops_per_jiffy.  Each
+   bit takes on average 1.5/HZ seconds.  This (like the original) is a little
+   better than 1% */
+#define LPS_PREC 8
+
+static void calibrate_delay(void)
+{
+	unsigned long ticks, loopbit;
+	int lps_precision = LPS_PREC;
+
+	loops_per_jiffy = (1 << 12);
+
+	while (loops_per_jiffy <<= 1) {
+		/* wait for "start of" clock tick */
+		ticks = jiffies;
+		while (ticks == jiffies)
+			/* nothing */ ;
+		/* Go .. */
+		ticks = jiffies;
+		__delay(loops_per_jiffy);
+		ticks = jiffies - ticks;
+		if (ticks)
+			break;
+	}
+
+/* Do a binary approximation to get loops_per_jiffy set to equal one clock
+   (up to lps_precision bits) */
+	loops_per_jiffy >>= 1;
+	loopbit = loops_per_jiffy;
+	while (lps_precision-- && (loopbit >>= 1)) {
+		loops_per_jiffy |= loopbit;
+		ticks = jiffies;
+		while (ticks == jiffies);
+		ticks = jiffies;
+		__delay(loops_per_jiffy);
+		if (jiffies != ticks)	/* longer than 1 tick */
+			loops_per_jiffy &= ~loopbit;
+	}
+}
+#endif				/* CONFIG_PM */
diff --git a/arch/mips/au1000/common/prom.c b/arch/mips/au1000/common/prom.c
new file mode 100644
index 0000000..22e5a85
--- /dev/null
+++ b/arch/mips/au1000/common/prom.c
@@ -0,0 +1,162 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *    PROM library initialisation code, assuming a version of
+ *    pmon is the boot code.
+ *
+ * Copyright 2000,2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * This file was derived from Carsten Langgaard's
+ * arch/mips/mips-boards/xx files.
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+
+/* #define DEBUG_CMDLINE */
+
+extern int prom_argc;
+extern char **prom_argv, **prom_envp;
+
+typedef struct
+{
+    char *name;
+/*    char *val; */
+}t_env_var;
+
+
+char * prom_getcmdline(void)
+{
+	return &(arcs_cmdline[0]);
+}
+
+void  prom_init_cmdline(void)
+{
+	char *cp;
+	int actr;
+
+	actr = 1; /* Always ignore argv[0] */
+
+	cp = &(arcs_cmdline[0]);
+	while(actr < prom_argc) {
+	        strcpy(cp, prom_argv[actr]);
+		cp += strlen(prom_argv[actr]);
+		*cp++ = ' ';
+		actr++;
+	}
+	if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
+		--cp;
+	*cp = '\0';
+
+}
+
+
+char *prom_getenv(char *envname)
+{
+	/*
+	 * Return a pointer to the given environment variable.
+	 * Environment variables are stored in the form of "memsize=64".
+	 */
+
+	t_env_var *env = (t_env_var *)prom_envp;
+	int i;
+
+	i = strlen(envname);
+
+	while(env->name) {
+		if(strncmp(envname, env->name, i) == 0) {
+			return(env->name + strlen(envname) + 1);
+		}
+		env++;
+	}
+	return(NULL);
+}
+
+inline unsigned char str2hexnum(unsigned char c)
+{
+	if(c >= '0' && c <= '9')
+		return c - '0';
+	if(c >= 'a' && c <= 'f')
+		return c - 'a' + 10;
+	if(c >= 'A' && c <= 'F')
+		return c - 'A' + 10;
+	return 0; /* foo */
+}
+
+inline void str2eaddr(unsigned char *ea, unsigned char *str)
+{
+	int i;
+
+	for(i = 0; i < 6; i++) {
+		unsigned char num;
+
+		if((*str == '.') || (*str == ':'))
+			str++;
+		num = str2hexnum(*str++) << 4;
+		num |= (str2hexnum(*str++));
+		ea[i] = num;
+	}
+}
+
+int get_ethernet_addr(char *ethernet_addr)
+{
+        char *ethaddr_str;
+
+        ethaddr_str = prom_getenv("ethaddr");
+	if (!ethaddr_str) {
+	        printk("ethaddr not set in boot prom\n");
+		return -1;
+	}
+	str2eaddr(ethernet_addr, ethaddr_str);
+
+#if 0
+	{
+		int i;
+
+	printk("get_ethernet_addr: ");
+	for (i=0; i<5; i++)
+		printk("%02x:", (unsigned char)*(ethernet_addr+i));
+	printk("%02x\n", *(ethernet_addr+i));
+	}
+#endif
+
+	return 0;
+}
+
+unsigned long __init prom_free_prom_memory(void)
+{
+	return 0;
+}
+
+EXPORT_SYMBOL(prom_getcmdline);
+EXPORT_SYMBOL(get_ethernet_addr);
+EXPORT_SYMBOL(str2eaddr);
diff --git a/arch/mips/au1000/common/puts.c b/arch/mips/au1000/common/puts.c
new file mode 100644
index 0000000..c2ae462
--- /dev/null
+++ b/arch/mips/au1000/common/puts.c
@@ -0,0 +1,145 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Low level uart routines to directly access a 16550 uart.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+#include <asm/mach-au1x00/au1000.h>
+
+#define SERIAL_BASE   UART_BASE
+#define SER_CMD       0x7
+#define SER_DATA      0x1
+#define TX_BUSY       0x20
+
+#define TIMEOUT       0xffffff
+#define SLOW_DOWN
+
+static const char digits[16] = "0123456789abcdef";
+static volatile unsigned long * const com1 = (unsigned long *)SERIAL_BASE;
+
+
+#ifdef SLOW_DOWN
+static inline void slow_down(void)
+{
+    int k;
+    for (k=0; k<10000; k++);
+}
+#else
+#define slow_down()
+#endif
+
+void
+putch(const unsigned char c)
+{
+    unsigned char ch;
+    int i = 0;
+
+    do {
+        ch = com1[SER_CMD];
+        slow_down();
+        i++;
+        if (i>TIMEOUT) {
+            break;
+        }
+    } while (0 == (ch & TX_BUSY));
+    com1[SER_DATA] = c;
+}
+
+void
+puts(unsigned char *cp)
+{
+    unsigned char ch;
+    int i = 0;
+
+    while (*cp) {
+        do {
+             ch = com1[SER_CMD];
+            slow_down();
+            i++;
+            if (i>TIMEOUT) {
+                break;
+            }
+        } while (0 == (ch & TX_BUSY));
+        com1[SER_DATA] = *cp++;
+    }
+    putch('\r');
+    putch('\n');
+}
+
+void
+fputs(const char *cp)
+{
+    unsigned char ch;
+    int i = 0;
+
+    while (*cp) {
+
+        do {
+             ch = com1[SER_CMD];
+             slow_down();
+            i++;
+            if (i>TIMEOUT) {
+                break;
+            }
+        } while (0 == (ch & TX_BUSY));
+        com1[SER_DATA] = *cp++;
+    }
+}
+
+
+void
+put64(uint64_t ul)
+{
+    int cnt;
+    unsigned ch;
+
+    cnt = 16;            /* 16 nibbles in a 64 bit long */
+    putch('0');
+    putch('x');
+    do {
+        cnt--;
+        ch = (unsigned char)(ul >> cnt * 4) & 0x0F;
+                putch(digits[ch]);
+    } while (cnt > 0);
+}
+
+void
+put32(unsigned u)
+{
+    int cnt;
+    unsigned ch;
+
+    cnt = 8;            /* 8 nibbles in a 32 bit long */
+    putch('0');
+    putch('x');
+    do {
+        cnt--;
+        ch = (unsigned char)(u >> cnt * 4) & 0x0F;
+                putch(digits[ch]);
+    } while (cnt > 0);
+}
diff --git a/arch/mips/au1000/common/reset.c b/arch/mips/au1000/common/reset.c
new file mode 100644
index 0000000..65b84db
--- /dev/null
+++ b/arch/mips/au1000/common/reset.c
@@ -0,0 +1,195 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Au1000 reset routines.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <asm/mach-au1x00/au1000.h>
+
+extern int au_sleep(void);
+extern void (*flush_cache_all)(void);
+
+void au1000_restart(char *command)
+{
+	/* Set all integrated peripherals to disabled states */
+	extern void board_reset (void);
+	u32 prid = read_c0_prid();
+
+	printk(KERN_NOTICE "\n** Resetting Integrated Peripherals\n");
+	switch (prid & 0xFF000000)
+	{
+	case 0x00000000: /* Au1000 */
+		au_writel(0x02, 0xb0000010); /* ac97_enable */
+		au_writel(0x08, 0xb017fffc); /* usbh_enable - early errata */
+		asm("sync");
+		au_writel(0x00, 0xb017fffc); /* usbh_enable */
+		au_writel(0x00, 0xb0200058); /* usbd_enable */
+		au_writel(0x00, 0xb0300040); /* ir_enable */
+		au_writel(0x00, 0xb4004104); /* mac dma */
+		au_writel(0x00, 0xb4004114); /* mac dma */
+		au_writel(0x00, 0xb4004124); /* mac dma */
+		au_writel(0x00, 0xb4004134); /* mac dma */
+		au_writel(0x00, 0xb0520000); /* macen0 */
+		au_writel(0x00, 0xb0520004); /* macen1 */
+		au_writel(0x00, 0xb1000008); /* i2s_enable  */
+		au_writel(0x00, 0xb1100100); /* uart0_enable */
+		au_writel(0x00, 0xb1200100); /* uart1_enable */
+		au_writel(0x00, 0xb1300100); /* uart2_enable */
+		au_writel(0x00, 0xb1400100); /* uart3_enable */
+		au_writel(0x02, 0xb1600100); /* ssi0_enable */
+		au_writel(0x02, 0xb1680100); /* ssi1_enable */
+		au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */
+		au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */
+		au_writel(0x00, 0xb1900028); /* sys_clksrc */
+		au_writel(0x10, 0xb1900060); /* sys_cpupll */
+		au_writel(0x00, 0xb1900064); /* sys_auxpll */
+		au_writel(0x00, 0xb1900100); /* sys_pininputen */
+		break;
+	case 0x01000000: /* Au1500 */
+		au_writel(0x02, 0xb0000010); /* ac97_enable */
+		au_writel(0x08, 0xb017fffc); /* usbh_enable - early errata */
+		asm("sync");
+		au_writel(0x00, 0xb017fffc); /* usbh_enable */
+		au_writel(0x00, 0xb0200058); /* usbd_enable */
+		au_writel(0x00, 0xb4004104); /* mac dma */
+		au_writel(0x00, 0xb4004114); /* mac dma */
+		au_writel(0x00, 0xb4004124); /* mac dma */
+		au_writel(0x00, 0xb4004134); /* mac dma */
+		au_writel(0x00, 0xb1520000); /* macen0 */
+		au_writel(0x00, 0xb1520004); /* macen1 */
+		au_writel(0x00, 0xb1100100); /* uart0_enable */
+		au_writel(0x00, 0xb1400100); /* uart3_enable */
+		au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */
+		au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */
+		au_writel(0x00, 0xb1900028); /* sys_clksrc */
+		au_writel(0x10, 0xb1900060); /* sys_cpupll */
+		au_writel(0x00, 0xb1900064); /* sys_auxpll */
+		au_writel(0x00, 0xb1900100); /* sys_pininputen */
+		break;
+	case 0x02000000: /* Au1100 */
+		au_writel(0x02, 0xb0000010); /* ac97_enable */
+		au_writel(0x08, 0xb017fffc); /* usbh_enable - early errata */
+		asm("sync");
+		au_writel(0x00, 0xb017fffc); /* usbh_enable */
+		au_writel(0x00, 0xb0200058); /* usbd_enable */
+		au_writel(0x00, 0xb0300040); /* ir_enable */
+		au_writel(0x00, 0xb4004104); /* mac dma */
+		au_writel(0x00, 0xb4004114); /* mac dma */
+		au_writel(0x00, 0xb4004124); /* mac dma */
+		au_writel(0x00, 0xb4004134); /* mac dma */
+		au_writel(0x00, 0xb0520000); /* macen0 */
+		au_writel(0x00, 0xb1000008); /* i2s_enable  */
+		au_writel(0x00, 0xb1100100); /* uart0_enable */
+		au_writel(0x00, 0xb1200100); /* uart1_enable */
+		au_writel(0x00, 0xb1400100); /* uart3_enable */
+		au_writel(0x02, 0xb1600100); /* ssi0_enable */
+		au_writel(0x02, 0xb1680100); /* ssi1_enable */
+		au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */
+		au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */
+		au_writel(0x00, 0xb1900028); /* sys_clksrc */
+		au_writel(0x10, 0xb1900060); /* sys_cpupll */
+		au_writel(0x00, 0xb1900064); /* sys_auxpll */
+		au_writel(0x00, 0xb1900100); /* sys_pininputen */
+		break;
+	case 0x03000000: /* Au1550 */
+		au_writel(0x00, 0xb1a00004); /* psc 0 */
+		au_writel(0x00, 0xb1b00004); /* psc 1 */
+		au_writel(0x00, 0xb0a00004); /* psc 2 */
+		au_writel(0x00, 0xb0b00004); /* psc 3 */
+		au_writel(0x00, 0xb017fffc); /* usbh_enable */
+		au_writel(0x00, 0xb0200058); /* usbd_enable */
+		au_writel(0x00, 0xb4004104); /* mac dma */
+		au_writel(0x00, 0xb4004114); /* mac dma */
+		au_writel(0x00, 0xb4004124); /* mac dma */
+		au_writel(0x00, 0xb4004134); /* mac dma */
+		au_writel(0x00, 0xb1520000); /* macen0 */
+		au_writel(0x00, 0xb1520004); /* macen1 */
+		au_writel(0x00, 0xb1100100); /* uart0_enable */
+		au_writel(0x00, 0xb1200100); /* uart1_enable */
+		au_writel(0x00, 0xb1400100); /* uart3_enable */
+		au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */
+		au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */
+		au_writel(0x00, 0xb1900028); /* sys_clksrc */
+		au_writel(0x10, 0xb1900060); /* sys_cpupll */
+		au_writel(0x00, 0xb1900064); /* sys_auxpll */
+		au_writel(0x00, 0xb1900100); /* sys_pininputen */
+		break;
+
+	default:
+		break;
+	}
+
+	set_c0_status(ST0_BEV | ST0_ERL);
+	set_c0_config(CONF_CM_UNCACHED);
+	flush_cache_all();
+	write_c0_wired(0);
+
+	/* Give board a chance to do a hardware reset */
+	board_reset();
+
+	/* Jump to the beggining in case board_reset() is empty */
+	__asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
+}
+
+void au1000_halt(void)
+{
+#if defined(CONFIG_MIPS_PB1550)
+	/* power off system */
+	printk("\n** Powering off Pb1550\n");
+	au_writew(au_readw(0xAF00001C) | (3<<14), 0xAF00001C);
+	au_sync();
+	while(1); /* should not get here */
+#endif
+	printk(KERN_NOTICE "\n** You can safely turn off the power\n");
+#ifdef CONFIG_MIPS_MIRAGE
+	au_writel((1 << 26) | (1 << 10), GPIO2_OUTPUT);
+#endif
+#ifdef CONFIG_PM
+	au_sleep();
+
+	/* should not get here */
+	printk(KERN_ERR "Unable to put cpu in sleep mode\n");
+	while(1);
+#else
+	while (1)
+		__asm__(".set\tmips3\n\t"
+	                "wait\n\t"
+			".set\tmips0");
+#endif
+}
+
+void au1000_power_off(void)
+{
+	au1000_halt();
+}
diff --git a/arch/mips/au1000/common/setup.c b/arch/mips/au1000/common/setup.c
new file mode 100644
index 0000000..dbc8b1b
--- /dev/null
+++ b/arch/mips/au1000/common/setup.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * Updates to 2.6, Pete Popov, Embedded Alley Solutions, Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/time.h>
+
+extern char * __init prom_getcmdline(void);
+extern void __init board_setup(void);
+extern void au1000_restart(char *);
+extern void au1000_halt(void);
+extern void au1000_power_off(void);
+extern struct resource ioport_resource;
+extern struct resource iomem_resource;
+extern void (*board_time_init)(void);
+extern void au1x_time_init(void);
+extern void (*board_timer_setup)(struct irqaction *irq);
+extern void au1x_timer_setup(struct irqaction *irq);
+extern void au1xxx_time_init(void);
+extern void au1xxx_timer_setup(struct irqaction *irq);
+extern void set_cpuspec(void);
+
+static int __init au1x00_setup(void)
+{
+	struct	cpu_spec *sp;
+	char *argptr;
+	unsigned long prid, cpupll, bclk = 1;
+
+	set_cpuspec();
+	sp = cur_cpu_spec[0];
+
+	board_setup();  /* board specific setup */
+
+	prid = read_c0_prid();
+	cpupll = (au_readl(0xB1900060) & 0x3F) * 12;
+	printk("(PRId %08lx) @ %ldMHZ\n", prid, cpupll);
+
+	bclk = sp->cpu_bclk;
+	if (bclk)
+	{
+		/* Enable BCLK switching */
+		bclk = au_readl(0xB190003C);
+		au_writel(bclk | 0x60, 0xB190003C);
+		printk("BCLK switching enabled!\n");
+	}
+
+	if (sp->cpu_od) {
+		/* Various early Au1000 Errata corrected by this */
+		set_c0_config(1<<19); /* Set Config[OD] */
+	}
+	else {
+		/* Clear to obtain best system bus performance */
+		clear_c0_config(1<<19); /* Clear Config[OD] */
+ 	}
+
+	argptr = prom_getcmdline();
+
+#ifdef CONFIG_SERIAL_AU1X00_CONSOLE
+	if ((argptr = strstr(argptr, "console=")) == NULL) {
+		argptr = prom_getcmdline();
+		strcat(argptr, " console=ttyS0,115200");
+	}
+#endif	  
+
+#ifdef CONFIG_FB_AU1100
+    if ((argptr = strstr(argptr, "video=")) == NULL) {
+        argptr = prom_getcmdline();
+        /* default panel */
+        /*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/
+#ifdef CONFIG_MIPS_HYDROGEN3
+         strcat(argptr, " video=au1100fb:panel:Hydrogen_3_NEC_panel_320x240,nohwcursor");
+#else
+        strcat(argptr, " video=au1100fb:panel:s10,nohwcursor");
+#endif
+    }
+#endif
+
+#ifdef CONFIG_FB_E1356
+	if ((argptr = strstr(argptr, "video=")) == NULL) {
+		argptr = prom_getcmdline();
+#ifdef CONFIG_MIPS_PB1000
+		strcat(argptr, " video=e1356fb:system:pb1000,mmunalign:1");
+#else
+		strcat(argptr, " video=e1356fb:system:pb1500");
+#endif
+	}
+#endif
+
+#ifdef CONFIG_FB_XPERT98
+	if ((argptr = strstr(argptr, "video=")) == NULL) {
+		argptr = prom_getcmdline();
+		strcat(argptr, " video=atyfb:1024x768-8@70");
+	}
+#endif
+
+#if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000)
+	/* au1000 does not support vra, au1500 and au1100 do */
+	strcat(argptr, " au1000_audio=vra");
+	argptr = prom_getcmdline();
+#endif
+	_machine_restart = au1000_restart;
+	_machine_halt = au1000_halt;
+	_machine_power_off = au1000_power_off;
+	board_time_init = au1xxx_time_init;
+	board_timer_setup = au1xxx_timer_setup;
+
+	/* IO/MEM resources. */
+	set_io_port_base(0);
+	ioport_resource.start = IOPORT_RESOURCE_START;
+	ioport_resource.end = IOPORT_RESOURCE_END;
+	iomem_resource.start = IOMEM_RESOURCE_START;
+	iomem_resource.end = IOMEM_RESOURCE_END;
+
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S);
+	au_writel(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL);
+	au_sync();
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S);
+	au_writel(0, SYS_TOYTRIM);
+
+	return 0;
+}
+
+early_initcall(au1x00_setup);
+
+#if defined(CONFIG_64BIT_PHYS_ADDR)
+/* This routine should be valid for all Au1x based boards */
+phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+{
+	u32 start, end;
+
+	/* Don't fixup 36 bit addresses */
+	if ((phys_addr >> 32) != 0) return phys_addr;
+
+#ifdef CONFIG_PCI
+	start = (u32)Au1500_PCI_MEM_START;
+	end = (u32)Au1500_PCI_MEM_END;
+	/* check for pci memory window */
+	if ((phys_addr >= start) && ((phys_addr + size) < end)) {
+		return (phys_t)((phys_addr - start) + Au1500_PCI_MEM_START);
+	}
+#endif
+
+	/* All Au1x SOCs have a pcmcia controller */
+	/* We setup our 32 bit pseudo addresses to be equal to the
+	 * 36 bit addr >> 4, to make it easier to check the address
+	 * and fix it.
+	 * The Au1x socket 0 phys attribute address is 0xF 4000 0000.
+	 * The pseudo address we use is 0xF400 0000. Any address over
+	 * 0xF400 0000 is a pcmcia pseudo address.
+	 */
+	if ((phys_addr >= 0xF4000000) && (phys_addr < 0xFFFFFFFF)) {
+		return (phys_t)(phys_addr << 4);
+	}
+
+	/* default nop */
+	return phys_addr;
+}
+#endif
diff --git a/arch/mips/au1000/common/sleeper.S b/arch/mips/au1000/common/sleeper.S
new file mode 100644
index 0000000..44dac3b
--- /dev/null
+++ b/arch/mips/au1000/common/sleeper.S
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2002 Embedded Edge, LLC
+ * Author: dan@embeddededge.com
+ *
+ * Sleep helper for Au1xxx sleep mode.
+ *
+ * This program is free software; you can redistribute	it and/or modify it
+ * under  the terms of	the GNU General	 Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+	.text
+	.set	macro
+	.set	noat
+	.align	5
+
+/* Save all of the processor general registers and go to sleep.
+ * A wakeup condition will get us back here to restore the registers.
+ */
+LEAF(save_and_sleep)
+
+	subu	sp, PT_SIZE
+	sw	$1, PT_R1(sp)
+	sw	$2, PT_R2(sp)
+	sw	$3, PT_R3(sp)
+	sw	$4, PT_R4(sp)
+	sw	$5, PT_R5(sp)
+	sw	$6, PT_R6(sp)
+	sw	$7, PT_R7(sp)
+	sw	$8, PT_R8(sp)
+	sw	$9, PT_R9(sp)
+	sw	$10, PT_R10(sp)
+	sw	$11, PT_R11(sp)
+	sw	$12, PT_R12(sp)
+	sw	$13, PT_R13(sp)
+	sw	$14, PT_R14(sp)
+	sw	$15, PT_R15(sp)
+	sw	$16, PT_R16(sp)
+	sw	$17, PT_R17(sp)
+	sw	$18, PT_R18(sp)
+	sw	$19, PT_R19(sp)
+	sw	$20, PT_R20(sp)
+	sw	$21, PT_R21(sp)
+	sw	$22, PT_R22(sp)
+	sw	$23, PT_R23(sp)
+	sw	$24, PT_R24(sp)
+	sw	$25, PT_R25(sp)
+	sw	$26, PT_R26(sp)
+	sw	$27, PT_R27(sp)
+	sw	$28, PT_R28(sp)
+	sw	$29, PT_R29(sp)
+	sw	$30, PT_R30(sp)
+	sw	$31, PT_R31(sp)
+	mfc0	k0, CP0_STATUS
+	sw	k0, 0x20(sp)
+	mfc0	k0, CP0_CONTEXT
+	sw	k0, 0x1c(sp)
+	mfc0	k0, CP0_PAGEMASK
+	sw	k0, 0x18(sp)
+	mfc0	k0, CP0_CONFIG
+	sw	k0, 0x14(sp)
+
+	/* Now set up the scratch registers so the boot rom will
+	 * return to this point upon wakeup.
+	 */
+	la	k0, 1f
+	lui	k1, 0xb190
+	ori	k1, 0x18
+	sw	sp, 0(k1)
+	ori 	k1, 0x1c
+	sw	k0, 0(k1)
+
+/* Put SDRAM into self refresh.  Preload instructions into cache,
+ * issue a precharge, then auto refresh, then sleep commands to it.
+ */
+ 	la	t0, sdsleep
+	.set	mips3
+ 	cache	0x14, 0(t0)
+ 	cache	0x14, 32(t0)
+ 	cache	0x14, 64(t0)
+ 	cache	0x14, 96(t0)
+	.set	mips0
+
+sdsleep:
+	lui 	k0, 0xb400
+	sw	zero, 0x001c(k0)	/* Precharge */
+	sw	zero, 0x0020(k0)	/* Auto refresh */
+	sw	zero, 0x0030(k0)	/* SDRAM sleep */
+	sync
+
+	lui 	k1, 0xb190
+	sw	zero, 0x0078(k1)	/* get ready  to sleep */
+	sync
+	sw	zero, 0x007c(k1)	/* Put processor to sleep */
+	sync
+
+	/* This is where we return upon wakeup.
+	 * Reload all of the registers and return.
+	 */
+1:	nop
+	lw	k0, 0x20(sp)
+	mtc0	k0, CP0_STATUS
+	lw	k0, 0x1c(sp)
+	mtc0	k0, CP0_CONTEXT
+	lw	k0, 0x18(sp)
+	mtc0	k0, CP0_PAGEMASK
+	lw	k0, 0x14(sp)
+	mtc0	k0, CP0_CONFIG
+	lw	$1, PT_R1(sp)
+	lw	$2, PT_R2(sp)
+	lw	$3, PT_R3(sp)
+	lw	$4, PT_R4(sp)
+	lw	$5, PT_R5(sp)
+	lw	$6, PT_R6(sp)
+	lw	$7, PT_R7(sp)
+	lw	$8, PT_R8(sp)
+	lw	$9, PT_R9(sp)
+	lw	$10, PT_R10(sp)
+	lw	$11, PT_R11(sp)
+	lw	$12, PT_R12(sp)
+	lw	$13, PT_R13(sp)
+	lw	$14, PT_R14(sp)
+	lw	$15, PT_R15(sp)
+	lw	$16, PT_R16(sp)
+	lw	$17, PT_R17(sp)
+	lw	$18, PT_R18(sp)
+	lw	$19, PT_R19(sp)
+	lw	$20, PT_R20(sp)
+	lw	$21, PT_R21(sp)
+	lw	$22, PT_R22(sp)
+	lw	$23, PT_R23(sp)
+	lw	$24, PT_R24(sp)
+	lw	$25, PT_R25(sp)
+	lw	$26, PT_R26(sp)
+	lw	$27, PT_R27(sp)
+	lw	$28, PT_R28(sp)
+	lw	$29, PT_R29(sp)
+	lw	$30, PT_R30(sp)
+	lw	$31, PT_R31(sp)
+	addiu	sp, PT_SIZE
+
+	jr	ra
+END(save_and_sleep)
diff --git a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c
new file mode 100644
index 0000000..fe418f1
--- /dev/null
+++ b/arch/mips/au1000/common/time.c
@@ -0,0 +1,469 @@
+/*
+ *
+ * Copyright (C) 2001 MontaVista Software, ppopov@mvista.com
+ * Copied and modified Carsten Langgaard's time.c
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * Setting up the clock on the MIPS boards.
+ *
+ * Update.  Always configure the kernel with CONFIG_NEW_TIME_C.  This
+ * will use the user interface gettimeofday() functions from the
+ * arch/mips/kernel/time.c, and we provide the clock interrupt processing
+ * and the timer offset compute functions.  If CONFIG_PM is selected,
+ * we also ensure the 32KHz timer is available.   -- Dan
+ */
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/hardirq.h>
+
+#include <asm/compiler.h>
+#include <asm/mipsregs.h>
+#include <asm/ptrace.h>
+#include <asm/time.h>
+#include <asm/div64.h>
+#include <asm/mach-au1x00/au1000.h>
+
+#include <linux/mc146818rtc.h>
+#include <linux/timex.h>
+
+extern void startup_match20_interrupt(void);
+extern void do_softirq(void);
+extern volatile unsigned long wall_jiffies;
+unsigned long missed_heart_beats = 0;
+
+static unsigned long r4k_offset; /* Amount to increment compare reg each time */
+static unsigned long r4k_cur;    /* What counter should be at next timer irq */
+int	no_au1xxx_32khz;
+void	(*au1k_wait_ptr)(void);
+
+/* Cycle counter value at the previous timer interrupt.. */
+static unsigned int timerhi = 0, timerlo = 0;
+
+#ifdef CONFIG_PM
+#define MATCH20_INC 328
+extern void startup_match20_interrupt(void);
+static unsigned long last_pc0, last_match20;
+#endif
+
+static DEFINE_SPINLOCK(time_lock);
+
+static inline void ack_r4ktimer(unsigned long newval)
+{
+	write_c0_compare(newval);
+}
+
+/*
+ * There are a lot of conceptually broken versions of the MIPS timer interrupt
+ * handler floating around.  This one is rather different, but the algorithm
+ * is provably more robust.
+ */
+unsigned long wtimer;
+void mips_timer_interrupt(struct pt_regs *regs)
+{
+	int irq = 63;
+	unsigned long count;
+
+	irq_enter();
+	kstat_this_cpu.irqs[irq]++;
+
+	if (r4k_offset == 0)
+		goto null;
+
+	do {
+		count = read_c0_count();
+		timerhi += (count < timerlo);   /* Wrap around */
+		timerlo = count;
+
+		kstat_this_cpu.irqs[irq]++;
+		do_timer(regs);
+#ifndef CONFIG_SMP
+		update_process_times(user_mode(regs));
+#endif
+		r4k_cur += r4k_offset;
+		ack_r4ktimer(r4k_cur);
+
+	} while (((unsigned long)read_c0_count()
+	         - r4k_cur) < 0x7fffffff);
+
+	irq_exit();
+	return;
+
+null:
+	ack_r4ktimer(0);
+}
+
+#ifdef CONFIG_PM
+void counter0_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned long pc0;
+	int time_elapsed;
+	static int jiffie_drift = 0;
+
+	kstat.irqs[0][irq]++;
+	if (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20) {
+		/* should never happen! */
+		printk(KERN_WARNING "counter 0 w status eror\n");
+		return;
+	}
+
+	pc0 = au_readl(SYS_TOYREAD);
+	if (pc0 < last_match20) {
+		/* counter overflowed */
+		time_elapsed = (0xffffffff - last_match20) + pc0;
+	}
+	else {
+		time_elapsed = pc0 - last_match20;
+	}
+
+	while (time_elapsed > 0) {
+		do_timer(regs);
+#ifndef CONFIG_SMP
+		update_process_times(user_mode(regs));
+#endif
+		time_elapsed -= MATCH20_INC;
+		last_match20 += MATCH20_INC;
+		jiffie_drift++;
+	}
+
+	last_pc0 = pc0;
+	au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
+	au_sync();
+
+	/* our counter ticks at 10.009765625 ms/tick, we we're running
+	 * almost 10uS too slow per tick.
+	 */
+
+	if (jiffie_drift >= 999) {
+		jiffie_drift -= 999;
+		do_timer(regs); /* increment jiffies by one */
+#ifndef CONFIG_SMP
+		update_process_times(user_mode(regs));
+#endif
+	}
+}
+
+/* When we wakeup from sleep, we have to "catch up" on all of the
+ * timer ticks we have missed.
+ */
+void
+wakeup_counter0_adjust(void)
+{
+	unsigned long pc0;
+	int time_elapsed;
+
+	pc0 = au_readl(SYS_TOYREAD);
+	if (pc0 < last_match20) {
+		/* counter overflowed */
+		time_elapsed = (0xffffffff - last_match20) + pc0;
+	}
+	else {
+		time_elapsed = pc0 - last_match20;
+	}
+
+	while (time_elapsed > 0) {
+		time_elapsed -= MATCH20_INC;
+		last_match20 += MATCH20_INC;
+	}
+
+	last_pc0 = pc0;
+	au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
+	au_sync();
+
+}
+
+/* This is just for debugging to set the timer for a sleep delay.
+*/
+void
+wakeup_counter0_set(int ticks)
+{
+	unsigned long pc0;
+
+	pc0 = au_readl(SYS_TOYREAD);
+	last_pc0 = pc0;
+	au_writel(last_match20 + (MATCH20_INC * ticks), SYS_TOYMATCH2);
+	au_sync();
+}
+#endif
+
+/* I haven't found anyone that doesn't use a 12 MHz source clock,
+ * but just in case.....
+ */
+#ifdef CONFIG_AU1000_SRC_CLK
+#define AU1000_SRC_CLK	CONFIG_AU1000_SRC_CLK
+#else
+#define AU1000_SRC_CLK	12000000
+#endif
+
+/*
+ * We read the real processor speed from the PLL.  This is important
+ * because it is more accurate than computing it from the 32KHz
+ * counter, if it exists.  If we don't have an accurate processor
+ * speed, all of the peripherals that derive their clocks based on
+ * this advertised speed will introduce error and sometimes not work
+ * properly.  This function is futher convoluted to still allow configurations
+ * to do that in case they have really, really old silicon with a
+ * write-only PLL register, that we need the 32KHz when power management
+ * "wait" is enabled, and we need to detect if the 32KHz isn't present
+ * but requested......got it? :-)		-- Dan
+ */
+unsigned long cal_r4koff(void)
+{
+	unsigned long count;
+	unsigned long cpu_speed;
+	unsigned long flags;
+	unsigned long counter;
+
+	spin_lock_irqsave(&time_lock, flags);
+
+	/* Power management cares if we don't have a 32KHz counter.
+	*/
+	no_au1xxx_32khz = 0;
+	counter = au_readl(SYS_COUNTER_CNTRL);
+	if (counter & SYS_CNTRL_E0) {
+		int trim_divide = 16;
+
+		au_writel(counter | SYS_CNTRL_EN1, SYS_COUNTER_CNTRL);
+
+		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S);
+		/* RTC now ticks at 32.768/16 kHz */
+		au_writel(trim_divide-1, SYS_RTCTRIM);
+		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S);
+
+		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S);
+		au_writel (0, SYS_TOYWRITE);
+		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S);
+
+#if defined(CONFIG_AU1000_USE32K)
+		{
+			unsigned long start, end;
+
+			start = au_readl(SYS_RTCREAD);
+			start += 2;
+			/* wait for the beginning of a new tick
+			*/
+			while (au_readl(SYS_RTCREAD) < start);
+
+			/* Start r4k counter.
+			*/
+			write_c0_count(0);
+
+			/* Wait 0.5 seconds.
+			*/
+			end = start + (32768 / trim_divide)/2;
+
+			while (end > au_readl(SYS_RTCREAD));
+
+			count = read_c0_count();
+			cpu_speed = count * 2;
+		}
+#else
+		cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * 
+			AU1000_SRC_CLK;
+		count = cpu_speed / 2;
+#endif
+	}
+	else {
+		/* The 32KHz oscillator isn't running, so assume there
+		 * isn't one and grab the processor speed from the PLL.
+		 * NOTE: some old silicon doesn't allow reading the PLL.
+		 */
+		cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK;
+		count = cpu_speed / 2;
+		no_au1xxx_32khz = 1;
+	}
+	mips_hpt_frequency = count;
+	// Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16)
+	set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16));
+	spin_unlock_irqrestore(&time_lock, flags);
+	return (cpu_speed / HZ);
+}
+
+/* This is for machines which generate the exact clock. */
+#define USECS_PER_JIFFY (1000000/HZ)
+#define USECS_PER_JIFFY_FRAC (0x100000000LL*1000000/HZ&0xffffffff)
+
+static unsigned long
+div64_32(unsigned long v1, unsigned long v2, unsigned long v3)
+{
+	unsigned long r0;
+	do_div64_32(r0, v1, v2, v3);
+	return r0;
+}
+
+static unsigned long do_fast_cp0_gettimeoffset(void)
+{
+	u32 count;
+	unsigned long res, tmp;
+	unsigned long r0;
+
+	/* Last jiffy when do_fast_gettimeoffset() was called. */
+	static unsigned long last_jiffies=0;
+	unsigned long quotient;
+
+	/*
+	 * Cached "1/(clocks per usec)*2^32" value.
+	 * It has to be recalculated once each jiffy.
+	 */
+	static unsigned long cached_quotient=0;
+
+	tmp = jiffies;
+
+	quotient = cached_quotient;
+
+	if (tmp && last_jiffies != tmp) {
+		last_jiffies = tmp;
+		if (last_jiffies != 0) {
+			r0 = div64_32(timerhi, timerlo, tmp);
+			quotient = div64_32(USECS_PER_JIFFY, USECS_PER_JIFFY_FRAC, r0);
+			cached_quotient = quotient;
+		}
+	}
+
+	/* Get last timer tick in absolute kernel time */
+	count = read_c0_count();
+
+	/* .. relative to previous jiffy (32 bits is enough) */
+	count -= timerlo;
+
+	__asm__("multu\t%1,%2\n\t"
+		"mfhi\t%0"
+		: "=r" (res)
+		: "r" (count), "r" (quotient)
+		: "hi", "lo", GCC_REG_ACCUM);
+
+	/*
+ 	 * Due to possible jiffies inconsistencies, we need to check 
+	 * the result so that we'll get a timer that is monotonic.
+	 */
+	if (res >= USECS_PER_JIFFY)
+		res = USECS_PER_JIFFY-1;
+
+	return res;
+}
+
+#ifdef CONFIG_PM
+static unsigned long do_fast_pm_gettimeoffset(void)
+{
+	unsigned long pc0;
+	unsigned long offset;
+
+	pc0 = au_readl(SYS_TOYREAD);
+	au_sync();
+	offset = pc0 - last_pc0;
+	if (offset > 2*MATCH20_INC) {
+		printk("huge offset %x, last_pc0 %x last_match20 %x pc0 %x\n", 
+				(unsigned)offset, (unsigned)last_pc0, 
+				(unsigned)last_match20, (unsigned)pc0);
+	}
+	offset = (unsigned long)((offset * 305) / 10);
+	return offset;
+}
+#endif
+
+void au1xxx_timer_setup(struct irqaction *irq)
+{
+        unsigned int est_freq;
+	extern unsigned long (*do_gettimeoffset)(void);
+	extern void au1k_wait(void);
+
+	printk("calculating r4koff... ");
+	r4k_offset = cal_r4koff();
+	printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset);
+
+	//est_freq = 2*r4k_offset*HZ;	
+	est_freq = r4k_offset*HZ;	
+	est_freq += 5000;    /* round */
+	est_freq -= est_freq%10000;
+	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, 
+	       (est_freq%1000000)*100/1000000);
+ 	set_au1x00_speed(est_freq);
+ 	set_au1x00_lcd_clock(); // program the LCD clock
+
+	r4k_cur = (read_c0_count() + r4k_offset);
+	write_c0_compare(r4k_cur);
+
+#ifdef CONFIG_PM
+	/*
+	 * setup counter 0, since it keeps ticking after a
+	 * 'wait' instruction has been executed. The CP0 timer and
+	 * counter 1 do NOT continue running after 'wait'
+	 *
+	 * It's too early to call request_irq() here, so we handle
+	 * counter 0 interrupt as a special irq and it doesn't show
+	 * up under /proc/interrupts.
+	 *
+	 * Check to ensure we really have a 32KHz oscillator before
+	 * we do this.
+	 */
+	if (no_au1xxx_32khz) {
+		unsigned int c0_status;
+
+		printk("WARNING: no 32KHz clock found.\n");
+		do_gettimeoffset = do_fast_cp0_gettimeoffset;
+
+		/* Ensure we get CPO_COUNTER interrupts.
+		*/
+		c0_status = read_c0_status();
+		c0_status |= IE_IRQ5;
+		write_c0_status(c0_status);
+	}
+	else {
+		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
+		au_writel(0, SYS_TOYWRITE);
+		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
+
+		au_writel(au_readl(SYS_WAKEMSK) | (1<<8), SYS_WAKEMSK);
+		au_writel(~0, SYS_WAKESRC);
+		au_sync();
+		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
+
+		/* setup match20 to interrupt once every 10ms */
+		last_pc0 = last_match20 = au_readl(SYS_TOYREAD);
+		au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
+		au_sync();
+		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
+		startup_match20_interrupt();
+
+		do_gettimeoffset = do_fast_pm_gettimeoffset;
+
+		/* We can use the real 'wait' instruction.
+		*/
+		au1k_wait_ptr = au1k_wait;
+	}
+
+#else
+	/* We have to do this here instead of in timer_init because
+	 * the generic code in arch/mips/kernel/time.c will write
+	 * over our function pointer.
+	 */
+	do_gettimeoffset = do_fast_cp0_gettimeoffset;
+#endif
+}
+
+void __init au1xxx_time_init(void)
+{
+}
diff --git a/arch/mips/au1000/common/usbdev.c b/arch/mips/au1000/common/usbdev.c
new file mode 100644
index 0000000..447a9a4
--- /dev/null
+++ b/arch/mips/au1000/common/usbdev.c
@@ -0,0 +1,1557 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Au1000 USB Device-Side (device layer)
+ *
+ * Copyright 2001-2002 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *		stevel@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
+ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
+ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/fcntl.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/smp_lock.h>
+#define DEBUG
+#include <linux/usb.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/au1000.h>
+#include <asm/au1000_dma.h>
+#include <asm/au1000_usbdev.h>
+
+#ifdef DEBUG
+#undef VDEBUG
+#ifdef VDEBUG
+#define vdbg(fmt, arg...) printk(KERN_DEBUG __FILE__ ": " fmt "\n" , ## arg)
+#else
+#define vdbg(fmt, arg...) do {} while (0)
+#endif
+#else
+#define vdbg(fmt, arg...) do {} while (0)
+#endif
+
+#define ALLOC_FLAGS (in_interrupt () ? GFP_ATOMIC : GFP_KERNEL)
+
+#define EP_FIFO_DEPTH 8
+
+typedef enum {
+	SETUP_STAGE = 0,
+	DATA_STAGE,
+	STATUS_STAGE
+} ep0_stage_t;
+
+typedef struct {
+	int read_fifo;
+	int write_fifo;
+	int ctrl_stat;
+	int read_fifo_status;
+	int write_fifo_status;
+} endpoint_reg_t;
+
+typedef struct {
+	usbdev_pkt_t *head;
+	usbdev_pkt_t *tail;
+	int count;
+} pkt_list_t;
+
+typedef struct {
+	int active;
+	struct usb_endpoint_descriptor *desc;
+	endpoint_reg_t *reg;
+	/* Only one of these are used, unless this is the control ep */
+	pkt_list_t inlist;
+	pkt_list_t outlist;
+	unsigned int indma, outdma; /* DMA channel numbers for IN, OUT */
+	/* following are extracted from endpoint descriptor for easy access */
+	int max_pkt_size;
+	int type;
+	int direction;
+	/* WE assign endpoint addresses! */
+	int address;
+	spinlock_t lock;
+} endpoint_t;
+
+
+static struct usb_dev {
+	endpoint_t ep[6];
+	ep0_stage_t ep0_stage;
+
+	struct usb_device_descriptor *   dev_desc;
+	struct usb_interface_descriptor* if_desc;
+	struct usb_config_descriptor *   conf_desc;
+	u8 *                             full_conf_desc;
+	struct usb_string_descriptor *   str_desc[6];
+
+	/* callback to function layer */
+	void (*func_cb)(usbdev_cb_type_t type, unsigned long arg,
+			void *cb_data);
+	void* cb_data;
+
+	usbdev_state_t state;	// device state
+	int suspended;		// suspended flag
+	int address;		// device address
+	int interface;
+	int num_ep;
+	u8 alternate_setting;
+	u8 configuration;	// configuration value
+	int remote_wakeup_en;
+} usbdev;
+
+
+static endpoint_reg_t ep_reg[] = {
+	// FIFO's 0 and 1 are EP0 default control
+	{USBD_EP0RD, USBD_EP0WR, USBD_EP0CS, USBD_EP0RDSTAT, USBD_EP0WRSTAT },
+	{0},
+	// FIFO 2 is EP2, IN
+	{ -1, USBD_EP2WR, USBD_EP2CS, -1, USBD_EP2WRSTAT },
+	// FIFO 3 is EP3, IN
+	{    -1,     USBD_EP3WR, USBD_EP3CS,     -1,         USBD_EP3WRSTAT },
+	// FIFO 4 is EP4, OUT
+	{USBD_EP4RD,     -1,     USBD_EP4CS, USBD_EP4RDSTAT,     -1         },
+	// FIFO 5 is EP5, OUT
+	{USBD_EP5RD,     -1,     USBD_EP5CS, USBD_EP5RDSTAT,     -1         }
+};
+
+static struct {
+	unsigned int id;
+	const char *str;
+} ep_dma_id[] = {
+	{ DMA_ID_USBDEV_EP0_TX, "USBDev EP0 IN" },
+	{ DMA_ID_USBDEV_EP0_RX, "USBDev EP0 OUT" },
+	{ DMA_ID_USBDEV_EP2_TX, "USBDev EP2 IN" },
+	{ DMA_ID_USBDEV_EP3_TX, "USBDev EP3 IN" },
+	{ DMA_ID_USBDEV_EP4_RX, "USBDev EP4 OUT" },
+	{ DMA_ID_USBDEV_EP5_RX, "USBDev EP5 OUT" }
+};
+
+#define DIR_OUT 0
+#define DIR_IN  (1<<3)
+
+#define CONTROL_EP USB_ENDPOINT_XFER_CONTROL
+#define BULK_EP    USB_ENDPOINT_XFER_BULK
+
+static inline endpoint_t *
+epaddr_to_ep(struct usb_dev* dev, int ep_addr)
+{
+	if (ep_addr >= 0 && ep_addr < 2)
+		return &dev->ep[0];
+	if (ep_addr < 6)
+		return &dev->ep[ep_addr];
+	return NULL;
+}
+
+static const char* std_req_name[] = {
+	"GET_STATUS",
+	"CLEAR_FEATURE",
+	"RESERVED",
+	"SET_FEATURE",
+	"RESERVED",
+	"SET_ADDRESS",
+	"GET_DESCRIPTOR",
+	"SET_DESCRIPTOR",
+	"GET_CONFIGURATION",
+	"SET_CONFIGURATION",
+	"GET_INTERFACE",
+	"SET_INTERFACE",
+	"SYNCH_FRAME"
+};
+
+static inline const char*
+get_std_req_name(int req)
+{
+	return (req >= 0 && req <= 12) ? std_req_name[req] : "UNKNOWN";
+}
+
+#if 0
+static void
+dump_setup(struct usb_ctrlrequest* s)
+{
+	dbg("%s: requesttype=%d", __FUNCTION__, s->requesttype);
+	dbg("%s: request=%d %s", __FUNCTION__, s->request,
+	    get_std_req_name(s->request));
+	dbg("%s: value=0x%04x", __FUNCTION__, s->wValue);
+	dbg("%s: index=%d", __FUNCTION__, s->index);
+	dbg("%s: length=%d", __FUNCTION__, s->length);
+}
+#endif
+
+static inline usbdev_pkt_t *
+alloc_packet(endpoint_t * ep, int data_size, void* data)
+{
+	usbdev_pkt_t* pkt = kmalloc(sizeof(usbdev_pkt_t) + data_size,
+				    ALLOC_FLAGS);
+	if (!pkt)
+		return NULL;
+	pkt->ep_addr = ep->address;
+	pkt->size = data_size;
+	pkt->status = 0;
+	pkt->next = NULL;
+	if (data)
+		memcpy(pkt->payload, data, data_size);
+
+	return pkt;
+}
+
+
+/*
+ * Link a packet to the tail of the enpoint's packet list.
+ * EP spinlock must be held when calling.
+ */
+static void
+link_tail(endpoint_t * ep, pkt_list_t * list, usbdev_pkt_t * pkt)
+{
+	if (!list->tail) {
+		list->head = list->tail = pkt;
+		list->count = 1;
+	} else {
+		list->tail->next = pkt;
+		list->tail = pkt;
+		list->count++;
+	}
+}
+
+/*
+ * Unlink and return a packet from the head of the given packet
+ * list. It is the responsibility of the caller to free the packet.
+ * EP spinlock must be held when calling.
+ */
+static usbdev_pkt_t *
+unlink_head(pkt_list_t * list)
+{
+	usbdev_pkt_t *pkt;
+
+	pkt = list->head;
+	if (!pkt || !list->count) {
+		return NULL;
+	}
+
+	list->head = pkt->next;
+	if (!list->head) {
+		list->head = list->tail = NULL;
+		list->count = 0;
+	} else
+		list->count--;
+
+	return pkt;
+}
+
+/*
+ * Create and attach a new packet to the tail of the enpoint's
+ * packet list. EP spinlock must be held when calling.
+ */
+static usbdev_pkt_t *
+add_packet(endpoint_t * ep, pkt_list_t * list, int size)
+{
+	usbdev_pkt_t *pkt = alloc_packet(ep, size, NULL);
+	if (!pkt)
+		return NULL;
+
+	link_tail(ep, list, pkt);
+	return pkt;
+}
+
+
+/*
+ * Unlink and free a packet from the head of the enpoint's
+ * packet list. EP spinlock must be held when calling.
+ */
+static inline void
+free_packet(pkt_list_t * list)
+{
+	kfree(unlink_head(list));
+}
+
+/* EP spinlock must be held when calling. */
+static inline void
+flush_pkt_list(pkt_list_t * list)
+{
+	while (list->count)
+		free_packet(list);
+}
+
+/* EP spinlock must be held when calling */
+static inline void
+flush_write_fifo(endpoint_t * ep)
+{
+	if (ep->reg->write_fifo_status >= 0) {
+		au_writel(USBDEV_FSTAT_FLUSH | USBDEV_FSTAT_UF |
+			  USBDEV_FSTAT_OF,
+			  ep->reg->write_fifo_status);
+		//udelay(100);
+		//au_writel(USBDEV_FSTAT_UF | USBDEV_FSTAT_OF,
+		//	  ep->reg->write_fifo_status);
+	}
+}
+
+/* EP spinlock must be held when calling */
+static inline void
+flush_read_fifo(endpoint_t * ep)
+{
+	if (ep->reg->read_fifo_status >= 0) {
+		au_writel(USBDEV_FSTAT_FLUSH | USBDEV_FSTAT_UF |
+			  USBDEV_FSTAT_OF,
+			  ep->reg->read_fifo_status);
+		//udelay(100);
+		//au_writel(USBDEV_FSTAT_UF | USBDEV_FSTAT_OF,
+		//	  ep->reg->read_fifo_status);
+	}
+}
+
+
+/* EP spinlock must be held when calling. */
+static void
+endpoint_flush(endpoint_t * ep)
+{
+	// First, flush all packets
+	flush_pkt_list(&ep->inlist);
+	flush_pkt_list(&ep->outlist);
+
+	// Now flush the endpoint's h/w FIFO(s)
+	flush_write_fifo(ep);
+	flush_read_fifo(ep);
+}
+
+/* EP spinlock must be held when calling. */
+static void
+endpoint_stall(endpoint_t * ep)
+{
+	u32 cs;
+
+	warn(__FUNCTION__);
+
+	cs = au_readl(ep->reg->ctrl_stat) | USBDEV_CS_STALL;
+	au_writel(cs, ep->reg->ctrl_stat);
+}
+
+/* EP spinlock must be held when calling. */
+static void
+endpoint_unstall(endpoint_t * ep)
+{
+	u32 cs;
+
+	warn(__FUNCTION__);
+
+	cs = au_readl(ep->reg->ctrl_stat) & ~USBDEV_CS_STALL;
+	au_writel(cs, ep->reg->ctrl_stat);
+}
+
+static void
+endpoint_reset_datatoggle(endpoint_t * ep)
+{
+	// FIXME: is this possible?
+}
+
+
+/* EP spinlock must be held when calling. */
+static int
+endpoint_fifo_read(endpoint_t * ep)
+{
+	int read_count = 0;
+	u8 *bufptr;
+	usbdev_pkt_t *pkt = ep->outlist.tail;
+
+	if (!pkt)
+		return -EINVAL;
+
+	bufptr = &pkt->payload[pkt->size];
+	while (au_readl(ep->reg->read_fifo_status) & USBDEV_FSTAT_FCNT_MASK) {
+		*bufptr++ = au_readl(ep->reg->read_fifo) & 0xff;
+		read_count++;
+		pkt->size++;
+	}
+
+	return read_count;
+}
+
+#if 0
+/* EP spinlock must be held when calling. */
+static int
+endpoint_fifo_write(endpoint_t * ep, int index)
+{
+	int write_count = 0;
+	u8 *bufptr;
+	usbdev_pkt_t *pkt = ep->inlist.head;
+
+	if (!pkt)
+		return -EINVAL;
+
+	bufptr = &pkt->payload[index];
+	while ((au_readl(ep->reg->write_fifo_status) &
+		USBDEV_FSTAT_FCNT_MASK) < EP_FIFO_DEPTH) {
+		if (bufptr < pkt->payload + pkt->size) {
+			au_writel(*bufptr++, ep->reg->write_fifo);
+			write_count++;
+		} else {
+			break;
+		}
+	}
+
+	return write_count;
+}
+#endif
+
+/*
+ * This routine is called to restart transmission of a packet.
+ * The endpoint's TSIZE must be set to the new packet's size,
+ * and DMA to the write FIFO needs to be restarted.
+ * EP spinlock must be held when calling.
+ */
+static void
+kickstart_send_packet(endpoint_t * ep)
+{
+	u32 cs;
+	usbdev_pkt_t *pkt = ep->inlist.head;
+
+	vdbg("%s: ep%d, pkt=%p", __FUNCTION__, ep->address, pkt);
+
+	if (!pkt) {
+		err("%s: head=NULL! list->count=%d", __FUNCTION__,
+		    ep->inlist.count);
+		return;
+	}
+
+	dma_cache_wback_inv((unsigned long)pkt->payload, pkt->size);
+
+	/*
+	 * make sure FIFO is empty
+	 */
+	flush_write_fifo(ep);
+
+	cs = au_readl(ep->reg->ctrl_stat) & USBDEV_CS_STALL;
+	cs |= (pkt->size << USBDEV_CS_TSIZE_BIT);
+	au_writel(cs, ep->reg->ctrl_stat);
+
+	if (get_dma_active_buffer(ep->indma) == 1) {
+		set_dma_count1(ep->indma, pkt->size);
+		set_dma_addr1(ep->indma, virt_to_phys(pkt->payload));
+		enable_dma_buffer1(ep->indma);	// reenable
+	} else {
+		set_dma_count0(ep->indma, pkt->size);
+		set_dma_addr0(ep->indma, virt_to_phys(pkt->payload));
+		enable_dma_buffer0(ep->indma);	// reenable
+	}
+	if (dma_halted(ep->indma))
+		start_dma(ep->indma);
+}
+
+
+/*
+ * This routine is called when a packet in the inlist has been
+ * completed. Frees the completed packet and starts sending the
+ * next. EP spinlock must be held when calling.
+ */
+static usbdev_pkt_t *
+send_packet_complete(endpoint_t * ep)
+{
+	usbdev_pkt_t *pkt = unlink_head(&ep->inlist);
+
+	if (pkt) {
+		pkt->status =
+			(au_readl(ep->reg->ctrl_stat) & USBDEV_CS_NAK) ?
+			PKT_STATUS_NAK : PKT_STATUS_ACK;
+
+		vdbg("%s: ep%d, %s pkt=%p, list count=%d", __FUNCTION__,
+		     ep->address, (pkt->status & PKT_STATUS_NAK) ?
+		     "NAK" : "ACK", pkt, ep->inlist.count);
+	}
+
+	/*
+	 * The write fifo should already be drained if things are
+	 * working right, but flush it anyway just in case.
+	 */
+	flush_write_fifo(ep);
+
+	// begin transmitting next packet in the inlist
+	if (ep->inlist.count) {
+		kickstart_send_packet(ep);
+	}
+
+	return pkt;
+}
+
+/*
+ * Add a new packet to the tail of the given ep's packet
+ * inlist. The transmit complete interrupt frees packets from
+ * the head of this list. EP spinlock must be held when calling.
+ */
+static int
+send_packet(struct usb_dev* dev, usbdev_pkt_t *pkt, int async)
+{
+	pkt_list_t *list;
+	endpoint_t* ep;
+
+	if (!pkt || !(ep = epaddr_to_ep(dev, pkt->ep_addr)))
+		return -EINVAL;
+
+	if (!pkt->size)
+		return 0;
+
+	list = &ep->inlist;
+
+	if (!async && list->count) {
+		halt_dma(ep->indma);
+		flush_pkt_list(list);
+	}
+
+	link_tail(ep, list, pkt);
+
+	vdbg("%s: ep%d, pkt=%p, size=%d, list count=%d", __FUNCTION__,
+	     ep->address, pkt, pkt->size, list->count);
+
+	if (list->count == 1) {
+		/*
+		 * if the packet count is one, it means the list was empty,
+		 * and no more data will go out this ep until we kick-start
+		 * it again.
+		 */
+		kickstart_send_packet(ep);
+	}
+
+	return pkt->size;
+}
+
+/*
+ * This routine is called to restart reception of a packet.
+ * EP spinlock must be held when calling.
+ */
+static void
+kickstart_receive_packet(endpoint_t * ep)
+{
+	usbdev_pkt_t *pkt;
+
+	// get and link a new packet for next reception
+	if (!(pkt = add_packet(ep, &ep->outlist, ep->max_pkt_size))) {
+		err("%s: could not alloc new packet", __FUNCTION__);
+		return;
+	}
+
+	if (get_dma_active_buffer(ep->outdma) == 1) {
+		clear_dma_done1(ep->outdma);
+		set_dma_count1(ep->outdma, ep->max_pkt_size);
+		set_dma_count0(ep->outdma, 0);
+		set_dma_addr1(ep->outdma, virt_to_phys(pkt->payload));
+		enable_dma_buffer1(ep->outdma);	// reenable
+	} else {
+		clear_dma_done0(ep->outdma);
+		set_dma_count0(ep->outdma, ep->max_pkt_size);
+		set_dma_count1(ep->outdma, 0);
+		set_dma_addr0(ep->outdma, virt_to_phys(pkt->payload));
+		enable_dma_buffer0(ep->outdma);	// reenable
+	}
+	if (dma_halted(ep->outdma))
+		start_dma(ep->outdma);
+}
+
+
+/*
+ * This routine is called when a packet in the outlist has been
+ * completed (received) and we need to prepare for a new packet
+ * to be received. Halts DMA and computes the packet size from the
+ * remaining DMA counter. Then prepares a new packet for reception
+ * and restarts DMA. FIXME: what if another packet comes in
+ * on top of the completed packet? Counter would be wrong.
+ * EP spinlock must be held when calling.
+ */
+static usbdev_pkt_t *
+receive_packet_complete(endpoint_t * ep)
+{
+	usbdev_pkt_t *pkt = ep->outlist.tail;
+	u32 cs;
+
+	halt_dma(ep->outdma);
+
+	cs = au_readl(ep->reg->ctrl_stat);
+
+	if (!pkt)
+		return NULL;
+
+	pkt->size = ep->max_pkt_size - get_dma_residue(ep->outdma);
+	if (pkt->size)
+		dma_cache_inv((unsigned long)pkt->payload, pkt->size);
+	/*
+	 * need to pull out any remaining bytes in the FIFO.
+	 */
+	endpoint_fifo_read(ep);
+	/*
+	 * should be drained now, but flush anyway just in case.
+	 */
+	flush_read_fifo(ep);
+
+	pkt->status = (cs & USBDEV_CS_NAK) ? PKT_STATUS_NAK : PKT_STATUS_ACK;
+	if (ep->address == 0 && (cs & USBDEV_CS_SU))
+		pkt->status |= PKT_STATUS_SU;
+
+	vdbg("%s: ep%d, %s pkt=%p, size=%d", __FUNCTION__,
+	     ep->address, (pkt->status & PKT_STATUS_NAK) ?
+	     "NAK" : "ACK", pkt, pkt->size);
+
+	kickstart_receive_packet(ep);
+
+	return pkt;
+}
+
+
+/*
+ ****************************************************************************
+ * Here starts the standard device request handlers. They are
+ * all called by do_setup() via a table of function pointers.
+ ****************************************************************************
+ */
+
+static ep0_stage_t
+do_get_status(struct usb_dev* dev, struct usb_ctrlrequest* setup)
+{
+	switch (setup->bRequestType) {
+	case 0x80:	// Device
+		// FIXME: send device status
+		break;
+	case 0x81:	// Interface
+		// FIXME: send interface status
+		break;
+	case 0x82:	// End Point
+		// FIXME: send endpoint status
+		break;
+	default:
+		// Invalid Command
+		endpoint_stall(&dev->ep[0]); // Stall End Point 0
+		break;
+	}
+
+	return STATUS_STAGE;
+}
+
+static ep0_stage_t
+do_clear_feature(struct usb_dev* dev, struct usb_ctrlrequest* setup)
+{
+	switch (setup->bRequestType) {
+	case 0x00:	// Device
+		if ((le16_to_cpu(setup->wValue) & 0xff) == 1)
+			dev->remote_wakeup_en = 0;
+	else
+			endpoint_stall(&dev->ep[0]);
+		break;
+	case 0x02:	// End Point
+		if ((le16_to_cpu(setup->wValue) & 0xff) == 0) {
+			endpoint_t *ep =
+				epaddr_to_ep(dev,
+					     le16_to_cpu(setup->wIndex) & 0xff);
+
+			endpoint_unstall(ep);
+			endpoint_reset_datatoggle(ep);
+		} else
+			endpoint_stall(&dev->ep[0]);
+		break;
+	}
+
+	return SETUP_STAGE;
+}
+
+static ep0_stage_t
+do_reserved(struct usb_dev* dev, struct usb_ctrlrequest* setup)
+{
+	// Invalid request, stall End Point 0
+	endpoint_stall(&dev->ep[0]);
+	return SETUP_STAGE;
+}
+
+static ep0_stage_t
+do_set_feature(struct usb_dev* dev, struct usb_ctrlrequest* setup)
+{
+	switch (setup->bRequestType) {
+	case 0x00:	// Device
+		if ((le16_to_cpu(setup->wValue) & 0xff) == 1)
+			dev->remote_wakeup_en = 1;
+		else
+			endpoint_stall(&dev->ep[0]);
+		break;
+	case 0x02:	// End Point
+		if ((le16_to_cpu(setup->wValue) & 0xff) == 0) {
+			endpoint_t *ep =
+				epaddr_to_ep(dev,
+					     le16_to_cpu(setup->wIndex) & 0xff);
+
+			endpoint_stall(ep);
+		} else
+			endpoint_stall(&dev->ep[0]);
+		break;
+	}
+
+	return SETUP_STAGE;
+}
+
+static ep0_stage_t
+do_set_address(struct usb_dev* dev, struct usb_ctrlrequest* setup)
+{
+	int new_state = dev->state;
+	int new_addr = le16_to_cpu(setup->wValue);
+
+	dbg("%s: our address=%d", __FUNCTION__, new_addr);
+
+	if (new_addr > 127) {
+			// usb spec doesn't tell us what to do, so just go to
+			// default state
+		new_state = DEFAULT;
+		dev->address = 0;
+	} else if (dev->address != new_addr) {
+		dev->address = new_addr;
+		new_state = ADDRESS;
+	}
+
+	if (dev->state != new_state) {
+		dev->state = new_state;
+		/* inform function layer of usbdev state change */
+		dev->func_cb(CB_NEW_STATE, dev->state, dev->cb_data);
+	}
+
+	return SETUP_STAGE;
+}
+
+static ep0_stage_t
+do_get_descriptor(struct usb_dev* dev, struct usb_ctrlrequest* setup)
+{
+	int strnum, desc_len = le16_to_cpu(setup->wLength);
+
+		switch (le16_to_cpu(setup->wValue) >> 8) {
+		case USB_DT_DEVICE:
+			// send device descriptor!
+		desc_len = desc_len > dev->dev_desc->bLength ?
+			dev->dev_desc->bLength : desc_len;
+			dbg("sending device desc, size=%d", desc_len);
+		send_packet(dev, alloc_packet(&dev->ep[0], desc_len,
+					      dev->dev_desc), 0);
+			break;
+		case USB_DT_CONFIG:
+			// If the config descr index in low-byte of
+			// setup->wValue	is valid, send config descr,
+			// otherwise stall ep0.
+			if ((le16_to_cpu(setup->wValue) & 0xff) == 0) {
+				// send config descriptor!
+				if (desc_len <= USB_DT_CONFIG_SIZE) {
+					dbg("sending partial config desc, size=%d",
+					     desc_len);
+				send_packet(dev,
+					    alloc_packet(&dev->ep[0],
+							 desc_len,
+							 dev->conf_desc),
+					    0);
+				} else {
+				int len = le16_to_cpu(dev->conf_desc->wTotalLength);
+				dbg("sending whole config desc,"
+				    " size=%d, our size=%d", desc_len, len);
+				desc_len = desc_len > len ? len : desc_len;
+				send_packet(dev,
+					    alloc_packet(&dev->ep[0],
+							 desc_len,
+							 dev->full_conf_desc),
+					    0);
+				}
+			} else
+			endpoint_stall(&dev->ep[0]);
+			break;
+		case USB_DT_STRING:
+			// If the string descr index in low-byte of setup->wValue
+			// is valid, send string descr, otherwise stall ep0.
+			strnum = le16_to_cpu(setup->wValue) & 0xff;
+			if (strnum >= 0 && strnum < 6) {
+				struct usb_string_descriptor *desc =
+				dev->str_desc[strnum];
+				desc_len = desc_len > desc->bLength ?
+					desc->bLength : desc_len;
+				dbg("sending string desc %d", strnum);
+			send_packet(dev,
+				    alloc_packet(&dev->ep[0], desc_len,
+						 desc), 0);
+			} else
+			endpoint_stall(&dev->ep[0]);
+			break;
+	default:
+		// Invalid request
+		err("invalid get desc=%d, stalled",
+			    le16_to_cpu(setup->wValue) >> 8);
+		endpoint_stall(&dev->ep[0]);	// Stall endpoint 0
+			break;
+		}
+
+	return STATUS_STAGE;
+}
+
+static ep0_stage_t
+do_set_descriptor(struct usb_dev* dev, struct usb_ctrlrequest* setup)
+{
+	// TODO: implement
+	// there will be an OUT data stage (the descriptor to set)
+	return DATA_STAGE;
+}
+
+static ep0_stage_t
+do_get_configuration(struct usb_dev* dev, struct usb_ctrlrequest* setup)
+{
+	// send dev->configuration
+	dbg("sending config");
+	send_packet(dev, alloc_packet(&dev->ep[0], 1, &dev->configuration),
+		    0);
+	return STATUS_STAGE;
+}
+
+static ep0_stage_t
+do_set_configuration(struct usb_dev* dev, struct usb_ctrlrequest* setup)
+{
+	// set active config to low-byte of setup->wValue
+	dev->configuration = le16_to_cpu(setup->wValue) & 0xff;
+	dbg("set config, config=%d", dev->configuration);
+	if (!dev->configuration && dev->state > DEFAULT) {
+		dev->state = ADDRESS;
+		/* inform function layer of usbdev state change */
+		dev->func_cb(CB_NEW_STATE, dev->state, dev->cb_data);
+	} else if (dev->configuration == 1) {
+		dev->state = CONFIGURED;
+		/* inform function layer of usbdev state change */
+		dev->func_cb(CB_NEW_STATE, dev->state, dev->cb_data);
+	} else {
+		// FIXME: "respond with request error" - how?
+	}
+
+	return SETUP_STAGE;
+}
+
+static ep0_stage_t
+do_get_interface(struct usb_dev* dev, struct usb_ctrlrequest* setup)
+{
+		// interface must be zero.
+	if ((le16_to_cpu(setup->wIndex) & 0xff) || dev->state == ADDRESS) {
+			// FIXME: respond with "request error". how?
+	} else if (dev->state == CONFIGURED) {
+		// send dev->alternate_setting
+			dbg("sending alt setting");
+		send_packet(dev, alloc_packet(&dev->ep[0], 1,
+					      &dev->alternate_setting), 0);
+		}
+
+	return STATUS_STAGE;
+
+}
+
+static ep0_stage_t
+do_set_interface(struct usb_dev* dev, struct usb_ctrlrequest* setup)
+{
+	if (dev->state == ADDRESS) {
+			// FIXME: respond with "request error". how?
+	} else if (dev->state == CONFIGURED) {
+		dev->interface = le16_to_cpu(setup->wIndex) & 0xff;
+		dev->alternate_setting =
+			    le16_to_cpu(setup->wValue) & 0xff;
+			// interface and alternate_setting must be zero
+		if (dev->interface || dev->alternate_setting) {
+				// FIXME: respond with "request error". how?
+			}
+		}
+
+	return SETUP_STAGE;
+}
+
+static ep0_stage_t
+do_synch_frame(struct usb_dev* dev, struct usb_ctrlrequest* setup)
+{
+	// TODO
+	return SETUP_STAGE;
+}
+
+typedef ep0_stage_t (*req_method_t)(struct usb_dev* dev,
+				    struct usb_ctrlrequest* setup);
+
+
+/* Table of the standard device request handlers */
+static const req_method_t req_method[] = {
+	do_get_status,
+	do_clear_feature,
+	do_reserved,
+	do_set_feature,
+	do_reserved,
+	do_set_address,
+	do_get_descriptor,
+	do_set_descriptor,
+	do_get_configuration,
+	do_set_configuration,
+	do_get_interface,
+	do_set_interface,
+	do_synch_frame
+};
+
+
+// SETUP packet request dispatcher
+static void
+do_setup (struct usb_dev* dev, struct usb_ctrlrequest* setup)
+{
+	req_method_t m;
+
+	dbg("%s: req %d %s", __FUNCTION__, setup->bRequestType,
+	    get_std_req_name(setup->bRequestType));
+
+	if ((setup->bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD ||
+	    (setup->bRequestType & USB_RECIP_MASK) != USB_RECIP_DEVICE) {
+		err("%s: invalid requesttype 0x%02x", __FUNCTION__,
+		    setup->bRequestType);
+		return;
+		}
+
+	if ((setup->bRequestType & 0x80) == USB_DIR_OUT && setup->wLength)
+		dbg("%s: OUT phase! length=%d", __FUNCTION__, setup->wLength);
+
+	if (setup->bRequestType < sizeof(req_method)/sizeof(req_method_t))
+		m = req_method[setup->bRequestType];
+			else
+		m = do_reserved;
+
+	dev->ep0_stage = (*m)(dev, setup);
+}
+
+/*
+ * A SETUP, DATA0, or DATA1 packet has been received
+ * on the default control endpoint's fifo.
+ */
+static void
+process_ep0_receive (struct usb_dev* dev)
+{
+	endpoint_t *ep0 = &dev->ep[0];
+	usbdev_pkt_t *pkt;
+
+	spin_lock(&ep0->lock);
+
+		// complete packet and prepare a new packet
+	pkt = receive_packet_complete(ep0);
+	if (!pkt) {
+		// FIXME: should  put a warn/err here.
+		spin_unlock(&ep0->lock);
+			return;
+		}
+
+	// unlink immediately from endpoint.
+	unlink_head(&ep0->outlist);
+
+	// override current stage if h/w says it's a setup packet
+	if (pkt->status & PKT_STATUS_SU)
+		dev->ep0_stage = SETUP_STAGE;
+
+	switch (dev->ep0_stage) {
+	case SETUP_STAGE:
+		vdbg("SU bit is %s in setup stage",
+		     (pkt->status & PKT_STATUS_SU) ? "set" : "not set");
+
+			if (pkt->size == sizeof(struct usb_ctrlrequest)) {
+#ifdef VDEBUG
+			if (pkt->status & PKT_STATUS_ACK)
+				vdbg("received SETUP");
+				else
+				vdbg("received NAK SETUP");
+#endif
+			do_setup(dev, (struct usb_ctrlrequest*)pkt->payload);
+		} else
+			err("%s: wrong size SETUP received", __FUNCTION__);
+		break;
+	case DATA_STAGE:
+		/*
+		 * this setup has an OUT data stage. Of the standard
+		 * device requests, only set_descriptor has this stage,
+		 * so this packet is that descriptor. TODO: drop it for
+		 * now, set_descriptor not implemented.
+		 *
+		 * Need to place a byte in the write FIFO here, to prepare
+		 * to send a zero-length DATA ack packet to the host in the
+		 * STATUS stage.
+		 */
+		au_writel(0, ep0->reg->write_fifo);
+		dbg("received OUT stage DATAx on EP0, size=%d", pkt->size);
+		dev->ep0_stage = SETUP_STAGE;
+		break;
+	case STATUS_STAGE:
+		// this setup had an IN data stage, and host is ACK'ing
+		// the packet we sent during that stage.
+		if (pkt->size != 0)
+			warn("received non-zero ACK on EP0??");
+#ifdef VDEBUG
+		else
+			vdbg("received ACK on EP0");
+#endif
+		dev->ep0_stage = SETUP_STAGE;
+		break;
+		}
+
+	spin_unlock(&ep0->lock);
+		// we're done processing the packet, free it
+		kfree(pkt);
+}
+
+
+/*
+ * A DATA0/1 packet has been received on one of the OUT endpoints (4 or 5)
+ */
+static void
+process_ep_receive (struct usb_dev* dev, endpoint_t *ep)
+{
+	usbdev_pkt_t *pkt;
+
+		spin_lock(&ep->lock);
+	pkt = receive_packet_complete(ep);
+		spin_unlock(&ep->lock);
+
+	dev->func_cb(CB_PKT_COMPLETE, (unsigned long)pkt, dev->cb_data);
+}
+
+
+
+/* This ISR handles the receive complete and suspend events */
+static void
+req_sus_intr (int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct usb_dev *dev = (struct usb_dev *) dev_id;
+	u32 status;
+
+	status = au_readl(USBD_INTSTAT);
+	au_writel(status, USBD_INTSTAT);	// ack'em
+
+	if (status & (1<<0))
+		process_ep0_receive(dev);
+	if (status & (1<<4))
+		process_ep_receive(dev, &dev->ep[4]);
+	if (status & (1<<5))
+		process_ep_receive(dev, &dev->ep[5]);
+}
+
+
+/* This ISR handles the DMA done events on EP0 */
+static void
+dma_done_ep0_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct usb_dev *dev = (struct usb_dev *) dev_id;
+	usbdev_pkt_t* pkt;
+	endpoint_t *ep0 = &dev->ep[0];
+	u32 cs0, buff_done;
+
+	spin_lock(&ep0->lock);
+	cs0 = au_readl(ep0->reg->ctrl_stat);
+
+	// first check packet transmit done
+	if ((buff_done = get_dma_buffer_done(ep0->indma)) != 0) {
+		// transmitted a DATAx packet during DATA stage
+		// on control endpoint 0
+		// clear DMA done bit
+		if (buff_done & DMA_D0)
+			clear_dma_done0(ep0->indma);
+		if (buff_done & DMA_D1)
+			clear_dma_done1(ep0->indma);
+
+		pkt = send_packet_complete(ep0);
+		if (pkt)
+			kfree(pkt);
+	}
+
+	/*
+	 * Now check packet receive done. Shouldn't get these,
+	 * the receive packet complete intr should happen
+	 * before the DMA done intr occurs.
+	 */
+	if ((buff_done = get_dma_buffer_done(ep0->outdma)) != 0) {
+		// clear DMA done bit
+		if (buff_done & DMA_D0)
+			clear_dma_done0(ep0->outdma);
+		if (buff_done & DMA_D1)
+			clear_dma_done1(ep0->outdma);
+
+		//process_ep0_receive(dev);
+	}
+
+	spin_unlock(&ep0->lock);
+}
+
+/* This ISR handles the DMA done events on endpoints 2,3,4,5 */
+static void
+dma_done_ep_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct usb_dev *dev = (struct usb_dev *) dev_id;
+	int i;
+
+	for (i = 2; i < 6; i++) {
+	u32 buff_done;
+		usbdev_pkt_t* pkt;
+		endpoint_t *ep = &dev->ep[i];
+
+		if (!ep->active) continue;
+
+	spin_lock(&ep->lock);
+
+		if (ep->direction == USB_DIR_IN) {
+			buff_done = get_dma_buffer_done(ep->indma);
+			if (buff_done != 0) {
+				// transmitted a DATAx pkt on the IN ep
+		// clear DMA done bit
+		if (buff_done & DMA_D0)
+			clear_dma_done0(ep->indma);
+		if (buff_done & DMA_D1)
+			clear_dma_done1(ep->indma);
+
+				pkt = send_packet_complete(ep);
+
+				spin_unlock(&ep->lock);
+				dev->func_cb(CB_PKT_COMPLETE,
+					     (unsigned long)pkt,
+					     dev->cb_data);
+				spin_lock(&ep->lock);
+			}
+		} else {
+	/*
+			 * Check packet receive done (OUT ep). Shouldn't get
+			 * these, the rx packet complete intr should happen
+	 * before the DMA done intr occurs.
+	 */
+			buff_done = get_dma_buffer_done(ep->outdma);
+			if (buff_done != 0) {
+				// received a DATAx pkt on the OUT ep
+		// clear DMA done bit
+		if (buff_done & DMA_D0)
+			clear_dma_done0(ep->outdma);
+		if (buff_done & DMA_D1)
+			clear_dma_done1(ep->outdma);
+
+				//process_ep_receive(dev, ep);
+	}
+	}
+
+		spin_unlock(&ep->lock);
+	}
+}
+
+
+/***************************************************************************
+ * Here begins the external interface functions
+ ***************************************************************************
+ */
+
+/*
+ * allocate a new packet
+ */
+int
+usbdev_alloc_packet(int ep_addr, int data_size, usbdev_pkt_t** pkt)
+{
+	endpoint_t * ep = epaddr_to_ep(&usbdev, ep_addr);
+	usbdev_pkt_t* lpkt = NULL;
+
+	if (!ep || !ep->active || ep->address < 2)
+		return -ENODEV;
+	if (data_size > ep->max_pkt_size)
+		return -EINVAL;
+
+	lpkt = *pkt = alloc_packet(ep, data_size, NULL);
+	if (!lpkt)
+		return -ENOMEM;
+	return 0;
+}
+
+
+/*
+ * packet send
+ */
+int
+usbdev_send_packet(int ep_addr, usbdev_pkt_t * pkt)
+{
+	unsigned long flags;
+	int count;
+	endpoint_t * ep;
+
+	if (!pkt || !(ep = epaddr_to_ep(&usbdev, pkt->ep_addr)) ||
+	    !ep->active || ep->address < 2)
+		return -ENODEV;
+	if (ep->direction != USB_DIR_IN)
+		return -EINVAL;
+
+	spin_lock_irqsave(&ep->lock, flags);
+	count = send_packet(&usbdev, pkt, 1);
+	spin_unlock_irqrestore(&ep->lock, flags);
+
+	return count;
+}
+
+/*
+ * packet receive
+ */
+int
+usbdev_receive_packet(int ep_addr, usbdev_pkt_t** pkt)
+{
+	unsigned long flags;
+	usbdev_pkt_t* lpkt = NULL;
+	endpoint_t *ep = epaddr_to_ep(&usbdev, ep_addr);
+
+	if (!ep || !ep->active || ep->address < 2)
+		return -ENODEV;
+	if (ep->direction != USB_DIR_OUT)
+		return -EINVAL;
+
+	spin_lock_irqsave(&ep->lock, flags);
+	if (ep->outlist.count > 1)
+		lpkt = unlink_head(&ep->outlist);
+	spin_unlock_irqrestore(&ep->lock, flags);
+
+	if (!lpkt) {
+		/* no packet available */
+		*pkt = NULL;
+		return -ENODATA;
+	}
+
+	*pkt = lpkt;
+
+	return lpkt->size;
+}
+
+
+/*
+ * return total queued byte count on the endpoint.
+ */
+int
+usbdev_get_byte_count(int ep_addr)
+{
+        unsigned long flags;
+        pkt_list_t *list;
+        usbdev_pkt_t *scan;
+        int count = 0;
+	endpoint_t * ep = epaddr_to_ep(&usbdev, ep_addr);
+
+	if (!ep || !ep->active || ep->address < 2)
+		return -ENODEV;
+
+	if (ep->direction == USB_DIR_IN) {
+		list = &ep->inlist;
+
+		spin_lock_irqsave(&ep->lock, flags);
+		for (scan = list->head; scan; scan = scan->next)
+			count += scan->size;
+		spin_unlock_irqrestore(&ep->lock, flags);
+	} else {
+		list = &ep->outlist;
+
+		spin_lock_irqsave(&ep->lock, flags);
+		if (list->count > 1) {
+			for (scan = list->head; scan != list->tail;
+			     scan = scan->next)
+				count += scan->size;
+	}
+		spin_unlock_irqrestore(&ep->lock, flags);
+	}
+
+	return count;
+}
+
+
+void
+usbdev_exit(void)
+{
+	endpoint_t *ep;
+	int i;
+
+	au_writel(0, USBD_INTEN);	// disable usb dev ints
+	au_writel(0, USBD_ENABLE);	// disable usb dev
+
+	free_irq(AU1000_USB_DEV_REQ_INT, &usbdev);
+	free_irq(AU1000_USB_DEV_SUS_INT, &usbdev);
+
+	// free all control endpoint resources
+	ep = &usbdev.ep[0];
+	free_au1000_dma(ep->indma);
+	free_au1000_dma(ep->outdma);
+	endpoint_flush(ep);
+
+	// free ep resources
+	for (i = 2; i < 6; i++) {
+		ep = &usbdev.ep[i];
+		if (!ep->active) continue;
+
+		if (ep->direction == USB_DIR_IN) {
+			free_au1000_dma(ep->indma);
+		} else {
+		free_au1000_dma(ep->outdma);
+		}
+		endpoint_flush(ep);
+	}
+
+	if (usbdev.full_conf_desc)
+		kfree(usbdev.full_conf_desc);
+}
+
+int
+usbdev_init(struct usb_device_descriptor* dev_desc,
+	    struct usb_config_descriptor* config_desc,
+	    struct usb_interface_descriptor* if_desc,
+	    struct usb_endpoint_descriptor* ep_desc,
+	    struct usb_string_descriptor* str_desc[],
+	    void (*cb)(usbdev_cb_type_t, unsigned long, void *),
+	    void* cb_data)
+{
+	endpoint_t *ep0;
+	int i, ret=0;
+	u8* fcd;
+
+	if (dev_desc->bNumConfigurations > 1 ||
+	    config_desc->bNumInterfaces > 1 ||
+	    if_desc->bNumEndpoints > 4) {
+		err("Only one config, one i/f, and no more "
+		    "than 4 ep's allowed");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (!cb) {
+		err("Function-layer callback required");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (dev_desc->bMaxPacketSize0 != USBDEV_EP0_MAX_PACKET_SIZE) {
+		warn("EP0 Max Packet size must be %d",
+		     USBDEV_EP0_MAX_PACKET_SIZE);
+		dev_desc->bMaxPacketSize0 = USBDEV_EP0_MAX_PACKET_SIZE;
+	}
+
+	memset(&usbdev, 0, sizeof(struct usb_dev));
+
+	usbdev.state = DEFAULT;
+	usbdev.dev_desc = dev_desc;
+	usbdev.if_desc = if_desc;
+	usbdev.conf_desc = config_desc;
+	for (i=0; i<6; i++)
+		usbdev.str_desc[i] = str_desc[i];
+	usbdev.func_cb = cb;
+	usbdev.cb_data = cb_data;
+
+	/* Initialize default control endpoint */
+	ep0 = &usbdev.ep[0];
+	ep0->active = 1;
+	ep0->type = CONTROL_EP;
+	ep0->max_pkt_size = USBDEV_EP0_MAX_PACKET_SIZE;
+	spin_lock_init(&ep0->lock);
+	ep0->desc = NULL;	// ep0 has no descriptor
+	ep0->address = 0;
+	ep0->direction = 0;
+	ep0->reg = &ep_reg[0];
+
+	/* Initialize the other requested endpoints */
+	for (i = 0; i < if_desc->bNumEndpoints; i++) {
+		struct usb_endpoint_descriptor* epd = &ep_desc[i];
+	endpoint_t *ep;
+
+		if ((epd->bEndpointAddress & 0x80) == USB_DIR_IN) {
+			ep = &usbdev.ep[2];
+			ep->address = 2;
+			if (ep->active) {
+				ep = &usbdev.ep[3];
+				ep->address = 3;
+				if (ep->active) {
+					err("too many IN ep's requested");
+					ret = -ENODEV;
+					goto out;
+	}
+	}
+		} else {
+			ep = &usbdev.ep[4];
+			ep->address = 4;
+			if (ep->active) {
+				ep = &usbdev.ep[5];
+				ep->address = 5;
+				if (ep->active) {
+					err("too many OUT ep's requested");
+					ret = -ENODEV;
+					goto out;
+	}
+	}
+		}
+
+		ep->active = 1;
+		epd->bEndpointAddress &= ~0x0f;
+		epd->bEndpointAddress |= (u8)ep->address;
+		ep->direction = epd->bEndpointAddress & 0x80;
+		ep->type = epd->bmAttributes & 0x03;
+		ep->max_pkt_size = le16_to_cpu(epd->wMaxPacketSize);
+		spin_lock_init(&ep->lock);
+		ep->desc = epd;
+		ep->reg = &ep_reg[ep->address];
+		}
+
+	/*
+	 * initialize the full config descriptor
+	 */
+	usbdev.full_conf_desc = fcd = kmalloc(le16_to_cpu(config_desc->wTotalLength),
+					      ALLOC_FLAGS);
+	if (!fcd) {
+		err("failed to alloc full config descriptor");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	memcpy(fcd, config_desc, USB_DT_CONFIG_SIZE);
+	fcd += USB_DT_CONFIG_SIZE;
+	memcpy(fcd, if_desc, USB_DT_INTERFACE_SIZE);
+	fcd += USB_DT_INTERFACE_SIZE;
+	for (i = 0; i < if_desc->bNumEndpoints; i++) {
+		memcpy(fcd, &ep_desc[i], USB_DT_ENDPOINT_SIZE);
+		fcd += USB_DT_ENDPOINT_SIZE;
+	}
+
+	/* Now we're ready to enable the controller */
+	au_writel(0x0002, USBD_ENABLE);
+	udelay(100);
+	au_writel(0x0003, USBD_ENABLE);
+	udelay(100);
+
+	/* build and send config table based on ep descriptors */
+	for (i = 0; i < 6; i++) {
+		endpoint_t *ep;
+		if (i == 1)
+			continue; // skip dummy ep
+		ep = &usbdev.ep[i];
+		if (ep->active) {
+			au_writel((ep->address << 4) | 0x04, USBD_CONFIG);
+			au_writel(((ep->max_pkt_size & 0x380) >> 7) |
+				  (ep->direction >> 4) | (ep->type << 4),
+				  USBD_CONFIG);
+			au_writel((ep->max_pkt_size & 0x7f) << 1, USBD_CONFIG);
+			au_writel(0x00, USBD_CONFIG);
+			au_writel(ep->address, USBD_CONFIG);
+		} else {
+			u8 dir = (i==2 || i==3) ? DIR_IN : DIR_OUT;
+			au_writel((i << 4) | 0x04, USBD_CONFIG);
+			au_writel(((16 & 0x380) >> 7) | dir |
+				  (BULK_EP << 4), USBD_CONFIG);
+			au_writel((16 & 0x7f) << 1, USBD_CONFIG);
+			au_writel(0x00, USBD_CONFIG);
+			au_writel(i, USBD_CONFIG);
+		}
+	}
+
+	/*
+	 * Enable Receive FIFO Complete interrupts only. Transmit
+	 * complete is being handled by the DMA done interrupts.
+	 */
+	au_writel(0x31, USBD_INTEN);
+
+	/*
+	 * Controller is now enabled, request DMA and IRQ
+	 * resources.
+	 */
+
+	/* request the USB device transfer complete interrupt */
+	if (request_irq(AU1000_USB_DEV_REQ_INT, req_sus_intr, SA_INTERRUPT,
+			"USBdev req", &usbdev)) {
+		err("Can't get device request intr");
+		ret = -ENXIO;
+		goto out;
+	}
+	/* request the USB device suspend interrupt */
+	if (request_irq(AU1000_USB_DEV_SUS_INT, req_sus_intr, SA_INTERRUPT,
+			"USBdev sus", &usbdev)) {
+		err("Can't get device suspend intr");
+		ret = -ENXIO;
+		goto out;
+	}
+
+	/* Request EP0 DMA and IRQ */
+	if ((ep0->indma = request_au1000_dma(ep_dma_id[0].id,
+					     ep_dma_id[0].str,
+					     dma_done_ep0_intr,
+					     SA_INTERRUPT,
+					     &usbdev)) < 0) {
+		err("Can't get %s DMA", ep_dma_id[0].str);
+		ret = -ENXIO;
+		goto out;
+	}
+	if ((ep0->outdma = request_au1000_dma(ep_dma_id[1].id,
+					      ep_dma_id[1].str,
+					      NULL, 0, NULL)) < 0) {
+		err("Can't get %s DMA", ep_dma_id[1].str);
+		ret = -ENXIO;
+		goto out;
+	}
+
+	// Flush the ep0 buffers and FIFOs
+	endpoint_flush(ep0);
+	// start packet reception on ep0
+	kickstart_receive_packet(ep0);
+
+	/* Request DMA and IRQ for the other endpoints */
+	for (i = 2; i < 6; i++) {
+		endpoint_t *ep = &usbdev.ep[i];
+		if (!ep->active)
+			continue;
+
+		// Flush the endpoint buffers and FIFOs
+		endpoint_flush(ep);
+
+		if (ep->direction == USB_DIR_IN) {
+			ep->indma =
+				request_au1000_dma(ep_dma_id[ep->address].id,
+						   ep_dma_id[ep->address].str,
+						   dma_done_ep_intr,
+						   SA_INTERRUPT,
+						   &usbdev);
+			if (ep->indma < 0) {
+				err("Can't get %s DMA",
+				    ep_dma_id[ep->address].str);
+				ret = -ENXIO;
+				goto out;
+			}
+		} else {
+			ep->outdma =
+				request_au1000_dma(ep_dma_id[ep->address].id,
+						   ep_dma_id[ep->address].str,
+						   NULL, 0, NULL);
+			if (ep->outdma < 0) {
+				err("Can't get %s DMA",
+				    ep_dma_id[ep->address].str);
+				ret = -ENXIO;
+				goto out;
+			}
+
+			// start packet reception on OUT endpoint
+			kickstart_receive_packet(ep);
+		}
+	}
+
+ out:
+	if (ret)
+		usbdev_exit();
+	return ret;
+}
+
+EXPORT_SYMBOL(usbdev_init);
+EXPORT_SYMBOL(usbdev_exit);
+EXPORT_SYMBOL(usbdev_alloc_packet);
+EXPORT_SYMBOL(usbdev_receive_packet);
+EXPORT_SYMBOL(usbdev_send_packet);
+EXPORT_SYMBOL(usbdev_get_byte_count);
diff --git a/arch/mips/au1000/csb250/Makefile b/arch/mips/au1000/csb250/Makefile
new file mode 100644
index 0000000..c0c4dcd
--- /dev/null
+++ b/arch/mips/au1000/csb250/Makefile
@@ -0,0 +1,8 @@
+#
+#  Copyright 2002 Cogent Computer Systems
+#     	dan@embeddededge.com
+#
+# Makefile for the Cogent CSB250 Au1500 board.  Copied from Pb1500.
+#
+
+obj-y := init.o board_setup.o irqmap.o
diff --git a/arch/mips/au1000/csb250/board_setup.c b/arch/mips/au1000/csb250/board_setup.c
new file mode 100644
index 0000000..90426ea
--- /dev/null
+++ b/arch/mips/au1000/csb250/board_setup.c
@@ -0,0 +1,239 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Cogent CSB250 board setup.
+ *
+ * Copyright 2002 Cogent Computer Systems, Inc.
+ *	dan@embeddededge.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/mc146818rtc.h>
+#include <linux/delay.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/keyboard.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/au1000.h>
+#include <asm/csb250.h>
+
+extern int (*board_pci_idsel)(unsigned int devsel, int assert);
+int	csb250_pci_idsel(unsigned int devsel, int assert);
+
+void __init board_setup(void)
+{
+	u32 pin_func, pin_val;
+	u32 sys_freqctrl, sys_clksrc;
+
+
+	// set AUX clock to 12MHz * 8 = 96 MHz
+	au_writel(8, SYS_AUXPLL);
+	au_writel(0, SYS_PINSTATERD);
+	udelay(100);
+
+#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
+
+	/* GPIO201 is input for PCMCIA card detect */
+	/* GPIO203 is input for PCMCIA interrupt request */
+	au_writel(au_readl(GPIO2_DIR) & (u32)(~((1<<1)|(1<<3))), GPIO2_DIR);
+
+	/* zero and disable FREQ2 */
+	sys_freqctrl = au_readl(SYS_FREQCTRL0);
+	sys_freqctrl &= ~0xFFF00000;
+	au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+	/* zero and disable USBH/USBD clocks */
+	sys_clksrc = au_readl(SYS_CLKSRC);
+	sys_clksrc &= ~0x00007FE0;
+	au_writel(sys_clksrc, SYS_CLKSRC);
+
+	sys_freqctrl = au_readl(SYS_FREQCTRL0);
+	sys_freqctrl &= ~0xFFF00000;
+
+	sys_clksrc = au_readl(SYS_CLKSRC);
+	sys_clksrc &= ~0x00007FE0;
+
+	// FREQ2 = aux/2 = 48 MHz
+	sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
+	au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+	/*
+	 * Route 48MHz FREQ2 into USB Host and/or Device
+	 */
+#ifdef CONFIG_USB_OHCI
+	sys_clksrc |= ((4<<12) | (0<<11) | (0<<10));
+#endif
+#ifdef CONFIG_AU1X00_USB_DEVICE
+	sys_clksrc |= ((4<<7) | (0<<6) | (0<<5));
+#endif
+	au_writel(sys_clksrc, SYS_CLKSRC);
+
+
+	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
+#ifndef CONFIG_AU1X00_USB_DEVICE
+	// 2nd USB port is USB host
+	pin_func |= 0x8000;
+#endif
+	au_writel(pin_func, SYS_PINFUNC);
+#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
+
+	/* Configure GPIO2....it's used by PCI among other things.
+	*/
+
+	/* Make everything but GP200 (PCI RST) an input until we get
+	 * the pins set correctly.
+	 */
+	au_writel(0x00000001, GPIO2_DIR);
+
+	/* Set the pins used for output.
+	 * A zero bit will leave PCI reset, LEDs off, power up USB,
+	 * IDSEL disabled.
+	 */
+	pin_val = ((3 << 30) | (7 << 19) | (1 << 17) | (1 << 16));
+	au_writel(pin_val, GPIO2_OUTPUT);
+
+	/* Set the output direction.
+	*/
+	pin_val = ((3 << 14) | (7 << 3) | (1 << 1) | (1 << 0));
+	au_writel(pin_val, GPIO2_DIR);
+
+#ifdef CONFIG_PCI
+	/* Use FREQ1 for the PCI output clock.  We use the
+	 * CPU clock of 384 MHz divided by 12 to get 32 MHz PCI.
+	 * If Michael changes the CPU speed, we need to adjust
+	 * that here as well :-).
+	 */
+
+	/* zero and disable FREQ1
+	*/
+	sys_freqctrl = au_readl(SYS_FREQCTRL0);
+	sys_freqctrl &= ~0x000ffc00;
+	au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+	/* zero and disable PCI clock
+	*/
+	sys_clksrc = au_readl(SYS_CLKSRC);
+	sys_clksrc &= ~0x000f8000;
+	au_writel(sys_clksrc, SYS_CLKSRC);
+
+	/* Get current values (which really should match above).
+	*/
+	sys_freqctrl = au_readl(SYS_FREQCTRL0);
+	sys_freqctrl &= ~0x000ffc00;
+
+	sys_clksrc = au_readl(SYS_CLKSRC);
+	sys_clksrc &= ~0x000f8000;
+
+	/* FREQ1 = cpu/12 = 32 MHz
+	*/
+	sys_freqctrl |= ((5<<12) | (1<<11) | (0<<10));
+	au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+	/* Just connect the clock without further dividing.
+	*/
+	sys_clksrc |= ((3<<17) | (0<<16) | (0<<15));
+	au_writel(sys_clksrc, SYS_CLKSRC);
+
+	udelay(1);
+
+	/* Now that clocks should be running, take PCI out of reset.
+	*/
+	pin_val = au_readl(GPIO2_OUTPUT);
+	pin_val |= ((1 << 16) | 1);
+	au_writel(pin_val, GPIO2_OUTPUT);
+
+	// Setup PCI bus controller
+	au_writel(0, Au1500_PCI_CMEM);
+	au_writel(0x00003fff, Au1500_CFG_BASE);
+
+	/* We run big endian without any of the software byte swapping,
+	 * so configure the PCI bridge to help us out.
+	 */
+	au_writel(0xf | (2<<6) | (1<<5) | (1<<4), Au1500_PCI_CFG);
+
+	au_writel(0xf0000000, Au1500_PCI_MWMASK_DEV);
+	au_writel(0, Au1500_PCI_MWBASE_REV_CCL);
+	au_writel(0x02a00356, Au1500_PCI_STATCMD);
+	au_writel(0x00003c04, Au1500_PCI_HDRTYPE);	
+	au_writel(0x00000008, Au1500_PCI_MBAR);
+	au_sync();
+
+	board_pci_idsel = csb250_pci_idsel;
+#endif
+
+	/* Enable sys bus clock divider when IDLE state or no bus activity. */
+	au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);
+
+#ifdef CONFIG_RTC
+	// Enable the RTC if not already enabled
+	if (!(au_readl(0xac000028) & 0x20)) {
+		printk("enabling clock ...\n");
+		au_writel((au_readl(0xac000028) | 0x20), 0xac000028);
+	}
+	// Put the clock in BCD mode
+	if (readl(0xac00002C) & 0x4) { /* reg B */
+		au_writel(au_readl(0xac00002c) & ~0x4, 0xac00002c);
+		au_sync();
+	}
+#endif
+}
+
+/* The IDSEL is selected in the GPIO2 register.  We will make device
+ * 12 appear in slot 0 and device 13 appear in slot 1.
+ */
+int
+csb250_pci_idsel(unsigned int devsel, int assert)
+{
+	int		retval;
+	unsigned int	gpio2_pins;
+
+	retval = 1;
+	
+	/* First, disable both selects, then assert the one requested.
+	*/
+	au_writel(0xc000c000, GPIO2_OUTPUT);
+	au_sync();
+
+	if (assert) {
+		if (devsel == 12)
+			gpio2_pins = 0x40000000;
+		else if (devsel == 13)
+			gpio2_pins = 0x80000000;
+		else {
+			gpio2_pins = 0xc000c000;
+			retval = 0;
+		}
+		au_writel(gpio2_pins, GPIO2_OUTPUT);
+	}
+	au_sync();
+
+	return retval;
+}
diff --git a/arch/mips/au1000/csb250/init.c b/arch/mips/au1000/csb250/init.c
new file mode 100644
index 0000000..4320057
--- /dev/null
+++ b/arch/mips/au1000/csb250/init.c
@@ -0,0 +1,95 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Cogent CSB250 board setup
+ *
+ * Copyright 2002 Cogent Computer Systems, Inc.
+ * 	dan@embeddededge.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+extern void  __init prom_init_cmdline(void);
+extern char *prom_getenv(char *envname);
+
+/* When we get initrd working someday.........
+*/
+int	my_initrd_start, my_initrd_size;
+
+/* Start arguments and environment.
+*/
+static char	*csb_env[2];
+static char	*csb_arg[4];
+static char	*arg1 = "console=ttyS3,38400";
+static char	*arg2 = "root=/dev/nfs rw ip=any";
+static char	*env1 = "ethaddr=00:30:23:50:00:00";
+
+const char *get_system_type(void)
+{
+	return "Cogent CSB250";
+}
+
+int __init prom_init(int argc, char **argv, char **envp, int *prom_vec)
+{
+	unsigned char *memsize_str;
+	unsigned long memsize;
+
+	/* We use a0 and a1 to pass initrd start and size.
+	*/
+	if (((uint) argc > 0) && ((uint)argv > 0)) {
+		my_initrd_start = (uint)argc;
+		my_initrd_size = (uint)argv;
+	}
+
+	/* First argv is ignored.
+	*/
+	prom_argc = 3;
+	prom_argv = csb_arg;
+	prom_envp = csb_env;
+	csb_arg[1] = arg1;
+	csb_arg[2] = arg2;
+	csb_env[0] = env1;
+
+	mips_machgroup = MACH_GROUP_ALCHEMY;
+	mips_machtype = MACH_CSB250;  
+
+	prom_init_cmdline();
+	memsize_str = prom_getenv("memsize");
+	if (!memsize_str) {
+		memsize = 0x02000000;
+	} else {
+		memsize = simple_strtol(memsize_str, NULL, 0);
+	}
+	add_memory_region(0, memsize, BOOT_MEM_RAM);
+	return 0;
+}
diff --git a/arch/mips/au1000/csb250/irqmap.c b/arch/mips/au1000/csb250/irqmap.c
new file mode 100644
index 0000000..5cb1166
--- /dev/null
+++ b/arch/mips/au1000/csb250/irqmap.c
@@ -0,0 +1,60 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Au1xxx irq map table
+ *
+ * Copyright 2003 Embedded Edge, LLC
+ *		dan@embeddededge.com
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
+ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
+ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/au1000.h>
+
+au1xxx_irq_map_t au1xxx_irq_map[] = {
+
+	{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1500_GPIO_207, INTC_INT_LOW_LEVEL, 0 },
+};
+
+int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
diff --git a/arch/mips/au1000/db1x00/Makefile b/arch/mips/au1000/db1x00/Makefile
new file mode 100644
index 0000000..4c7d763
--- /dev/null
+++ b/arch/mips/au1000/db1x00/Makefile
@@ -0,0 +1,9 @@
+#
+#  Copyright 2000 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc.
+#     	ppopov@mvista.com or source@mvista.com
+#
+# Makefile for the Alchemy Semiconductor Db1x00 board.
+
+lib-y := init.o board_setup.o irqmap.o
+obj-$(CONFIG_WM97XX_COMODULE) += mirage_ts.o
diff --git a/arch/mips/au1000/db1x00/board_setup.c b/arch/mips/au1000/db1x00/board_setup.c
new file mode 100644
index 0000000..ac05ba0
--- /dev/null
+++ b/arch/mips/au1000/db1x00/board_setup.c
@@ -0,0 +1,127 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Alchemy Db1x00 board setup.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/mc146818rtc.h>
+#include <linux/delay.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-db1x00/db1x00.h>
+
+/* not correct for db1550 */
+static BCSR * const bcsr = (BCSR *)0xAE000000;
+
+void board_reset (void)
+{
+	/* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
+	au_writel(0x00000000, 0xAE00001C);
+}
+
+void __init board_setup(void)
+{
+	u32 pin_func;
+
+	pin_func = 0;
+	/* not valid for 1550 */
+#ifdef CONFIG_AU1X00_USB_DEVICE
+	// 2nd USB port is USB device
+	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
+	au_writel(pin_func, SYS_PINFUNC);
+#endif
+
+#if defined(CONFIG_IRDA) && (defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100))
+	/* set IRFIRSEL instead of GPIO15 */
+	pin_func = au_readl(SYS_PINFUNC) | (u32)((1<<8));
+	au_writel(pin_func, SYS_PINFUNC);
+	/* power off until the driver is in use */
+	bcsr->resets &= ~BCSR_RESETS_IRDA_MODE_MASK;
+	bcsr->resets |= BCSR_RESETS_IRDA_MODE_OFF;
+	au_sync();
+#endif
+	au_writel(0, 0xAE000010); /* turn off pcmcia power */
+
+#ifdef CONFIG_MIPS_MIRAGE
+	/* enable GPIO[31:0] inputs */
+	au_writel(0, SYS_PININPUTEN);
+
+	/* GPIO[20] is output, tristate the other input primary GPIO's */
+	au_writel((u32)(~(1<<20)), SYS_TRIOUTCLR);
+
+	/* set GPIO[210:208] instead of SSI_0 */
+	pin_func = au_readl(SYS_PINFUNC) | (u32)(1);
+
+	/* set GPIO[215:211] for LED's */
+	pin_func |= (u32)((5<<2));
+
+	/* set GPIO[214:213] for more LED's */
+	pin_func |= (u32)((5<<12));
+
+	/* set GPIO[207:200] instead of PCMCIA/LCD */
+	pin_func |= (u32)((3<<17));
+	au_writel(pin_func, SYS_PINFUNC);
+
+	/* Enable speaker amplifier.  This should
+	 * be part of the audio driver.
+	 */
+	au_writel(au_readl(GPIO2_DIR) | 0x200, GPIO2_DIR);
+	au_writel(0x02000200, GPIO2_OUTPUT);
+#endif
+
+	au_sync();
+
+#ifdef CONFIG_MIPS_DB1000
+    printk("AMD Alchemy Au1000/Db1000 Board\n");
+#endif
+#ifdef CONFIG_MIPS_DB1500
+    printk("AMD Alchemy Au1500/Db1500 Board\n");
+#endif
+#ifdef CONFIG_MIPS_DB1100
+    printk("AMD Alchemy Au1100/Db1100 Board\n");
+#endif
+#ifdef CONFIG_MIPS_BOSPORUS
+    printk("AMD Alchemy Bosporus Board\n");
+#endif
+#ifdef CONFIG_MIPS_MIRAGE
+    printk("AMD Alchemy Mirage Board\n");
+#endif
+#ifdef CONFIG_MIPS_DB1550
+    printk("AMD Alchemy Au1550/Db1550 Board\n");
+#endif
+}
diff --git a/arch/mips/au1000/db1x00/init.c b/arch/mips/au1000/db1x00/init.c
new file mode 100644
index 0000000..51eee94
--- /dev/null
+++ b/arch/mips/au1000/db1x00/init.c
@@ -0,0 +1,74 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	PB1000 board setup
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <linux/config.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+extern void  __init prom_init_cmdline(void);
+extern char *prom_getenv(char *envname);
+
+const char *get_system_type(void)
+{
+#ifdef CONFIG_MIPS_BOSPORUS
+	return "Alchemy Bosporus Gateway Reference";
+#else
+	return "Alchemy Db1x00";
+#endif
+}
+
+void __init prom_init(void)
+{
+	unsigned char *memsize_str;
+	unsigned long memsize;
+
+	prom_argc = fw_arg0;
+	prom_argv = (char **) fw_arg1;
+	prom_envp = (char **) fw_arg2;
+
+	mips_machgroup = MACH_GROUP_ALCHEMY;
+	mips_machtype = MACH_DB1000;	/* set the platform # */   
+
+	prom_init_cmdline();
+
+	memsize_str = prom_getenv("memsize");
+	if (!memsize_str)
+		memsize = 0x04000000;
+	else
+		memsize = simple_strtol(memsize_str, NULL, 0);
+	add_memory_region(0, memsize, BOOT_MEM_RAM);
+}
diff --git a/arch/mips/au1000/db1x00/irqmap.c b/arch/mips/au1000/db1x00/irqmap.c
new file mode 100644
index 0000000..8f6ef0d
--- /dev/null
+++ b/arch/mips/au1000/db1x00/irqmap.c
@@ -0,0 +1,72 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Au1xxx irq map table
+ *
+ * Copyright 2003 Embedded Edge, LLC
+ *		dan@embeddededge.com
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
+ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
+ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/mach-au1x00/au1000.h>
+
+au1xxx_irq_map_t au1xxx_irq_map[] = {
+
+#ifndef CONFIG_MIPS_MIRAGE
+#ifdef CONFIG_MIPS_DB1550
+	{ AU1000_GPIO_3, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 0 IRQ# */
+	{ AU1000_GPIO_5, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 1 IRQ# */
+#else
+	{ AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 0 Fully_Interted# */
+	{ AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 0 STSCHG# */
+	{ AU1000_GPIO_2, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 0 IRQ# */
+
+	{ AU1000_GPIO_3, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 1 Fully_Interted# */
+	{ AU1000_GPIO_4, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 1 STSCHG# */
+	{ AU1000_GPIO_5, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 1 IRQ# */
+#endif
+#else
+	{ AU1000_GPIO_7, INTC_INT_RISE_EDGE, 0 }, /* touchscreen pen down */
+#endif
+
+};
+
+int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
diff --git a/arch/mips/au1000/db1x00/mirage_ts.c b/arch/mips/au1000/db1x00/mirage_ts.c
new file mode 100644
index 0000000..ade35e4
--- /dev/null
+++ b/arch/mips/au1000/db1x00/mirage_ts.c
@@ -0,0 +1,261 @@
+/*
+ * linux/arch/mips/au1000/db1x00/mirage_ts.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Glue between Mirage board-specific touchscreen pieces
+ *	and generic Wolfson Codec touchscreen support.
+ *
+ *	Based on pb1100_ts.c used in Hydrogen II.
+ *
+ * Copyright (c) 2003 Embedded Edge, LLC
+ *		dan@embeddededge.com
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
+ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
+ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/poll.h>
+#include <linux/proc_fs.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/wait.h>
+
+#include <asm/segment.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/delay.h>
+#include <asm/au1000.h>
+
+/*
+ *  Imported interface to Wolfson Codec driver.
+ */
+extern void *wm97xx_ts_get_handle(int which);
+extern int wm97xx_ts_ready(void* ts_handle);
+extern void wm97xx_ts_set_cal(void* ts_handle, int xscale, int xtrans, int yscale, int ytrans);
+extern u16 wm97xx_ts_get_ac97(void* ts_handle, u8 reg);
+extern void wm97xx_ts_set_ac97(void* ts_handle, u8 reg, u16 val);
+extern int wm97xx_ts_read_data(void* ts_handle, long* x, long* y, long* pressure);
+extern void wm97xx_ts_send_data(void* ts_handle, long x, long y, long z);
+
+int wm97xx_comodule_present = 1;
+
+
+#define TS_NAME "mirage_ts"
+
+#define err(format, arg...) printk(KERN_ERR TS_NAME ": " format "\n" , ## arg)
+#define info(format, arg...) printk(KERN_INFO TS_NAME ": " format "\n" , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING TS_NAME ": " format "\n" , ## arg)
+#define DPRINTK(format, arg...) printk("%s: " format "\n", __FUNCTION__ , ## arg)
+
+
+#define PEN_DOWN_IRQ	AU1000_GPIO_7
+
+static struct task_struct *ts_task = 0;
+static DECLARE_COMPLETION(ts_complete);
+static DECLARE_WAIT_QUEUE_HEAD(pendown_wait);
+
+#ifdef CONFIG_WM97XX_FIVEWIRETS
+static int release_pressure = 1;
+#else
+static int release_pressure = 50;
+#endif
+
+typedef struct {
+   long x;
+   long y;
+} DOWN_EVENT;
+
+#define SAMPLE_RATE	50	/* samples per second */
+#define PEN_DEBOUNCE	5	/* samples for settling - fn of SAMPLE_RATE */
+#define PEN_UP_TIMEOUT	10	/* in seconds */
+#define PEN_UP_SETTLE	5	/* samples per second */
+
+static struct {
+	int xscale;
+	int xtrans;
+	int yscale;
+	int ytrans;
+} mirage_ts_cal =
+{
+#if 0
+	xscale:   84,
+	xtrans: -157,
+	yscale:   66,
+	ytrans: -150,
+#else
+	xscale:   84,
+	xtrans: -150,
+	yscale:   66,
+	ytrans: -146,
+#endif
+};
+
+
+static void pendown_irq(int irqnr, void *devid, struct pt_regs *regs)
+{
+//DPRINTK("got one 0x%x", au_readl(SYS_PINSTATERD));
+	wake_up(&pendown_wait);
+}
+
+static int ts_thread(void *id)
+{
+	static int pen_was_down = 0;
+	static DOWN_EVENT pen_xy;
+	long x, y, z;
+	void *ts;	/* handle */
+	struct task_struct *tsk = current;
+	int timeout = HZ / SAMPLE_RATE;
+
+	ts_task = tsk;
+
+	daemonize();
+	tsk->tty = NULL;
+	tsk->policy = SCHED_FIFO;
+	tsk->rt_priority = 1;
+	strcpy(tsk->comm, "touchscreen");
+
+	/* only want to receive SIGKILL */
+	spin_lock_irq(&tsk->sigmask_lock);
+	siginitsetinv(&tsk->blocked, sigmask(SIGKILL));
+	recalc_sigpending(tsk);
+	spin_unlock_irq(&tsk->sigmask_lock);
+
+	/* get handle for codec */
+	ts = wm97xx_ts_get_handle(0);
+
+	/* proceed only after everybody is ready */
+	wait_event_timeout(pendown_wait, wm97xx_ts_ready(ts), HZ/4);
+
+	/* board-specific calibration */
+	wm97xx_ts_set_cal(ts,
+			mirage_ts_cal.xscale,
+			mirage_ts_cal.xtrans,
+			mirage_ts_cal.yscale,
+			mirage_ts_cal.ytrans);
+
+	/* route Wolfson pendown interrupts to our GPIO */
+	au_sync();
+	wm97xx_ts_set_ac97(ts, 0x4c, wm97xx_ts_get_ac97(ts, 0x4c) & ~0x0008);
+	au_sync();
+	wm97xx_ts_set_ac97(ts, 0x56, wm97xx_ts_get_ac97(ts, 0x56) & ~0x0008);
+	au_sync();
+	wm97xx_ts_set_ac97(ts, 0x52, wm97xx_ts_get_ac97(ts, 0x52) | 0x2008);
+	au_sync();
+
+	for (;;) {
+		interruptible_sleep_on_timeout(&pendown_wait, timeout);
+		disable_irq(PEN_DOWN_IRQ);
+		if (signal_pending(tsk)) {
+			break;
+		}
+
+		/* read codec */
+		if (!wm97xx_ts_read_data(ts, &x, &y, &z))
+			z = 0;	/* treat no-data and pen-up the same */
+
+		if (signal_pending(tsk)) {
+			break;
+		}
+
+		if (z >= release_pressure) {
+			y = ~y;	/* top to bottom */
+			if (pen_was_down > 1 /*&& pen_was_down < PEN_DEBOUNCE*/) {//THXXX
+				/* bounce ? */
+				x = pen_xy.x;
+				y = pen_xy.y;
+				--pen_was_down;
+			} else if (pen_was_down <= 1) {
+				pen_xy.x = x;
+				pen_xy.y = y;
+				if (pen_was_down)
+					wm97xx_ts_send_data(ts, x, y, z);
+				pen_was_down = PEN_DEBOUNCE;
+			}
+			//wm97xx_ts_send_data(ts, x, y, z);
+			timeout = HZ / SAMPLE_RATE;
+		} else {
+			if (pen_was_down) {
+				if (--pen_was_down)
+					z = release_pressure;
+				else //THXXX
+				wm97xx_ts_send_data(ts, pen_xy.x, pen_xy.y, z);
+			}
+			/* The pendown signal takes some time to settle after
+			 * reading the pen pressure so wait a little
+			 * before enabling the pen.
+			 */
+			if (! pen_was_down) {
+//				interruptible_sleep_on_timeout(&pendown_wait, HZ / PEN_UP_SETTLE);
+				timeout = HZ * PEN_UP_TIMEOUT;
+			}
+		}
+		enable_irq(PEN_DOWN_IRQ);
+	}
+	enable_irq(PEN_DOWN_IRQ);
+	ts_task = NULL;
+	complete(&ts_complete);
+	return 0;
+}
+
+static int __init ts_mirage_init(void)
+{
+	int ret;
+
+	/* pen down signal is connected to GPIO 7 */
+
+	ret = request_irq(PEN_DOWN_IRQ, pendown_irq, 0, "ts-pendown", NULL);
+	if (ret) {
+		err("unable to get pendown irq%d: [%d]", PEN_DOWN_IRQ, ret);
+		return ret;
+	}
+
+	lock_kernel();
+	ret = kernel_thread(ts_thread, NULL, CLONE_FS | CLONE_FILES);
+	if (ret < 0) {
+		unlock_kernel();
+		return ret;
+	}
+	unlock_kernel();
+
+	info("Mirage touchscreen IRQ initialized.");
+
+	return 0;
+}
+
+static void __exit ts_mirage_exit(void)
+{
+	if (ts_task) {
+		send_sig(SIGKILL, ts_task, 1);
+		wait_for_completion(&ts_complete);
+	}
+
+	free_irq(PEN_DOWN_IRQ, NULL);
+}
+
+module_init(ts_mirage_init);
+module_exit(ts_mirage_exit);
+
diff --git a/arch/mips/au1000/hydrogen3/Makefile b/arch/mips/au1000/hydrogen3/Makefile
new file mode 100644
index 0000000..974f792
--- /dev/null
+++ b/arch/mips/au1000/hydrogen3/Makefile
@@ -0,0 +1,9 @@
+#
+#  Copyright 2000 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc.
+#     	ppopov@mvista.com or source@mvista.com
+#
+# Makefile for the Alchemy Semiconductor PB1000 board.
+#
+
+obj-y := init.o board_setup.o irqmap.o
diff --git a/arch/mips/au1000/hydrogen3/board_setup.c b/arch/mips/au1000/hydrogen3/board_setup.c
new file mode 100644
index 0000000..2efae10
--- /dev/null
+++ b/arch/mips/au1000/hydrogen3/board_setup.c
@@ -0,0 +1,70 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Alchemy Db1x00 board setup.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/mc146818rtc.h>
+#include <linux/delay.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/keyboard.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/au1000.h>
+
+void board_reset (void)
+{
+}
+
+void __init board_setup(void)
+{
+	u32 pin_func;
+
+#ifdef CONFIG_AU1X00_USB_DEVICE
+	// 2nd USB port is USB device
+	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
+	au_writel(pin_func, SYS_PINFUNC);
+#endif
+
+#if defined(CONFIG_IRDA) && (defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100))
+	/* set IRFIRSEL instead of GPIO15 */
+	pin_func = au_readl(SYS_PINFUNC) | (u32)((1<<8));
+	au_writel(pin_func, SYS_PINFUNC);
+	au_sync();
+#endif
+
+    printk("AMD Alchemy Hydrogen3 Board\n");
+}
diff --git a/arch/mips/au1000/hydrogen3/init.c b/arch/mips/au1000/hydrogen3/init.c
new file mode 100644
index 0000000..eee4adf
--- /dev/null
+++ b/arch/mips/au1000/hydrogen3/init.c
@@ -0,0 +1,77 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	PB1000 board setup
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <linux/config.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+extern void  __init prom_init_cmdline(void);
+extern char *prom_getenv(char *envname);
+
+const char *get_system_type(void)
+{
+#ifdef CONFIG_MIPS_BOSPORUS
+	return "Alchemy Bosporus Gateway Reference";
+#else
+	return "Alchemy Db1x00";
+#endif
+}
+
+int __init prom_init(int argc, char **argv, char **envp, int *prom_vec)
+{
+	unsigned char *memsize_str;
+	unsigned long memsize;
+
+	prom_argc = argc;
+	prom_argv = argv;
+	prom_envp = envp;
+
+	mips_machgroup = MACH_GROUP_ALCHEMY;
+	mips_machtype = MACH_DB1000;	/* set the platform # */   
+	prom_init_cmdline();
+
+	memsize_str = prom_getenv("memsize");
+	if (!memsize_str) {
+		memsize = 0x04000000;
+	} else {
+		memsize = simple_strtol(memsize_str, NULL, 0);
+	}
+	add_memory_region(0, memsize, BOOT_MEM_RAM);
+	return 0;
+}
diff --git a/arch/mips/au1000/hydrogen3/irqmap.c b/arch/mips/au1000/hydrogen3/irqmap.c
new file mode 100644
index 0000000..6eacaa0
--- /dev/null
+++ b/arch/mips/au1000/hydrogen3/irqmap.c
@@ -0,0 +1,56 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Au1xxx irq map table
+ *
+ * Copyright 2003 Embedded Edge, LLC
+ *		dan@embeddededge.com
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
+ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
+ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/au1000.h>
+
+au1xxx_irq_map_t au1xxx_irq_map[] = {
+
+	/* { AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 }, */
+	{ AU1000_GPIO_21, INTC_INT_LOW_LEVEL, 0 },
+};
+
+int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
diff --git a/arch/mips/au1000/mtx-1/Makefile b/arch/mips/au1000/mtx-1/Makefile
new file mode 100644
index 0000000..764bf9f
--- /dev/null
+++ b/arch/mips/au1000/mtx-1/Makefile
@@ -0,0 +1,10 @@
+#
+#  Copyright 2003 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc.
+#     	ppopov@mvista.com or source@mvista.com
+#       Bruno Randolf <bruno.randolf@4g-systems.biz>
+#
+# Makefile for 4G Systems MTX-1 board.
+#
+
+lib-y := init.o board_setup.o irqmap.o
diff --git a/arch/mips/au1000/mtx-1/board_setup.c b/arch/mips/au1000/mtx-1/board_setup.c
new file mode 100644
index 0000000..638de7b
--- /dev/null
+++ b/arch/mips/au1000/mtx-1/board_setup.c
@@ -0,0 +1,89 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	4G Systems MTX-1 board setup.
+ *
+ * Copyright 2003 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *         Bruno Randolf <bruno.randolf@4g-systems.biz>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/mach-au1x00/au1000.h>
+
+void board_reset (void)
+{
+	/* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
+	au_writel(0x00000000, 0xAE00001C);
+}
+
+void __init board_setup(void)
+{
+#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
+#ifdef CONFIG_AU1X00_USB_DEVICE
+	// 2nd USB port is USB device
+	au_writel(au_readl(SYS_PINFUNC) & (u32)(~0x8000), SYS_PINFUNC);
+#endif
+	// enable USB power switch
+	au_writel( au_readl(GPIO2_DIR) | 0x10, GPIO2_DIR );
+	au_writel( 0x100000, GPIO2_OUTPUT );
+#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
+
+#ifdef CONFIG_PCI
+#if defined(__MIPSEB__)
+	au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG);
+#else
+	au_writel(0xf, Au1500_PCI_CFG);
+#endif
+#endif
+
+	// initialize sys_pinfunc:
+	// disable second ethernet port (SYS_PF_NI2)
+	// set U3/GPIO23 to GPIO23 (SYS_PF_U3)
+	au_writel( SYS_PF_NI2 | SYS_PF_U3, SYS_PINFUNC );
+
+	// initialize GPIO
+	au_writel( 0xFFFFFFFF, SYS_TRIOUTCLR );
+	au_writel( 0x00000001, SYS_OUTPUTCLR ); // set M66EN (PCI 66MHz) to OFF
+	au_writel( 0x00000008, SYS_OUTPUTSET ); // set PCI CLKRUN# to OFF
+	au_writel( 0x00000020, SYS_OUTPUTCLR ); // set eth PHY TX_ER to OFF
+
+	// enable LED and set it to green
+	au_writel( au_readl(GPIO2_DIR) | 0x1800, GPIO2_DIR );
+	au_writel( 0x18000800, GPIO2_OUTPUT );
+
+	printk("4G Systems MTX-1 Board\n");
+}
diff --git a/arch/mips/au1000/mtx-1/init.c b/arch/mips/au1000/mtx-1/init.c
new file mode 100644
index 0000000..02e7dbc
--- /dev/null
+++ b/arch/mips/au1000/mtx-1/init.c
@@ -0,0 +1,71 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	4G Systems MTX-1 board setup
+ *
+ * Copyright 2003 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *         Bruno Randolf <bruno.randolf@4g-systems.biz>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+extern void  __init prom_init_cmdline(void);
+extern char *prom_getenv(char *envname);
+
+const char *get_system_type(void)
+{
+	return "MTX-1";
+}
+
+void __init prom_init(void)
+{
+	unsigned char *memsize_str;
+	unsigned long memsize;
+
+	prom_argc = fw_arg0;
+	prom_argv = (char **) fw_arg1;
+	prom_envp = (char **) fw_arg2;
+
+	mips_machgroup = MACH_GROUP_ALCHEMY;
+	mips_machtype = MACH_MTX1;	/* set the platform # */
+
+	prom_init_cmdline();
+
+	memsize_str = prom_getenv("memsize");
+	if (!memsize_str)
+		memsize = 0x04000000;
+	else
+		memsize = simple_strtol(memsize_str, NULL, 0);
+	add_memory_region(0, memsize, BOOT_MEM_RAM);
+}
diff --git a/arch/mips/au1000/mtx-1/irqmap.c b/arch/mips/au1000/mtx-1/irqmap.c
new file mode 100644
index 0000000..ddcb9d0
--- /dev/null
+++ b/arch/mips/au1000/mtx-1/irqmap.c
@@ -0,0 +1,58 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Au1xxx irq map table
+ *
+ * Copyright 2003 Embedded Edge, LLC
+ *		dan@embeddededge.com
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
+ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
+ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/mach-au1x00/au1000.h>
+
+au1xxx_irq_map_t au1xxx_irq_map[] = {
+       { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
+       { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
+       { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
+       { AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 },
+       { AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 },
+};
+
+int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
diff --git a/arch/mips/au1000/pb1000/Makefile b/arch/mips/au1000/pb1000/Makefile
new file mode 100644
index 0000000..daa1a50
--- /dev/null
+++ b/arch/mips/au1000/pb1000/Makefile
@@ -0,0 +1,8 @@
+#
+#  Copyright 2000 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc.
+#     	ppopov@mvista.com or source@mvista.com
+#
+# Makefile for the Alchemy Semiconductor PB1000 board.
+
+lib-y := init.o board_setup.o irqmap.o
diff --git a/arch/mips/au1000/pb1000/board_setup.c b/arch/mips/au1000/pb1000/board_setup.c
new file mode 100644
index 0000000..2fa211b
--- /dev/null
+++ b/arch/mips/au1000/pb1000/board_setup.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-pb1x00/pb1000.h>
+
+void board_reset (void)
+{
+}
+
+void __init board_setup(void)
+{
+	u32 pin_func, static_cfg0;
+	u32 sys_freqctrl, sys_clksrc;
+	u32 prid = read_c0_prid();
+
+	// set AUX clock to 12MHz * 8 = 96 MHz
+	au_writel(8, SYS_AUXPLL);
+	au_writel(0, SYS_PINSTATERD);
+	udelay(100);
+
+#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
+	/* zero and disable FREQ2 */
+	sys_freqctrl = au_readl(SYS_FREQCTRL0);
+	sys_freqctrl &= ~0xFFF00000;
+	au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+	/* zero and disable USBH/USBD clocks */
+	sys_clksrc = au_readl(SYS_CLKSRC);
+	sys_clksrc &= ~0x00007FE0;
+	au_writel(sys_clksrc, SYS_CLKSRC);
+
+	sys_freqctrl = au_readl(SYS_FREQCTRL0);
+	sys_freqctrl &= ~0xFFF00000;
+
+	sys_clksrc = au_readl(SYS_CLKSRC);
+	sys_clksrc &= ~0x00007FE0;
+
+	switch (prid & 0x000000FF)
+	{
+	case 0x00: /* DA */
+	case 0x01: /* HA */
+	case 0x02: /* HB */
+	/* CPU core freq to 48MHz to slow it way down... */
+	au_writel(4, SYS_CPUPLL);
+
+	/*
+	 * Setup 48MHz FREQ2 from CPUPLL for USB Host
+	 */
+	/* FRDIV2=3 -> div by 8 of 384MHz -> 48MHz */
+	sys_freqctrl |= ((3<<22) | (1<<21) | (0<<20));
+	au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+	/* CPU core freq to 384MHz */
+	au_writel(0x20, SYS_CPUPLL);
+
+	printk("Au1000: 48MHz OHCI workaround enabled\n");
+		break;
+
+	default:  /* HC and newer */
+	// FREQ2 = aux/2 = 48 MHz
+	sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
+	au_writel(sys_freqctrl, SYS_FREQCTRL0);
+		break;
+	}
+
+	/*
+	 * Route 48MHz FREQ2 into USB Host and/or Device
+	 */
+#ifdef CONFIG_USB_OHCI
+	sys_clksrc |= ((4<<12) | (0<<11) | (0<<10));
+#endif
+#ifdef CONFIG_AU1X00_USB_DEVICE
+	sys_clksrc |= ((4<<7) | (0<<6) | (0<<5));
+#endif
+	au_writel(sys_clksrc, SYS_CLKSRC);
+
+	// configure pins GPIO[14:9] as GPIO
+	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8080);
+
+#ifndef CONFIG_AU1X00_USB_DEVICE
+	// 2nd USB port is USB host
+	pin_func |= 0x8000;
+#endif
+	au_writel(pin_func, SYS_PINFUNC);
+	au_writel(0x2800, SYS_TRIOUTCLR);
+	au_writel(0x0030, SYS_OUTPUTCLR);
+#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
+
+	// make gpio 15 an input (for interrupt line)
+	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x100);
+	// we don't need I2S, so make it available for GPIO[31:29]
+	pin_func |= (1<<5);
+	au_writel(pin_func, SYS_PINFUNC);
+
+	au_writel(0x8000, SYS_TRIOUTCLR);
+
+	static_cfg0 = au_readl(MEM_STCFG0) & (u32)(~0xc00);
+	au_writel(static_cfg0, MEM_STCFG0);
+
+	// configure RCE2* for LCD
+	au_writel(0x00000004, MEM_STCFG2);
+
+	// MEM_STTIME2
+	au_writel(0x09000000, MEM_STTIME2);
+
+	// Set 32-bit base address decoding for RCE2*
+	au_writel(0x10003ff0, MEM_STADDR2);
+
+	// PCI CPLD setup
+	// expand CE0 to cover PCI
+	au_writel(0x11803e40, MEM_STADDR1);
+
+	// burst visibility on
+	au_writel(au_readl(MEM_STCFG0) | 0x1000, MEM_STCFG0);
+
+	au_writel(0x83, MEM_STCFG1);         // ewait enabled, flash timing
+	au_writel(0x33030a10, MEM_STTIME1);   // slower timing for FPGA
+
+	/* setup the static bus controller */
+	au_writel(0x00000002, MEM_STCFG3);  /* type = PCMCIA */
+	au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */
+	au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */
+
+#ifdef CONFIG_PCI
+	au_writel(0, PCI_BRIDGE_CONFIG); // set extend byte to 0
+	au_writel(0, SDRAM_MBAR);        // set mbar to 0
+	au_writel(0x2, SDRAM_CMD);       // enable memory accesses
+	au_sync_delay(1);
+#endif
+
+	/* Enable Au1000 BCLK switching - note: sed1356 must not use
+	 * its BCLK (Au1000 LCLK) for any timings */
+	switch (prid & 0x000000FF)
+	{
+	case 0x00: /* DA */
+	case 0x01: /* HA */
+	case 0x02: /* HB */
+		break;
+	default:  /* HC and newer */
+		/* Enable sys bus clock divider when IDLE state or no bus 
+		   activity. */
+		au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);
+		break;
+	}
+}
diff --git a/arch/mips/au1000/pb1000/init.c b/arch/mips/au1000/pb1000/init.c
new file mode 100644
index 0000000..34713c5
--- /dev/null
+++ b/arch/mips/au1000/pb1000/init.c
@@ -0,0 +1,69 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	PB1000 board setup
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+extern void  __init prom_init_cmdline(void);
+extern char *prom_getenv(char *envname);
+
+const char *get_system_type(void)
+{
+	return "Alchemy Pb1000";
+}
+
+void __init prom_init(void)
+{
+	unsigned char *memsize_str;
+	unsigned long memsize;
+
+	prom_argc = (int) fw_arg0;
+	prom_argv = (char **) fw_arg1;
+	prom_envp = (char **) fw_arg2;
+
+	mips_machgroup = MACH_GROUP_ALCHEMY;
+	mips_machtype = MACH_PB1000;
+
+	prom_init_cmdline();
+	memsize_str = prom_getenv("memsize");
+	if (!memsize_str) {
+		memsize = 0x04000000;
+	} else {
+		memsize = simple_strtol(memsize_str, NULL, 0);
+	}
+	add_memory_region(0, memsize, BOOT_MEM_RAM);
+	return 0;
+}
diff --git a/arch/mips/au1000/pb1000/irqmap.c b/arch/mips/au1000/pb1000/irqmap.c
new file mode 100644
index 0000000..a3c460e
--- /dev/null
+++ b/arch/mips/au1000/pb1000/irqmap.c
@@ -0,0 +1,54 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Au1xxx irq map table
+ *
+ * Copyright 2003 Embedded Edge, LLC
+ *		dan@embeddededge.com
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
+ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
+ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/mach-au1x00/au1000.h>
+
+au1xxx_irq_map_t au1xxx_irq_map[] = {
+	{ AU1000_GPIO_15, INTC_INT_LOW_LEVEL, 0 },
+};
+
+int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
diff --git a/arch/mips/au1000/pb1100/Makefile b/arch/mips/au1000/pb1100/Makefile
new file mode 100644
index 0000000..996236d
--- /dev/null
+++ b/arch/mips/au1000/pb1100/Makefile
@@ -0,0 +1,8 @@
+#
+#  Copyright 2000,2001 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc.
+#     	ppopov@mvista.com or source@mvista.com
+#
+# Makefile for the Alchemy Semiconductor Pb1100 board.
+
+lib-y := init.o board_setup.o irqmap.o
diff --git a/arch/mips/au1000/pb1100/board_setup.c b/arch/mips/au1000/pb1100/board_setup.c
new file mode 100644
index 0000000..13c2f6c
--- /dev/null
+++ b/arch/mips/au1000/pb1100/board_setup.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2002 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-pb1x00/pb1100.h>
+
+void board_reset (void)
+{
+    /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
+    au_writel(0x00000000, 0xAE00001C);
+}
+
+void __init board_setup(void)
+{
+	u32 pin_func;
+	u32 sys_freqctrl, sys_clksrc;
+
+	// set AUX clock to 12MHz * 8 = 96 MHz
+	au_writel(8, SYS_AUXPLL);
+	au_writel(0, SYS_PININPUTEN);
+	udelay(100);
+
+#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
+	// configure pins GPIO[14:9] as GPIO
+	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x80);
+
+	/* zero and disable FREQ2 */
+	sys_freqctrl = au_readl(SYS_FREQCTRL0);
+	sys_freqctrl &= ~0xFFF00000;
+	au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+	/* zero and disable USBH/USBD/IrDA clock */
+	sys_clksrc = au_readl(SYS_CLKSRC);
+	sys_clksrc &= ~0x0000001F;
+	au_writel(sys_clksrc, SYS_CLKSRC);
+
+	sys_freqctrl = au_readl(SYS_FREQCTRL0);
+	sys_freqctrl &= ~0xFFF00000;
+
+	sys_clksrc = au_readl(SYS_CLKSRC);
+	sys_clksrc &= ~0x0000001F;
+
+	// FREQ2 = aux/2 = 48 MHz
+	sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
+	au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+	/*
+	 * Route 48MHz FREQ2 into USBH/USBD/IrDA
+	 */
+	sys_clksrc |= ((4<<2) | (0<<1) | 0 );
+	au_writel(sys_clksrc, SYS_CLKSRC);
+
+	/* setup the static bus controller */
+	au_writel(0x00000002, MEM_STCFG3);  /* type = PCMCIA */
+	au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */
+	au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */
+
+	// get USB Functionality pin state (device vs host drive pins)
+	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
+#ifndef CONFIG_AU1X00_USB_DEVICE
+	// 2nd USB port is USB host
+	pin_func |= 0x8000;
+#endif
+	au_writel(pin_func, SYS_PINFUNC);
+#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
+
+	/* Enable sys bus clock divider when IDLE state or no bus activity. */
+	au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);
+
+	// Enable the RTC if not already enabled
+	if (!(readb(0xac000028) & 0x20)) {
+		writeb(readb(0xac000028) | 0x20, 0xac000028);
+		au_sync();
+	}
+	// Put the clock in BCD mode
+	if (readb(0xac00002C) & 0x4) { /* reg B */
+		writeb(readb(0xac00002c) & ~0x4, 0xac00002c);
+		au_sync();
+	}
+}
diff --git a/arch/mips/au1000/pb1100/init.c b/arch/mips/au1000/pb1100/init.c
new file mode 100644
index 0000000..1fae39a
--- /dev/null
+++ b/arch/mips/au1000/pb1100/init.c
@@ -0,0 +1,70 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Pb1100 board setup
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+extern void  __init prom_init_cmdline(void);
+extern char *prom_getenv(char *envname);
+
+const char *get_system_type(void)
+{
+	return "Alchemy Pb1100";
+}
+
+void __init prom_init(void)
+{
+	unsigned char *memsize_str;
+	unsigned long memsize;
+
+	prom_argc = fw_arg0;
+	prom_argv = (char **) fw_arg1;
+	prom_envp = (int *) fw_arg3;
+
+	mips_machgroup = MACH_GROUP_ALCHEMY;
+	mips_machtype = MACH_PB1100;
+
+	prom_init_cmdline();
+
+	memsize_str = prom_getenv("memsize");
+	if (!memsize_str)
+		memsize = 0x04000000;
+	else
+		memsize = simple_strtol(memsize_str, NULL, 0);
+
+	add_memory_region(0, memsize, BOOT_MEM_RAM);
+}
diff --git a/arch/mips/au1000/pb1100/irqmap.c b/arch/mips/au1000/pb1100/irqmap.c
new file mode 100644
index 0000000..43be715
--- /dev/null
+++ b/arch/mips/au1000/pb1100/irqmap.c
@@ -0,0 +1,57 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Au1xxx irq map table
+ *
+ * Copyright 2003 Embedded Edge, LLC
+ *		dan@embeddededge.com
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
+ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
+ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/mach-au1x00/au1000.h>
+
+au1xxx_irq_map_t au1xxx_irq_map[] = {
+	{ AU1000_GPIO_9, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card Fully_Interted#
+	{ AU1000_GPIO_10, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card STSCHG#
+	{ AU1000_GPIO_11, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card IRQ#
+	{ AU1000_GPIO_13, INTC_INT_LOW_LEVEL, 0 }, // DC_IRQ#
+};
+
+int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
diff --git a/arch/mips/au1000/pb1500/Makefile b/arch/mips/au1000/pb1500/Makefile
new file mode 100644
index 0000000..97a7308
--- /dev/null
+++ b/arch/mips/au1000/pb1500/Makefile
@@ -0,0 +1,8 @@
+#
+#  Copyright 2000,2001 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc.
+#     	ppopov@mvista.com or source@mvista.com
+#
+# Makefile for the Alchemy Semiconductor Pb1500 board.
+
+lib-y := init.o board_setup.o irqmap.o
diff --git a/arch/mips/au1000/pb1500/board_setup.c b/arch/mips/au1000/pb1500/board_setup.c
new file mode 100644
index 0000000..30bb872
--- /dev/null
+++ b/arch/mips/au1000/pb1500/board_setup.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-pb1x00/pb1500.h>
+
+void board_reset (void)
+{
+    /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
+    au_writel(0x00000000, 0xAE00001C);
+}
+
+void __init board_setup(void)
+{
+	u32 pin_func;
+	u32 sys_freqctrl, sys_clksrc;
+
+	sys_clksrc = sys_freqctrl = pin_func = 0;
+	// set AUX clock to 12MHz * 8 = 96 MHz
+	au_writel(8, SYS_AUXPLL);
+	au_writel(0, SYS_PINSTATERD);
+	udelay(100);
+
+#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
+
+	/* GPIO201 is input for PCMCIA card detect */
+	/* GPIO203 is input for PCMCIA interrupt request */
+	au_writel(au_readl(GPIO2_DIR) & (u32)(~((1<<1)|(1<<3))), GPIO2_DIR);
+
+	/* zero and disable FREQ2 */
+	sys_freqctrl = au_readl(SYS_FREQCTRL0);
+	sys_freqctrl &= ~0xFFF00000;
+	au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+	/* zero and disable USBH/USBD clocks */
+	sys_clksrc = au_readl(SYS_CLKSRC);
+	sys_clksrc &= ~0x00007FE0;
+	au_writel(sys_clksrc, SYS_CLKSRC);
+
+	sys_freqctrl = au_readl(SYS_FREQCTRL0);
+	sys_freqctrl &= ~0xFFF00000;
+
+	sys_clksrc = au_readl(SYS_CLKSRC);
+	sys_clksrc &= ~0x00007FE0;
+
+	// FREQ2 = aux/2 = 48 MHz
+	sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
+	au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+	/*
+	 * Route 48MHz FREQ2 into USB Host and/or Device
+	 */
+#ifdef CONFIG_USB_OHCI
+	sys_clksrc |= ((4<<12) | (0<<11) | (0<<10));
+#endif
+#ifdef CONFIG_AU1X00_USB_DEVICE
+	sys_clksrc |= ((4<<7) | (0<<6) | (0<<5));
+#endif
+	au_writel(sys_clksrc, SYS_CLKSRC);
+
+
+	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
+#ifndef CONFIG_AU1X00_USB_DEVICE
+	// 2nd USB port is USB host
+	pin_func |= 0x8000;
+#endif
+	au_writel(pin_func, SYS_PINFUNC);
+#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
+
+
+
+#ifdef CONFIG_PCI
+	// Setup PCI bus controller
+	au_writel(0, Au1500_PCI_CMEM);
+	au_writel(0x00003fff, Au1500_CFG_BASE);
+#if defined(__MIPSEB__)
+	au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG);
+#else
+	au_writel(0xf, Au1500_PCI_CFG);
+#endif
+	au_writel(0xf0000000, Au1500_PCI_MWMASK_DEV);
+	au_writel(0, Au1500_PCI_MWBASE_REV_CCL);
+	au_writel(0x02a00356, Au1500_PCI_STATCMD);
+	au_writel(0x00003c04, Au1500_PCI_HDRTYPE);
+	au_writel(0x00000008, Au1500_PCI_MBAR);
+	au_sync();
+#endif
+
+	/* Enable sys bus clock divider when IDLE state or no bus activity. */
+	au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);
+
+	/* Enable the RTC if not already enabled */
+	if (!(au_readl(0xac000028) & 0x20)) {
+		printk("enabling clock ...\n");
+		au_writel((au_readl(0xac000028) | 0x20), 0xac000028);
+	}
+	/* Put the clock in BCD mode */
+	if (readl(0xac00002C) & 0x4) { /* reg B */
+		au_writel(au_readl(0xac00002c) & ~0x4, 0xac00002c);
+		au_sync();
+	}
+}
diff --git a/arch/mips/au1000/pb1500/init.c b/arch/mips/au1000/pb1500/init.c
new file mode 100644
index 0000000..733d2e4
--- /dev/null
+++ b/arch/mips/au1000/pb1500/init.c
@@ -0,0 +1,69 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	PB1500 board setup
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+extern void  __init prom_init_cmdline(void);
+extern char *prom_getenv(char *envname);
+
+const char *get_system_type(void)
+{
+	return "Alchemy Pb1500";
+}
+
+void __init prom_init(void)
+{
+	unsigned char *memsize_str;
+	unsigned long memsize;
+
+	prom_argc = (int) fw_arg0;
+	prom_argv = (char **) fw_arg1;
+	prom_envp = (char **) fw_arg2;
+
+	mips_machgroup = MACH_GROUP_ALCHEMY;
+	mips_machtype = MACH_PB1500;
+
+	prom_init_cmdline();
+	memsize_str = prom_getenv("memsize");
+	if (!memsize_str) {
+		memsize = 0x04000000;
+	} else {
+		memsize = simple_strtol(memsize_str, NULL, 0);
+	}
+	add_memory_region(0, memsize, BOOT_MEM_RAM);
+}
diff --git a/arch/mips/au1000/pb1500/irqmap.c b/arch/mips/au1000/pb1500/irqmap.c
new file mode 100644
index 0000000..476e250
--- /dev/null
+++ b/arch/mips/au1000/pb1500/irqmap.c
@@ -0,0 +1,58 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Au1xxx irq map table
+ *
+ * Copyright 2003 Embedded Edge, LLC
+ *		dan@embeddededge.com
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
+ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
+ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/mach-au1x00/au1000.h>
+
+au1xxx_irq_map_t au1xxx_irq_map[] = {
+	{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 },
+};
+
+int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
diff --git a/arch/mips/au1000/pb1550/Makefile b/arch/mips/au1000/pb1550/Makefile
new file mode 100644
index 0000000..aa35bc6
--- /dev/null
+++ b/arch/mips/au1000/pb1550/Makefile
@@ -0,0 +1,9 @@
+#
+#  Copyright 2000 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc.
+#     	ppopov@mvista.com or source@mvista.com
+#
+# Makefile for the Alchemy Semiconductor PB1000 board.
+#
+
+lib-y := init.o board_setup.o irqmap.o
diff --git a/arch/mips/au1000/pb1550/board_setup.c b/arch/mips/au1000/pb1550/board_setup.c
new file mode 100644
index 0000000..05fd27d
--- /dev/null
+++ b/arch/mips/au1000/pb1550/board_setup.c
@@ -0,0 +1,69 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Alchemy Pb1550 board setup.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/mc146818rtc.h>
+#include <linux/delay.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-pb1x00/pb1550.h>
+
+void board_reset (void)
+{
+    /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
+	au_writew(au_readw(0xAF00001C) & ~(1<<15), 0xAF00001C);
+}
+
+void __init board_setup(void)
+{
+	u32 pin_func;
+
+	/* Enable PSC1 SYNC for AC97.  Normaly done in audio driver,
+	 * but it is board specific code, so put it here.
+	 */
+	pin_func = au_readl(SYS_PINFUNC);
+	au_sync();
+	pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
+	au_writel(pin_func, SYS_PINFUNC);
+
+	au_writel(0, (u32)bcsr|0x10); /* turn off pcmcia power */
+	au_sync();
+
+	printk("AMD Alchemy Pb1550 Board\n");
+}
diff --git a/arch/mips/au1000/pb1550/init.c b/arch/mips/au1000/pb1550/init.c
new file mode 100644
index 0000000..41daa33
--- /dev/null
+++ b/arch/mips/au1000/pb1550/init.c
@@ -0,0 +1,69 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	PB1550 board setup
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+extern void  __init prom_init_cmdline(void);
+extern char *prom_getenv(char *envname);
+
+const char *get_system_type(void)
+{
+	return "Alchemy Pb1550";
+}
+
+void __init prom_init(void)
+{
+	unsigned char *memsize_str;
+	unsigned long memsize;
+
+	prom_argc = (int) fw_arg0;
+	prom_argv = (char **) fw_arg1;
+	prom_envp = (char **) fw_arg2;
+
+	mips_machgroup = MACH_GROUP_ALCHEMY;
+	mips_machtype = MACH_PB1550;
+
+	prom_init_cmdline();
+	memsize_str = prom_getenv("memsize");
+	if (!memsize_str) {
+		memsize = 0x08000000;
+	} else {
+		memsize = simple_strtol(memsize_str, NULL, 0);
+	}
+	add_memory_region(0, memsize, BOOT_MEM_RAM);
+}
diff --git a/arch/mips/au1000/pb1550/irqmap.c b/arch/mips/au1000/pb1550/irqmap.c
new file mode 100644
index 0000000..889d494
--- /dev/null
+++ b/arch/mips/au1000/pb1550/irqmap.c
@@ -0,0 +1,55 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Au1xxx irq map table
+ *
+ * Copyright 2003 Embedded Edge, LLC
+ *		dan@embeddededge.com
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
+ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
+ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/mach-au1x00/au1000.h>
+
+au1xxx_irq_map_t au1xxx_irq_map[] = {
+	{ AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 },
+};
+
+int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
diff --git a/arch/mips/au1000/xxs1500/Makefile b/arch/mips/au1000/xxs1500/Makefile
new file mode 100644
index 0000000..44d7f70
--- /dev/null
+++ b/arch/mips/au1000/xxs1500/Makefile
@@ -0,0 +1,9 @@
+#
+#  Copyright 2003 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc.
+#     	ppopov@mvista.com or source@mvista.com
+#
+# Makefile for MyCable XXS1500 board.
+#
+
+lib-y := init.o board_setup.o irqmap.o
diff --git a/arch/mips/au1000/xxs1500/board_setup.c b/arch/mips/au1000/xxs1500/board_setup.c
new file mode 100644
index 0000000..9dadc82
--- /dev/null
+++ b/arch/mips/au1000/xxs1500/board_setup.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2000-2003 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/keyboard.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/au1000.h>
+
+void board_reset (void)
+{
+	/* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
+	au_writel(0x00000000, 0xAE00001C);
+}
+
+void __init board_setup(void)
+{
+	u32 pin_func;
+	
+	// set multiple use pins (UART3/GPIO) to UART (it's used as UART too)
+	pin_func = au_readl(SYS_PINFUNC) & (u32)(~SYS_PF_UR3);
+	pin_func |= SYS_PF_UR3;
+	au_writel(pin_func, SYS_PINFUNC);
+
+	// enable UART
+	au_writel(0x01, UART3_ADDR+UART_MOD_CNTRL); // clock enable (CE)
+	mdelay(10);
+	au_writel(0x03, UART3_ADDR+UART_MOD_CNTRL); // CE and "enable"
+	mdelay(10);
+
+	// enable DTR = USB power up
+	au_writel(0x01, UART3_ADDR+UART_MCR); //? UART_MCR_DTR is 0x01???
+
+#ifdef CONFIG_PCMCIA_XXS1500
+	/* setup pcmcia signals */
+	au_writel(0, SYS_PININPUTEN);
+
+	/* gpio 0, 1, and 4 are inputs */
+	au_writel(1 | (1<<1) | (1<<4), SYS_TRIOUTCLR);
+
+	/* enable GPIO2 if not already enabled */
+	au_writel(1, GPIO2_ENABLE);
+	/* gpio2 208/9/10/11 are inputs */
+	au_writel((1<<8) | (1<<9) | (1<<10) | (1<<11), GPIO2_DIR);
+	
+	/* turn off power */
+	au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<14))|(1<<30), GPIO2_OUTPUT);
+#endif
+	
+
+#ifdef CONFIG_PCI
+#if defined(__MIPSEB__)
+	au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG);
+#else
+	au_writel(0xf, Au1500_PCI_CFG);
+#endif
+#endif
+}
diff --git a/arch/mips/au1000/xxs1500/init.c b/arch/mips/au1000/xxs1500/init.c
new file mode 100644
index 0000000..03f7552
--- /dev/null
+++ b/arch/mips/au1000/xxs1500/init.c
@@ -0,0 +1,68 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	XXS1500 board setup
+ *
+ * Copyright 2003 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+extern void  __init prom_init_cmdline(void);
+extern char *prom_getenv(char *envname);
+
+const char *get_system_type(void)
+{
+	return "XXS1500";
+}
+
+void __init prom_init(void)
+{
+	unsigned char *memsize_str;
+	unsigned long memsize;
+
+	prom_argc = fw_arg0;
+	prom_argv = (char **) fw_arg1;
+	prom_envp = (char **) fw_arg2;
+
+	mips_machgroup = MACH_GROUP_ALCHEMY;
+	mips_machtype = MACH_XXS1500;	/* set the platform # */   
+
+	prom_init_cmdline();
+
+	memsize_str = prom_getenv("memsize");
+	if (!memsize_str)
+		memsize = 0x04000000;
+	else
+		memsize = simple_strtol(memsize_str, NULL, 0);
+	add_memory_region(0, memsize, BOOT_MEM_RAM);
+}
diff --git a/arch/mips/au1000/xxs1500/irqmap.c b/arch/mips/au1000/xxs1500/irqmap.c
new file mode 100644
index 0000000..954800a
--- /dev/null
+++ b/arch/mips/au1000/xxs1500/irqmap.c
@@ -0,0 +1,66 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Au1xxx irq map table
+ *
+ * Copyright 2003 Embedded Edge, LLC
+ *		dan@embeddededge.com
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
+ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
+ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/au1000.h>
+
+au1xxx_irq_map_t au1xxx_irq_map[] = {
+	{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1500_GPIO_207, INTC_INT_LOW_LEVEL, 0 },
+
+	{ AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 }, 
+	{ AU1000_GPIO_2, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1000_GPIO_3, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1000_GPIO_4, INTC_INT_LOW_LEVEL, 0 }, /* CF interrupt */
+	{ AU1000_GPIO_5, INTC_INT_LOW_LEVEL, 0 },
+};
+
+int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile
new file mode 100644
index 0000000..efbeac3
--- /dev/null
+++ b/arch/mips/boot/Makefile
@@ -0,0 +1,49 @@
+#
+# 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, 1998, 2001, 2002 by Ralf Baechle
+# Copyright (C) 2004  Maciej W. Rozycki
+#
+
+#
+# Some DECstations need all possible sections of an ECOFF executable
+#
+ifdef CONFIG_MACH_DECSTATION
+  E2EFLAGS = -a
+else
+  E2EFLAGS =
+endif
+
+#
+# Drop some uninteresting sections in the kernel.
+# This is only relevant for ELF kernels but doesn't hurt a.out
+#
+drop-sections	= .reginfo .mdebug .comment .note .pdr .options .MIPS.options
+strip-flags	= $(addprefix --remove-section=,$(drop-sections))
+
+VMLINUX = vmlinux
+
+all: vmlinux.ecoff vmlinux.srec addinitrd
+
+vmlinux.ecoff: $(obj)/elf2ecoff $(VMLINUX)
+	$(obj)/elf2ecoff $(VMLINUX) vmlinux.ecoff $(E2EFLAGS)
+
+$(obj)/elf2ecoff: $(obj)/elf2ecoff.c
+	$(HOSTCC) -o $@ $^
+
+vmlinux.srec: $(VMLINUX)
+	$(OBJCOPY) -S -O srec $(strip-flags) $(VMLINUX) $(obj)/vmlinux.srec
+
+$(obj)/addinitrd: $(obj)/addinitrd.c
+	$(HOSTCC) -o $@ $^
+
+archhelp:
+	@echo	'* vmlinux.ecoff	- ECOFF boot image'
+	@echo	'* vmlinux.srec		- SREC boot image'
+
+clean-files += addinitrd \
+	       elf2ecoff \
+	       vmlinux.ecoff \
+	       vmlinux.srec
diff --git a/arch/mips/boot/addinitrd.c b/arch/mips/boot/addinitrd.c
new file mode 100644
index 0000000..8b30333
--- /dev/null
+++ b/arch/mips/boot/addinitrd.c
@@ -0,0 +1,131 @@
+/*
+ * addinitrd - program to add a initrd image to an ecoff kernel
+ *
+ * (C) 1999 Thomas Bogendoerfer
+ * minor modifications, cleanup: Guido Guenther <agx@sigxcpu.org>
+ * further cleanup: Maciej W. Rozycki
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <netinet/in.h>
+
+#include "ecoff.h"
+
+#define MIPS_PAGE_SIZE	4096
+#define MIPS_PAGE_MASK	(MIPS_PAGE_SIZE-1)
+
+#define swab16(x) \
+        ((unsigned short)( \
+                (((unsigned short)(x) & (unsigned short)0x00ffU) << 8) | \
+                (((unsigned short)(x) & (unsigned short)0xff00U) >> 8) ))
+
+#define swab32(x) \
+        ((unsigned int)( \
+                (((unsigned int)(x) & (unsigned int)0x000000ffUL) << 24) | \
+                (((unsigned int)(x) & (unsigned int)0x0000ff00UL) <<  8) | \
+                (((unsigned int)(x) & (unsigned int)0x00ff0000UL) >>  8) | \
+                (((unsigned int)(x) & (unsigned int)0xff000000UL) >> 24) ))
+
+#define SWAB(a)	(swab ? swab32(a) : (a))
+
+void die (char *s)
+{
+	perror (s);
+	exit (1);
+}
+
+int main (int argc, char *argv[])
+{
+	int fd_vmlinux,fd_initrd,fd_outfile;
+	FILHDR efile;
+	AOUTHDR eaout;
+	SCNHDR esecs[3];
+	struct stat st;
+	char buf[1024];
+	unsigned long loadaddr;
+	unsigned long initrd_header[2];
+	int i,cnt;
+	int swab = 0;
+
+	if (argc != 4) {
+		printf ("Usage: %s <vmlinux> <initrd> <outfile>\n",argv[0]);
+		exit (1);
+	}
+
+	if ((fd_vmlinux = open (argv[1],O_RDONLY)) < 0)
+		 die ("open vmlinux");
+	if (read (fd_vmlinux, &efile, sizeof efile) != sizeof efile)
+		die ("read file header");
+	if (read (fd_vmlinux, &eaout, sizeof eaout) != sizeof eaout)
+		die ("read aout header");
+	if (read (fd_vmlinux, esecs, sizeof esecs) != sizeof esecs)
+		die ("read section headers");
+	/*
+	 * check whether the file is good for us
+	 */
+	/* TBD */
+
+	/*
+	 * check, if we have to swab words
+	 */
+	if (ntohs(0xaa55) == 0xaa55) {
+		if (efile.f_magic == swab16(MIPSELMAGIC))
+			swab = 1;
+	} else {
+		if (efile.f_magic == swab16(MIPSEBMAGIC))
+			swab = 1;
+	}
+
+	/* make sure we have an empty data segment for the initrd */
+	if (eaout.dsize || esecs[1].s_size) {
+		fprintf (stderr, "Data segment not empty. Giving up!\n");
+		exit (1);
+	}
+	if ((fd_initrd = open (argv[2], O_RDONLY)) < 0)
+		die ("open initrd");
+	if (fstat (fd_initrd, &st) < 0)
+		die ("fstat initrd");
+	loadaddr = ((SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size)
+			+ MIPS_PAGE_SIZE-1) & ~MIPS_PAGE_MASK) - 8;
+	if (loadaddr < (SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size)))
+		loadaddr += MIPS_PAGE_SIZE;
+	initrd_header[0] = SWAB(0x494E5244);
+	initrd_header[1] = SWAB(st.st_size);
+	eaout.dsize = esecs[1].s_size = initrd_header[1] = SWAB(st.st_size+8);
+	eaout.data_start = esecs[1].s_vaddr = esecs[1].s_paddr = SWAB(loadaddr);
+
+	if ((fd_outfile = open (argv[3], O_RDWR|O_CREAT|O_TRUNC,0666)) < 0)
+		die ("open outfile");
+	if (write (fd_outfile, &efile, sizeof efile) != sizeof efile)
+		die ("write file header");
+	if (write (fd_outfile, &eaout, sizeof eaout) != sizeof eaout)
+		die ("write aout header");
+	if (write (fd_outfile, esecs, sizeof esecs) != sizeof esecs)
+		die ("write section headers");
+	/* skip padding */
+	if(lseek(fd_vmlinux, SWAB(esecs[0].s_scnptr), SEEK_SET) == (off_t)-1)
+		die ("lseek vmlinux");
+	if(lseek(fd_outfile, SWAB(esecs[0].s_scnptr), SEEK_SET) == (off_t)-1)
+		die ("lseek outfile");
+	/* copy text segment */
+	cnt = SWAB(eaout.tsize);
+	while (cnt) {
+		if ((i = read (fd_vmlinux, buf, sizeof buf)) <= 0)
+			die ("read vmlinux");
+		if (write (fd_outfile, buf, i) != i)
+			die ("write vmlinux");
+		cnt -= i;
+	}
+	if (write (fd_outfile, initrd_header, sizeof initrd_header) != sizeof initrd_header)
+		die ("write initrd header");
+	while ((i = read (fd_initrd, buf, sizeof buf)) > 0)
+		if (write (fd_outfile, buf, i) != i)
+			die ("write initrd");
+	close (fd_vmlinux);
+	close (fd_initrd);
+	return 0;
+}
diff --git a/arch/mips/boot/ecoff.h b/arch/mips/boot/ecoff.h
new file mode 100644
index 0000000..8c3eed2
--- /dev/null
+++ b/arch/mips/boot/ecoff.h
@@ -0,0 +1,62 @@
+/*
+ * Some ECOFF definitions.
+ */
+typedef struct filehdr {
+        unsigned short  f_magic;        /* magic number */
+        unsigned short  f_nscns;        /* number of sections */
+        long            f_timdat;       /* time & date stamp */
+        long            f_symptr;       /* file pointer to symbolic header */
+        long            f_nsyms;        /* sizeof(symbolic hdr) */
+        unsigned short  f_opthdr;       /* sizeof(optional hdr) */
+        unsigned short  f_flags;        /* flags */
+} FILHDR;
+#define FILHSZ  sizeof(FILHDR)
+
+#define OMAGIC		0407
+#define MIPSEBMAGIC	0x160
+#define MIPSELMAGIC	0x162
+
+typedef struct scnhdr {
+        char            s_name[8];      /* section name */
+        long            s_paddr;        /* physical address, aliased s_nlib */
+        long            s_vaddr;        /* virtual address */
+        long            s_size;         /* section size */
+        long            s_scnptr;       /* file ptr to raw data for section */
+        long            s_relptr;       /* file ptr to relocation */
+        long            s_lnnoptr;      /* file ptr to gp histogram */
+        unsigned short  s_nreloc;       /* number of relocation entries */
+        unsigned short  s_nlnno;        /* number of gp histogram entries */
+        long            s_flags;        /* flags */
+} SCNHDR;
+#define SCNHSZ		sizeof(SCNHDR)
+#define SCNROUND	((long)16)
+
+typedef struct aouthdr {
+        short   magic;          /* see above                            */
+        short   vstamp;         /* version stamp                        */
+        long    tsize;          /* text size in bytes, padded to DW bdry*/
+        long    dsize;          /* initialized data "  "                */
+        long    bsize;          /* uninitialized data "   "             */
+        long    entry;          /* entry pt.                            */
+        long    text_start;     /* base of text used for this file      */
+        long    data_start;     /* base of data used for this file      */
+        long    bss_start;      /* base of bss used for this file       */
+        long    gprmask;        /* general purpose register mask        */
+        long    cprmask[4];     /* co-processor register masks          */
+        long    gp_value;       /* the gp value used for this object    */
+} AOUTHDR;
+#define AOUTHSZ sizeof(AOUTHDR)
+
+#define OMAGIC		0407
+#define NMAGIC		0410
+#define ZMAGIC		0413
+#define SMAGIC		0411
+#define LIBMAGIC        0443
+
+#define N_TXTOFF(f, a) \
+ ((a).magic == ZMAGIC || (a).magic == LIBMAGIC ? 0 : \
+  ((a).vstamp < 23 ? \
+   ((FILHSZ + AOUTHSZ + (f).f_nscns * SCNHSZ + 7) & 0xfffffff8) : \
+   ((FILHSZ + AOUTHSZ + (f).f_nscns * SCNHSZ + SCNROUND-1) & ~(SCNROUND-1)) ) )
+#define N_DATOFF(f, a) \
+  N_TXTOFF(f, a) + (a).tsize;
diff --git a/arch/mips/boot/elf2ecoff.c b/arch/mips/boot/elf2ecoff.c
new file mode 100644
index 0000000..c3543d9
--- /dev/null
+++ b/arch/mips/boot/elf2ecoff.c
@@ -0,0 +1,616 @@
+/*
+ * Copyright (c) 1995
+ *	Ted Lemon (hereinafter referred to as the author)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* elf2ecoff.c
+
+   This program converts an elf executable to an ECOFF executable.
+   No symbol table is retained.   This is useful primarily in building
+   net-bootable kernels for machines (e.g., DECstation and Alpha) which
+   only support the ECOFF object file format. */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <elf.h>
+#include <limits.h>
+#include <netinet/in.h>
+#include <stdlib.h>
+
+#include "ecoff.h"
+
+/*
+ * Some extra ELF definitions
+ */
+#define PT_MIPS_REGINFO 0x70000000	/* Register usage information */
+
+/* -------------------------------------------------------------------- */
+
+struct sect {
+	unsigned long vaddr;
+	unsigned long len;
+};
+
+int *symTypeTable;
+int must_convert_endian = 0;
+int format_bigendian = 0;
+
+static void copy(int out, int in, off_t offset, off_t size)
+{
+	char ibuf[4096];
+	int remaining, cur, count;
+
+	/* Go to the start of the ELF symbol table... */
+	if (lseek(in, offset, SEEK_SET) < 0) {
+		perror("copy: lseek");
+		exit(1);
+	}
+
+	remaining = size;
+	while (remaining) {
+		cur = remaining;
+		if (cur > sizeof ibuf)
+			cur = sizeof ibuf;
+		remaining -= cur;
+		if ((count = read(in, ibuf, cur)) != cur) {
+			fprintf(stderr, "copy: read: %s\n",
+				count ? strerror(errno) :
+				"premature end of file");
+			exit(1);
+		}
+		if ((count = write(out, ibuf, cur)) != cur) {
+			perror("copy: write");
+			exit(1);
+		}
+	}
+}
+
+/*
+ * Combine two segments, which must be contiguous.   If pad is true, it's
+ * okay for there to be padding between.
+ */
+static void combine(struct sect *base, struct sect *new, int pad)
+{
+	if (!base->len)
+		*base = *new;
+	else if (new->len) {
+		if (base->vaddr + base->len != new->vaddr) {
+			if (pad)
+				base->len = new->vaddr - base->vaddr;
+			else {
+				fprintf(stderr,
+					"Non-contiguous data can't be converted.\n");
+				exit(1);
+			}
+		}
+		base->len += new->len;
+	}
+}
+
+static int phcmp(const void *v1, const void *v2)
+{
+	const Elf32_Phdr *h1 = v1;
+	const Elf32_Phdr *h2 = v2;
+
+	if (h1->p_vaddr > h2->p_vaddr)
+		return 1;
+	else if (h1->p_vaddr < h2->p_vaddr)
+		return -1;
+	else
+		return 0;
+}
+
+static char *saveRead(int file, off_t offset, off_t len, char *name)
+{
+	char *tmp;
+	int count;
+	off_t off;
+	if ((off = lseek(file, offset, SEEK_SET)) < 0) {
+		fprintf(stderr, "%s: fseek: %s\n", name, strerror(errno));
+		exit(1);
+	}
+	if (!(tmp = (char *) malloc(len))) {
+		fprintf(stderr, "%s: Can't allocate %ld bytes.\n", name,
+			len);
+		exit(1);
+	}
+	count = read(file, tmp, len);
+	if (count != len) {
+		fprintf(stderr, "%s: read: %s.\n",
+			name,
+			count ? strerror(errno) : "End of file reached");
+		exit(1);
+	}
+	return tmp;
+}
+
+#define swab16(x) \
+	((unsigned short)( \
+		(((unsigned short)(x) & (unsigned short)0x00ffU) << 8) | \
+		(((unsigned short)(x) & (unsigned short)0xff00U) >> 8) ))
+
+#define swab32(x) \
+	((unsigned int)( \
+		(((unsigned int)(x) & (unsigned int)0x000000ffUL) << 24) | \
+		(((unsigned int)(x) & (unsigned int)0x0000ff00UL) <<  8) | \
+		(((unsigned int)(x) & (unsigned int)0x00ff0000UL) >>  8) | \
+		(((unsigned int)(x) & (unsigned int)0xff000000UL) >> 24) ))
+
+static void convert_elf_hdr(Elf32_Ehdr * e)
+{
+	e->e_type = swab16(e->e_type);
+	e->e_machine = swab16(e->e_machine);
+	e->e_version = swab32(e->e_version);
+	e->e_entry = swab32(e->e_entry);
+	e->e_phoff = swab32(e->e_phoff);
+	e->e_shoff = swab32(e->e_shoff);
+	e->e_flags = swab32(e->e_flags);
+	e->e_ehsize = swab16(e->e_ehsize);
+	e->e_phentsize = swab16(e->e_phentsize);
+	e->e_phnum = swab16(e->e_phnum);
+	e->e_shentsize = swab16(e->e_shentsize);
+	e->e_shnum = swab16(e->e_shnum);
+	e->e_shstrndx = swab16(e->e_shstrndx);
+}
+
+static void convert_elf_phdrs(Elf32_Phdr * p, int num)
+{
+	int i;
+
+	for (i = 0; i < num; i++, p++) {
+		p->p_type = swab32(p->p_type);
+		p->p_offset = swab32(p->p_offset);
+		p->p_vaddr = swab32(p->p_vaddr);
+		p->p_paddr = swab32(p->p_paddr);
+		p->p_filesz = swab32(p->p_filesz);
+		p->p_memsz = swab32(p->p_memsz);
+		p->p_flags = swab32(p->p_flags);
+		p->p_align = swab32(p->p_align);
+	}
+
+}
+
+static void convert_elf_shdrs(Elf32_Shdr * s, int num)
+{
+	int i;
+
+	for (i = 0; i < num; i++, s++) {
+		s->sh_name = swab32(s->sh_name);
+		s->sh_type = swab32(s->sh_type);
+		s->sh_flags = swab32(s->sh_flags);
+		s->sh_addr = swab32(s->sh_addr);
+		s->sh_offset = swab32(s->sh_offset);
+		s->sh_size = swab32(s->sh_size);
+		s->sh_link = swab32(s->sh_link);
+		s->sh_info = swab32(s->sh_info);
+		s->sh_addralign = swab32(s->sh_addralign);
+		s->sh_entsize = swab32(s->sh_entsize);
+	}
+}
+
+static void convert_ecoff_filehdr(struct filehdr *f)
+{
+	f->f_magic = swab16(f->f_magic);
+	f->f_nscns = swab16(f->f_nscns);
+	f->f_timdat = swab32(f->f_timdat);
+	f->f_symptr = swab32(f->f_symptr);
+	f->f_nsyms = swab32(f->f_nsyms);
+	f->f_opthdr = swab16(f->f_opthdr);
+	f->f_flags = swab16(f->f_flags);
+}
+
+static void convert_ecoff_aouthdr(struct aouthdr *a)
+{
+	a->magic = swab16(a->magic);
+	a->vstamp = swab16(a->vstamp);
+	a->tsize = swab32(a->tsize);
+	a->dsize = swab32(a->dsize);
+	a->bsize = swab32(a->bsize);
+	a->entry = swab32(a->entry);
+	a->text_start = swab32(a->text_start);
+	a->data_start = swab32(a->data_start);
+	a->bss_start = swab32(a->bss_start);
+	a->gprmask = swab32(a->gprmask);
+	a->cprmask[0] = swab32(a->cprmask[0]);
+	a->cprmask[1] = swab32(a->cprmask[1]);
+	a->cprmask[2] = swab32(a->cprmask[2]);
+	a->cprmask[3] = swab32(a->cprmask[3]);
+	a->gp_value = swab32(a->gp_value);
+}
+
+static void convert_ecoff_esecs(struct scnhdr *s, int num)
+{
+	int i;
+
+	for (i = 0; i < num; i++, s++) {
+		s->s_paddr = swab32(s->s_paddr);
+		s->s_vaddr = swab32(s->s_vaddr);
+		s->s_size = swab32(s->s_size);
+		s->s_scnptr = swab32(s->s_scnptr);
+		s->s_relptr = swab32(s->s_relptr);
+		s->s_lnnoptr = swab32(s->s_lnnoptr);
+		s->s_nreloc = swab16(s->s_nreloc);
+		s->s_nlnno = swab16(s->s_nlnno);
+		s->s_flags = swab32(s->s_flags);
+	}
+}
+
+int main(int argc, char *argv[])
+{
+	Elf32_Ehdr ex;
+	Elf32_Phdr *ph;
+	Elf32_Shdr *sh;
+	char *shstrtab;
+	int i, pad;
+	struct sect text, data, bss;
+	struct filehdr efh;
+	struct aouthdr eah;
+	struct scnhdr esecs[6];
+	int infile, outfile;
+	unsigned long cur_vma = ULONG_MAX;
+	int addflag = 0;
+	int nosecs;
+
+	text.len = data.len = bss.len = 0;
+	text.vaddr = data.vaddr = bss.vaddr = 0;
+
+	/* Check args... */
+	if (argc < 3 || argc > 4) {
+	      usage:
+		fprintf(stderr,
+			"usage: elf2ecoff <elf executable> <ecoff executable> [-a]\n");
+		exit(1);
+	}
+	if (argc == 4) {
+		if (strcmp(argv[3], "-a"))
+			goto usage;
+		addflag = 1;
+	}
+
+	/* Try the input file... */
+	if ((infile = open(argv[1], O_RDONLY)) < 0) {
+		fprintf(stderr, "Can't open %s for read: %s\n",
+			argv[1], strerror(errno));
+		exit(1);
+	}
+
+	/* Read the header, which is at the beginning of the file... */
+	i = read(infile, &ex, sizeof ex);
+	if (i != sizeof ex) {
+		fprintf(stderr, "ex: %s: %s.\n",
+			argv[1],
+			i ? strerror(errno) : "End of file reached");
+		exit(1);
+	}
+
+	if (ex.e_ident[EI_DATA] == ELFDATA2MSB)
+		format_bigendian = 1;
+
+	if (ntohs(0xaa55) == 0xaa55) {
+		if (!format_bigendian)
+			must_convert_endian = 1;
+	} else {
+		if (format_bigendian)
+			must_convert_endian = 1;
+	}
+	if (must_convert_endian)
+		convert_elf_hdr(&ex);
+
+	/* Read the program headers... */
+	ph = (Elf32_Phdr *) saveRead(infile, ex.e_phoff,
+				     ex.e_phnum * sizeof(Elf32_Phdr),
+				     "ph");
+	if (must_convert_endian)
+		convert_elf_phdrs(ph, ex.e_phnum);
+	/* Read the section headers... */
+	sh = (Elf32_Shdr *) saveRead(infile, ex.e_shoff,
+				     ex.e_shnum * sizeof(Elf32_Shdr),
+				     "sh");
+	if (must_convert_endian)
+		convert_elf_shdrs(sh, ex.e_shnum);
+	/* Read in the section string table. */
+	shstrtab = saveRead(infile, sh[ex.e_shstrndx].sh_offset,
+			    sh[ex.e_shstrndx].sh_size, "shstrtab");
+
+	/* Figure out if we can cram the program header into an ECOFF
+	   header...  Basically, we can't handle anything but loadable
+	   segments, but we can ignore some kinds of segments.  We can't
+	   handle holes in the address space.  Segments may be out of order,
+	   so we sort them first. */
+
+	qsort(ph, ex.e_phnum, sizeof(Elf32_Phdr), phcmp);
+
+	for (i = 0; i < ex.e_phnum; i++) {
+		/* Section types we can ignore... */
+		if (ph[i].p_type == PT_NULL || ph[i].p_type == PT_NOTE ||
+		    ph[i].p_type == PT_PHDR
+		    || ph[i].p_type == PT_MIPS_REGINFO)
+			continue;
+		/* Section types we can't handle... */
+		else if (ph[i].p_type != PT_LOAD) {
+			fprintf(stderr,
+				"Program header %d type %d can't be converted.\n",
+				ex.e_phnum, ph[i].p_type);
+			exit(1);
+		}
+		/* Writable (data) segment? */
+		if (ph[i].p_flags & PF_W) {
+			struct sect ndata, nbss;
+
+			ndata.vaddr = ph[i].p_vaddr;
+			ndata.len = ph[i].p_filesz;
+			nbss.vaddr = ph[i].p_vaddr + ph[i].p_filesz;
+			nbss.len = ph[i].p_memsz - ph[i].p_filesz;
+
+			combine(&data, &ndata, 0);
+			combine(&bss, &nbss, 1);
+		} else {
+			struct sect ntxt;
+
+			ntxt.vaddr = ph[i].p_vaddr;
+			ntxt.len = ph[i].p_filesz;
+
+			combine(&text, &ntxt, 0);
+		}
+		/* Remember the lowest segment start address. */
+		if (ph[i].p_vaddr < cur_vma)
+			cur_vma = ph[i].p_vaddr;
+	}
+
+	/* Sections must be in order to be converted... */
+	if (text.vaddr > data.vaddr || data.vaddr > bss.vaddr ||
+	    text.vaddr + text.len > data.vaddr
+	    || data.vaddr + data.len > bss.vaddr) {
+		fprintf(stderr,
+			"Sections ordering prevents a.out conversion.\n");
+		exit(1);
+	}
+
+	/* If there's a data section but no text section, then the loader
+	   combined everything into one section.   That needs to be the
+	   text section, so just make the data section zero length following
+	   text. */
+	if (data.len && !text.len) {
+		text = data;
+		data.vaddr = text.vaddr + text.len;
+		data.len = 0;
+	}
+
+	/* If there is a gap between text and data, we'll fill it when we copy
+	   the data, so update the length of the text segment as represented in
+	   a.out to reflect that, since a.out doesn't allow gaps in the program
+	   address space. */
+	if (text.vaddr + text.len < data.vaddr)
+		text.len = data.vaddr - text.vaddr;
+
+	/* We now have enough information to cons up an a.out header... */
+	eah.magic = OMAGIC;
+	eah.vstamp = 200;
+	eah.tsize = text.len;
+	eah.dsize = data.len;
+	eah.bsize = bss.len;
+	eah.entry = ex.e_entry;
+	eah.text_start = text.vaddr;
+	eah.data_start = data.vaddr;
+	eah.bss_start = bss.vaddr;
+	eah.gprmask = 0xf3fffffe;
+	memset(&eah.cprmask, '\0', sizeof eah.cprmask);
+	eah.gp_value = 0;	/* unused. */
+
+	if (format_bigendian)
+		efh.f_magic = MIPSEBMAGIC;
+	else
+		efh.f_magic = MIPSELMAGIC;
+	if (addflag)
+		nosecs = 6;
+	else
+		nosecs = 3;
+	efh.f_nscns = nosecs;
+	efh.f_timdat = 0;	/* bogus */
+	efh.f_symptr = 0;
+	efh.f_nsyms = 0;
+	efh.f_opthdr = sizeof eah;
+	efh.f_flags = 0x100f;	/* Stripped, not sharable. */
+
+	memset(esecs, 0, sizeof esecs);
+	strcpy(esecs[0].s_name, ".text");
+	strcpy(esecs[1].s_name, ".data");
+	strcpy(esecs[2].s_name, ".bss");
+	if (addflag) {
+		strcpy(esecs[3].s_name, ".rdata");
+		strcpy(esecs[4].s_name, ".sdata");
+		strcpy(esecs[5].s_name, ".sbss");
+	}
+	esecs[0].s_paddr = esecs[0].s_vaddr = eah.text_start;
+	esecs[1].s_paddr = esecs[1].s_vaddr = eah.data_start;
+	esecs[2].s_paddr = esecs[2].s_vaddr = eah.bss_start;
+	if (addflag) {
+		esecs[3].s_paddr = esecs[3].s_vaddr = 0;
+		esecs[4].s_paddr = esecs[4].s_vaddr = 0;
+		esecs[5].s_paddr = esecs[5].s_vaddr = 0;
+	}
+	esecs[0].s_size = eah.tsize;
+	esecs[1].s_size = eah.dsize;
+	esecs[2].s_size = eah.bsize;
+	if (addflag) {
+		esecs[3].s_size = 0;
+		esecs[4].s_size = 0;
+		esecs[5].s_size = 0;
+	}
+	esecs[0].s_scnptr = N_TXTOFF(efh, eah);
+	esecs[1].s_scnptr = N_DATOFF(efh, eah);
+#define ECOFF_SEGMENT_ALIGNMENT(a) 0x10
+#define ECOFF_ROUND(s,a) (((s)+(a)-1)&~((a)-1))
+	esecs[2].s_scnptr = esecs[1].s_scnptr +
+	    ECOFF_ROUND(esecs[1].s_size, ECOFF_SEGMENT_ALIGNMENT(&eah));
+	if (addflag) {
+		esecs[3].s_scnptr = 0;
+		esecs[4].s_scnptr = 0;
+		esecs[5].s_scnptr = 0;
+	}
+	esecs[0].s_relptr = esecs[1].s_relptr = esecs[2].s_relptr = 0;
+	esecs[0].s_lnnoptr = esecs[1].s_lnnoptr = esecs[2].s_lnnoptr = 0;
+	esecs[0].s_nreloc = esecs[1].s_nreloc = esecs[2].s_nreloc = 0;
+	esecs[0].s_nlnno = esecs[1].s_nlnno = esecs[2].s_nlnno = 0;
+	if (addflag) {
+		esecs[3].s_relptr = esecs[4].s_relptr
+		    = esecs[5].s_relptr = 0;
+		esecs[3].s_lnnoptr = esecs[4].s_lnnoptr
+		    = esecs[5].s_lnnoptr = 0;
+		esecs[3].s_nreloc = esecs[4].s_nreloc = esecs[5].s_nreloc =
+		    0;
+		esecs[3].s_nlnno = esecs[4].s_nlnno = esecs[5].s_nlnno = 0;
+	}
+	esecs[0].s_flags = 0x20;
+	esecs[1].s_flags = 0x40;
+	esecs[2].s_flags = 0x82;
+	if (addflag) {
+		esecs[3].s_flags = 0x100;
+		esecs[4].s_flags = 0x200;
+		esecs[5].s_flags = 0x400;
+	}
+
+	/* Make the output file... */
+	if ((outfile = open(argv[2], O_WRONLY | O_CREAT, 0777)) < 0) {
+		fprintf(stderr, "Unable to create %s: %s\n", argv[2],
+			strerror(errno));
+		exit(1);
+	}
+
+	if (must_convert_endian)
+		convert_ecoff_filehdr(&efh);
+	/* Write the headers... */
+	i = write(outfile, &efh, sizeof efh);
+	if (i != sizeof efh) {
+		perror("efh: write");
+		exit(1);
+
+		for (i = 0; i < nosecs; i++) {
+			printf
+			    ("Section %d: %s phys %lx  size %lx  file offset %lx\n",
+			     i, esecs[i].s_name, esecs[i].s_paddr,
+			     esecs[i].s_size, esecs[i].s_scnptr);
+		}
+	}
+	fprintf(stderr, "wrote %d byte file header.\n", i);
+
+	if (must_convert_endian)
+		convert_ecoff_aouthdr(&eah);
+	i = write(outfile, &eah, sizeof eah);
+	if (i != sizeof eah) {
+		perror("eah: write");
+		exit(1);
+	}
+	fprintf(stderr, "wrote %d byte a.out header.\n", i);
+
+	if (must_convert_endian)
+		convert_ecoff_esecs(&esecs[0], nosecs);
+	i = write(outfile, &esecs, nosecs * sizeof(struct scnhdr));
+	if (i != nosecs * sizeof(struct scnhdr)) {
+		perror("esecs: write");
+		exit(1);
+	}
+	fprintf(stderr, "wrote %d bytes of section headers.\n", i);
+
+	pad = (sizeof(efh) + sizeof(eah) + nosecs * sizeof(struct scnhdr)) & 15;
+	if (pad) {
+		pad = 16 - pad;
+		i = write(outfile, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", pad);
+		if (i < 0) {
+			perror("ipad: write");
+			exit(1);
+		}
+		fprintf(stderr, "wrote %d byte pad.\n", i);
+	}
+
+	/*
+	 * Copy the loadable sections.   Zero-fill any gaps less than 64k;
+	 * complain about any zero-filling, and die if we're asked to zero-fill
+	 * more than 64k.
+	 */
+	for (i = 0; i < ex.e_phnum; i++) {
+		/* Unprocessable sections were handled above, so just verify that
+		   the section can be loaded before copying. */
+		if (ph[i].p_type == PT_LOAD && ph[i].p_filesz) {
+			if (cur_vma != ph[i].p_vaddr) {
+				unsigned long gap =
+				    ph[i].p_vaddr - cur_vma;
+				char obuf[1024];
+				if (gap > 65536) {
+					fprintf(stderr,
+						"Intersegment gap (%ld bytes) too large.\n",
+						gap);
+					exit(1);
+				}
+				fprintf(stderr,
+					"Warning: %ld byte intersegment gap.\n",
+					gap);
+				memset(obuf, 0, sizeof obuf);
+				while (gap) {
+					int count =
+					    write(outfile, obuf,
+						  (gap >
+						   sizeof obuf ? sizeof
+						   obuf : gap));
+					if (count < 0) {
+						fprintf(stderr,
+							"Error writing gap: %s\n",
+							strerror(errno));
+						exit(1);
+					}
+					gap -= count;
+				}
+			}
+			fprintf(stderr, "writing %d bytes...\n",
+				ph[i].p_filesz);
+			copy(outfile, infile, ph[i].p_offset,
+			     ph[i].p_filesz);
+			cur_vma = ph[i].p_vaddr + ph[i].p_filesz;
+		}
+	}
+
+	/*
+	 * Write a page of padding for boot PROMS that read entire pages.
+	 * Without this, they may attempt to read past the end of the
+	 * data section, incur an error, and refuse to boot.
+	 */
+	{
+		char obuf[4096];
+		memset(obuf, 0, sizeof obuf);
+		if (write(outfile, obuf, sizeof(obuf)) != sizeof(obuf)) {
+			fprintf(stderr, "Error writing PROM padding: %s\n",
+				strerror(errno));
+			exit(1);
+		}
+	}
+
+	/* Looks like we won... */
+	exit(0);
+}
diff --git a/arch/mips/cobalt/Makefile b/arch/mips/cobalt/Makefile
new file mode 100644
index 0000000..a5e6554
--- /dev/null
+++ b/arch/mips/cobalt/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the Cobalt micro systems family specific parts of the kernel
+#
+
+obj-y	 := irq.o int-handler.o reset.o setup.o promcon.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/cobalt/int-handler.S b/arch/mips/cobalt/int-handler.S
new file mode 100644
index 0000000..1a21dec
--- /dev/null
+++ b/arch/mips/cobalt/int-handler.S
@@ -0,0 +1,25 @@
+/*
+ * 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, 1996, 1997, 2003 by Ralf Baechle
+ * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv)
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/cobalt/cobalt.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+		.text
+		.align	5
+		NESTED(cobalt_handle_int, PT_SIZE, sp)
+		SAVE_ALL
+		CLI
+
+		la	ra, ret_from_irq
+		move	a1, sp
+		j	cobalt_irq
+
+		END(cobalt_handle_int)
diff --git a/arch/mips/cobalt/irq.c b/arch/mips/cobalt/irq.c
new file mode 100644
index 0000000..6d2a815
--- /dev/null
+++ b/arch/mips/cobalt/irq.c
@@ -0,0 +1,102 @@
+/*
+ * IRQ vector handles
+ *
+ * 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, 1996, 1997, 2003 by Ralf Baechle
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/i8259.h>
+#include <asm/irq_cpu.h>
+#include <asm/gt64120.h>
+#include <asm/ptrace.h>
+
+#include <asm/cobalt/cobalt.h>
+
+extern void cobalt_handle_int(void);
+
+/*
+ * We have two types of interrupts that we handle, ones that come in through
+ * the CPU interrupt lines, and ones that come in on the via chip. The CPU
+ * mappings are:
+ *
+ *    16,  - Software interrupt 0 (unused)	IE_SW0
+ *    17   - Software interrupt 1 (unused)	IE_SW0
+ *    18   - Galileo chip (timer)		IE_IRQ0
+ *    19   - Tulip 0 + NCR SCSI			IE_IRQ1
+ *    20   - Tulip 1				IE_IRQ2
+ *    21   - 16550 UART				IE_IRQ3
+ *    22   - VIA southbridge PIC		IE_IRQ4
+ *    23   - unused				IE_IRQ5
+ *
+ * The VIA chip is a master/slave 8259 setup and has the following interrupts:
+ *
+ *     8  - RTC
+ *     9  - PCI
+ *    14  - IDE0
+ *    15  - IDE1
+ */
+
+asmlinkage void cobalt_irq(struct pt_regs *regs)
+{
+	unsigned int pending = read_c0_status() & read_c0_cause();
+
+	if (pending & CAUSEF_IP2) {			/* int 18 */
+		unsigned long irq_src = GALILEO_INL(GT_INTRCAUSE_OFS);
+
+		/* Check for timer irq ... */
+		if (irq_src & GALILEO_T0EXP) {
+			/* Clear the int line */
+			GALILEO_OUTL(0, GT_INTRCAUSE_OFS);
+			do_IRQ(COBALT_TIMER_IRQ, regs);
+		}
+		return;
+	}
+
+	if (pending & CAUSEF_IP6) {			/* int 22 */
+		int irq = i8259_irq();
+
+		if (irq >= 0)
+			do_IRQ(irq, regs);
+		return;
+	}
+
+	if (pending & CAUSEF_IP3) {			/* int 19 */
+		do_IRQ(COBALT_ETH0_IRQ, regs);
+		return;
+	}
+
+	if (pending & CAUSEF_IP4) {			/* int 20 */
+		do_IRQ(COBALT_ETH1_IRQ, regs);
+		return;
+	}
+
+	if (pending & CAUSEF_IP5) {			/* int 21 */
+		do_IRQ(COBALT_SERIAL_IRQ, regs);
+		return;
+	}
+
+	if (pending & CAUSEF_IP7) {			/* int 23 */
+		do_IRQ(COBALT_QUBE_SLOT_IRQ, regs);
+		return;
+	}
+}
+
+void __init arch_init_irq(void)
+{
+	set_except_vector(0, cobalt_handle_int);
+
+	init_i8259_irqs();				/*  0 ... 15 */
+	mips_cpu_irq_init(16);				/* 16 ... 23 */
+
+	/*
+	 * Mask all cpu interrupts
+	 *  (except IE4, we already masked those at VIA level)
+	 */
+	change_c0_status(ST0_IM, IE_IRQ4);
+}
diff --git a/arch/mips/cobalt/promcon.c b/arch/mips/cobalt/promcon.c
new file mode 100644
index 0000000..f03df76
--- /dev/null
+++ b/arch/mips/cobalt/promcon.c
@@ -0,0 +1,87 @@
+/*
+ * PROM console for Cobalt Raq2
+ *
+ * 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, 1996, 1997 by Ralf Baechle
+ * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv)
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/kdev_t.h>
+#include <linux/serial_reg.h>
+
+#include <asm/delay.h>
+#include <asm/serial.h>
+#include <asm/io.h>
+
+static unsigned long port = 0xc800000;
+
+static __inline__ void ns16550_cons_put_char(char ch, unsigned long ioaddr)
+{
+	char lsr;
+
+	do {
+		lsr = inb(ioaddr + UART_LSR);
+	} while ((lsr & (UART_LSR_TEMT | UART_LSR_THRE)) != (UART_LSR_TEMT | UART_LSR_THRE));
+	outb(ch, ioaddr + UART_TX);
+}
+
+static __inline__ char ns16550_cons_get_char(unsigned long ioaddr)
+{
+	while ((inb(ioaddr + UART_LSR) & UART_LSR_DR) == 0)
+		udelay(1);
+	return inb(ioaddr + UART_RX);
+}
+
+void ns16550_console_write(struct console *co, const char *s, unsigned count)
+{
+	char lsr, ier;
+	unsigned i;
+
+	ier = inb(port + UART_IER);
+	outb(0x00, port + UART_IER);
+	for (i=0; i < count; i++, s++) {
+
+		if(*s == '\n')
+			ns16550_cons_put_char('\r', port);
+		ns16550_cons_put_char(*s, port);
+	}
+
+	do {
+		lsr = inb(port + UART_LSR);
+   	} while ((lsr & (UART_LSR_TEMT | UART_LSR_THRE)) != (UART_LSR_TEMT | UART_LSR_THRE));
+
+	outb(ier, port + UART_IER);
+}
+
+char getDebugChar(void)
+{
+	return ns16550_cons_get_char(port);
+}
+
+void putDebugChar(char kgdb_char)
+{
+	ns16550_cons_put_char(kgdb_char, port);
+}
+
+static struct console ns16550_console = {
+    .name	= "prom",
+    .setup	= NULL,
+    .write	= ns16550_console_write,
+    .flags	= CON_PRINTBUFFER,
+    .index	= -1,
+};
+
+static int __init ns16550_setup_console(void)
+{
+	register_console(&ns16550_console);
+
+	return 0;
+}
+
+console_initcall(ns16550_setup_console);
diff --git a/arch/mips/cobalt/reset.c b/arch/mips/cobalt/reset.c
new file mode 100644
index 0000000..084c8e5
--- /dev/null
+++ b/arch/mips/cobalt/reset.c
@@ -0,0 +1,68 @@
+/*
+ * Cobalt Reset operations
+ *
+ * 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, 1996, 1997 by Ralf Baechle
+ * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv)
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/cacheflush.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <asm/mipsregs.h>
+
+void cobalt_machine_restart(char *command)
+{
+	*(volatile char *)0xbc000000 = 0x0f;
+
+	/*
+	 * Ouch, we're still alive ... This time we take the silver bullet ...
+	 * ... and find that we leave the hardware in a state in which the
+	 * kernel in the flush locks up somewhen during of after the PCI
+	 * detection stuff.
+	 */
+	set_c0_status(ST0_BEV | ST0_ERL);
+	change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+	flush_cache_all();
+	write_c0_wired(0);
+	__asm__ __volatile__(
+		"jr\t%0"
+		:
+		: "r" (0xbfc00000));
+}
+
+extern int led_state;
+#define kLED            0xBC000000
+#define LEDSet(x)       (*(volatile unsigned char *) kLED) = (( unsigned char)x)
+
+void cobalt_machine_halt(void)
+{
+	int mark;
+
+	/* Blink our cute? little LED (number 3)... */
+	while (1) {
+		led_state = led_state | ( 1 << 3 );
+		LEDSet(led_state);
+		mark = jiffies;
+		while (jiffies<(mark+HZ));
+		led_state = led_state & ~( 1 << 3 );
+		LEDSet(led_state);
+		mark = jiffies;
+		while (jiffies<(mark+HZ));
+	}
+}
+
+/*
+ * This triggers the luser mode device driver for the power switch ;-)
+ */
+void cobalt_machine_power_off(void)
+{
+	printk("You can switch the machine off now.\n");
+	cobalt_machine_halt();
+}
diff --git a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c
new file mode 100644
index 0000000..6b4737e
--- /dev/null
+++ b/arch/mips/cobalt/setup.c
@@ -0,0 +1,150 @@
+/*
+ * Setup pointers to hardware dependent routines.
+ *
+ * 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) 1996, 1997, 2004 by Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv)
+ *
+ */
+#include <linux/config.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/bootinfo.h>
+#include <asm/time.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/gt64120.h>
+
+#include <asm/cobalt/cobalt.h>
+
+extern void cobalt_machine_restart(char *command);
+extern void cobalt_machine_halt(void);
+extern void cobalt_machine_power_off(void);
+
+int cobalt_board_id;
+
+static char my_cmdline[CL_SIZE] = {
+ "console=ttyS0,115200 "
+#ifdef CONFIG_IP_PNP
+ "ip=on "
+#endif
+#ifdef CONFIG_ROOT_NFS
+ "root=/dev/nfs "
+#else
+ "root=/dev/hda1 "
+#endif
+ };
+
+const char *get_system_type(void)
+{
+	return "MIPS Cobalt";
+}
+
+static void __init cobalt_timer_setup(struct irqaction *irq)
+{
+	/* Load timer value for 150 Hz */
+	GALILEO_OUTL(500000, GT_TC0_OFS);
+
+	/* Register our timer interrupt */
+	setup_irq(COBALT_TIMER_IRQ, irq);
+
+	/* Enable timer ints */
+	GALILEO_OUTL((GALILEO_ENTC0 | GALILEO_SELTC0), GT_TC_CONTROL_OFS);
+	/* Unmask timer int */
+	GALILEO_OUTL(0x100, GT_INTRMASK_OFS);
+}
+
+extern struct pci_ops gt64111_pci_ops;
+
+static struct resource cobalt_mem_resource = {
+	"GT64111 PCI MEM", GT64111_IO_BASE, 0xffffffffUL, IORESOURCE_MEM
+};
+
+static struct resource cobalt_io_resource = {
+	"GT64111 IO MEM", 0x00001000UL, 0x0fffffffUL, IORESOURCE_IO
+};
+
+static struct resource cobalt_io_resources[] = {
+	{ "dma1", 0x00, 0x1f, IORESOURCE_BUSY },
+	{ "timer", 0x40, 0x5f, IORESOURCE_BUSY },
+	{ "keyboard", 0x60, 0x6f, IORESOURCE_BUSY },
+	{ "dma page reg", 0x80, 0x8f, IORESOURCE_BUSY },
+	{ "dma2", 0xc0, 0xdf, IORESOURCE_BUSY },
+};
+
+#define COBALT_IO_RESOURCES (sizeof(cobalt_io_resources)/sizeof(struct resource))
+
+static struct pci_controller cobalt_pci_controller = {
+	.pci_ops	= &gt64111_pci_ops,
+	.mem_resource	= &cobalt_mem_resource,
+	.mem_offset	= 0,
+	.io_resource	= &cobalt_io_resource,
+	.io_offset	= 0x00001000UL - GT64111_IO_BASE
+};
+
+static void __init cobalt_setup(void)
+{
+	unsigned int devfn = PCI_DEVFN(COBALT_PCICONF_VIA, 0);
+	int i;
+
+	_machine_restart = cobalt_machine_restart;
+	_machine_halt = cobalt_machine_halt;
+	_machine_power_off = cobalt_machine_power_off;
+
+	board_timer_setup = cobalt_timer_setup;
+
+        set_io_port_base(KSEG1ADDR(GT64111_IO_BASE));
+
+	/*
+	 * This is a prom style console. We just poke at the
+	 *  UART to make it talk.
+	 * Only use this console if you really screw up and can't
+	 *  get to the stage of setting up a real serial console.
+	 */
+	/*ns16550_setup_console();*/
+
+	/* request I/O space for devices used on all i[345]86 PCs */
+	for (i = 0; i < COBALT_IO_RESOURCES; i++)
+		request_resource(&ioport_resource, cobalt_io_resources + i);
+
+        /* Read the cobalt id register out of the PCI config space */
+        PCI_CFG_SET(devfn, (VIA_COBALT_BRD_ID_REG & ~0x3));
+        cobalt_board_id = GALILEO_INL(GT_PCI0_CFGDATA_OFS);
+        cobalt_board_id >>= ((VIA_COBALT_BRD_ID_REG & 3) * 8);
+        cobalt_board_id = VIA_COBALT_BRD_REG_to_ID(cobalt_board_id);
+
+#ifdef CONFIG_PCI
+	register_pci_controller(&cobalt_pci_controller);
+#endif
+}
+
+early_initcall(cobalt_setup);
+
+/*
+ * Prom init. We read our one and only communication with the firmware.
+ * Grab the amount of installed memory
+ */
+
+void __init prom_init(void)
+{
+	int argc = fw_arg0;
+
+	strcpy(arcs_cmdline, my_cmdline);
+
+	mips_machgroup = MACH_GROUP_COBALT;
+
+	add_memory_region(0x0, argc & 0x7fffffff, BOOT_MEM_RAM);
+}
+
+unsigned long __init prom_free_prom_memory(void)
+{
+	/* Nothing to do! */
+	return 0;
+}
diff --git a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig
new file mode 100644
index 0000000..caad7ca
--- /dev/null
+++ b/arch/mips/configs/atlas_defconfig
@@ -0,0 +1,1104 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:00 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+CONFIG_MIPS_ATLAS=y
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_MIPS_BONITO64=y
+CONFIG_MIPS_MSC=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_MIPS_BOARDS_GEN=y
+CONFIG_MIPS_GT64120=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_BOOT_ELF32=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+
+#
+# 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_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# 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_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECD=y
+# 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
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_IDEPCI is not set
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=y
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLA2XXX=y
+# CONFIG_SCSI_QLA21XX is not set
+# CONFIG_SCSI_QLA22XX is not set
+# CONFIG_SCSI_QLA2300 is not set
+# CONFIG_SCSI_QLA2322 is not set
+# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID5=m
+CONFIG_MD_RAID6=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_FWMARK=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+CONFIG_IP_TCPDIAG_IPV6=y
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_CT_ACCT=y
+CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CT_PROTO_SCTP=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_PHYSDEV=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_REALM=m
+CONFIG_IP_NF_MATCH_SCTP=m
+CONFIG_IP_NF_MATCH_COMMENT=m
+CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_CONNMARK=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_TARGET_NOTRACK=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_LIMIT=m
+CONFIG_IP6_NF_MATCH_MAC=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_MULTIPORT=m
+CONFIG_IP6_NF_MATCH_OWNER=m
+CONFIG_IP6_NF_MATCH_MARK=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_AHESP=m
+CONFIG_IP6_NF_MATCH_LENGTH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_PHYSDEV=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_TARGET_MARK=m
+CONFIG_IP6_NF_RAW=m
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+# CONFIG_ATM is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=y
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+CONFIG_NET_DIVERT=y
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CLK_JIFFIES=y
+# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
+# CONFIG_NET_SCH_CLK_CPU is not set
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_QOS=y
+CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+# CONFIG_CLS_U32_PERF is not set
+CONFIG_NET_CLS_IND=y
+# CONFIG_CLS_U32_MARK is not set
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_CLS_POLICE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+# CONFIG_ETHERTAP is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=y
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+CONFIG_LAN_SAA9730=y
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=m
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=y
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+CONFIG_INPUT_MOUSE=y
+# CONFIG_MOUSE_PS2 is not set
+CONFIG_MOUSE_SERIAL=m
+# CONFIG_MOUSE_VSXXXAA 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+# CONFIG_XFS_RT is not set
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=y
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=m
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_CRAMFS=m
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE 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=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V4 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig
new file mode 100644
index 0000000..1b7f8a7
--- /dev/null
+++ b/arch/mips/configs/capcella_defconfig
@@ -0,0 +1,705 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:00 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+CONFIG_MACH_VR41XX=y
+# CONFIG_NEC_CMBVR4133 is not set
+# CONFIG_CASIO_E55 is not set
+# CONFIG_IBM_WORKPAD is not set
+# CONFIG_TANBAC_TB0226 is not set
+# CONFIG_TANBAC_TB0229 is not set
+# CONFIG_VICTOR_MPC30X is not set
+CONFIG_ZAO_CAPCELLA=y
+CONFIG_PCI_VR41XX=y
+CONFIG_VRC4173=y
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+CONFIG_CPU_VR41XX=y
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# 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_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_IDEPCI is not set
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input 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
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=m
+CONFIG_SERIO_RAW=m
+
+#
+# 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI 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_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=y
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_EXPORTFS=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC32 is not set
+CONFIG_LIBCRC32C=m
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig
new file mode 100644
index 0000000..8861854
--- /dev/null
+++ b/arch/mips/configs/cobalt_defconfig
@@ -0,0 +1,680 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:00 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+CONFIG_MIPS_COBALT=y
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_I8259=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_MIPS_GT64111=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+CONFIG_CPU_NEVADA=y
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+
+#
+# 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_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=y
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=y
+
+#
+# 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_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_IDEPCI is not set
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=y
+
+#
+# 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_RTC=y
+CONFIG_COBALT_LCD=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+# CONFIG_EXPORTFS is not set
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC32 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig
new file mode 100644
index 0000000..19cac1b
--- /dev/null
+++ b/arch/mips/configs/db1000_defconfig
@@ -0,0 +1,763 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:01 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+CONFIG_SOC_AU1X00=y
+CONFIG_SOC_AU1000=y
+# CONFIG_SOC_AU1100 is not set
+# CONFIG_SOC_AU1500 is not set
+# CONFIG_SOC_AU1550 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+CONFIG_MIPS_DB1000=y
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_64BIT_PHYS_ADDR=y
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+# CONFIG_PCI is not set
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=m
+
+#
+# PC-card bridges
+#
+# CONFIG_TCIC is not set
+# CONFIG_PCMCIA_AU1X00 is not set
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_CONNTRACK_MARK=y
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_MIPS_AU1X00_ENET=y
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# 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 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+
+#
+# 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_AU1X00_GPIO is not set
+# CONFIG_TS_AU1X00_ADS7846 is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_AU1X00=y
+CONFIG_SERIAL_AU1X00_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+CONFIG_SYNCLINK_CS=m
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+# CONFIG_EXT2_FS_SECURITY is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_CRAMFS=m
+# 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 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=m
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_EXPORTFS=m
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT 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=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=m
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+CONFIG_CRYPTO_TWOFISH=y
+# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_TEA=m
+# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig
new file mode 100644
index 0000000..035ac95
--- /dev/null
+++ b/arch/mips/configs/db1100_defconfig
@@ -0,0 +1,758 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:01 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+CONFIG_SOC_AU1X00=y
+# CONFIG_SOC_AU1000 is not set
+CONFIG_SOC_AU1100=y
+# CONFIG_SOC_AU1500 is not set
+# CONFIG_SOC_AU1550 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_DB1000 is not set
+CONFIG_MIPS_DB1100=y
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=m
+
+#
+# PC-card bridges
+#
+# CONFIG_TCIC is not set
+# CONFIG_PCMCIA_AU1X00 is not set
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_CONNTRACK_MARK=y
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+# CONFIG_MIPS_AU1X00_ENET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# 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 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+CONFIG_SERIO_LIBPS2=m
+CONFIG_SERIO_RAW=m
+
+#
+# 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_AU1X00_GPIO is not set
+# CONFIG_TS_AU1X00_ADS7846 is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AU1X00 is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+CONFIG_SYNCLINK_CS=m
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+# CONFIG_EXT2_FS_SECURITY is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_CRAMFS=m
+# 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 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=m
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_EXPORTFS=m
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT 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=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=m
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+CONFIG_CRYPTO_TWOFISH=y
+# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_TEA=m
+# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig
new file mode 100644
index 0000000..c38c4ed
--- /dev/null
+++ b/arch/mips/configs/db1500_defconfig
@@ -0,0 +1,1018 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:01 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+CONFIG_SOC_AU1X00=y
+# CONFIG_SOC_AU1000 is not set
+# CONFIG_SOC_AU1100 is not set
+CONFIG_SOC_AU1500=y
+# CONFIG_SOC_AU1550 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+CONFIG_MIPS_DB1500=y
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_COHERENT=y
+CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_64BIT_PHYS_ADDR=y
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=m
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+# CONFIG_YENTA is not set
+# CONFIG_PD6729 is not set
+# CONFIG_I82092 is not set
+# CONFIG_TCIC is not set
+CONFIG_PCMCIA_AU1X00=m
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_AMDSTD_RETRY=0
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_XIP is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_DB1X00=y
+CONFIG_MTD_DB1X00_BOOT=y
+CONFIG_MTD_DB1X00_USER=y
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND 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_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# 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_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_IDE_GENERIC is not set
+# CONFIG_BLK_DEV_IDEPCI is not set
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_CONNTRACK_MARK=y
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+CONFIG_MIPS_AU1X00_ENET=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# 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 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+
+#
+# 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
+# CONFIG_AU1X00_GPIO is not set
+# CONFIG_TS_AU1X00_ADS7846 is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_AU1X00=y
+CONFIG_SERIAL_AU1X00_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+CONFIG_SYNCLINK_CS=m
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+# CONFIG_SND is not set
+
+#
+# Open Sound System
+#
+CONFIG_SOUND_PRIME=y
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_SONICVIBES is not set
+CONFIG_SOUND_AU1000=y
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_SOUND_OSS is not set
+# CONFIG_SOUND_ALI5455 is not set
+# CONFIG_SOUND_FORTE is not set
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_AD1980 is not set
+
+#
+# USB support
+#
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH_TTY is not set
+# CONFIG_USB_MIDI is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+# CONFIG_USB_STORAGE is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+
+#
+# USB ATM/DSL drivers
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+# CONFIG_EXT2_FS_SECURITY is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=m
+# 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 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=m
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_EXPORTFS=m
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT 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=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=m
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+CONFIG_CRYPTO_TWOFISH=y
+# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_TEA=m
+# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig
new file mode 100644
index 0000000..ee81309
--- /dev/null
+++ b/arch/mips/configs/db1550_defconfig
@@ -0,0 +1,932 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:02 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+CONFIG_SOC_AU1X00=y
+# CONFIG_SOC_AU1000 is not set
+# CONFIG_SOC_AU1100 is not set
+# CONFIG_SOC_AU1500 is not set
+CONFIG_SOC_AU1550=y
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+CONFIG_MIPS_DB1550=y
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_COHERENT=y
+CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_64BIT_PHYS_ADDR=y
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=m
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+# CONFIG_YENTA is not set
+# CONFIG_PD6729 is not set
+# CONFIG_I82092 is not set
+# CONFIG_TCIC is not set
+CONFIG_PCMCIA_AU1X00=m
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_AMDSTD_RETRY=0
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_DB1550=y
+CONFIG_MTD_DB1550_BOOT=y
+CONFIG_MTD_DB1550_USER=y
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_IDS=m
+CONFIG_MTD_NAND_AU1550=m
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM 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_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# 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_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_CONNTRACK_MARK=y
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_MIPS_AU1X00_ENET=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# 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 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+
+#
+# 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
+# CONFIG_AU1X00_GPIO is not set
+# CONFIG_TS_AU1X00_ADS7846 is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_AU1X00=y
+CONFIG_SERIAL_AU1X00_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+CONFIG_SYNCLINK_CS=m
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+# CONFIG_EXT2_FS_SECURITY is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=m
+# 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 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=m
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_EXPORTFS=m
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT 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=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=m
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+CONFIG_CRYPTO_TWOFISH=y
+# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_TEA=m
+# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/ddb5476_defconfig b/arch/mips/configs/ddb5476_defconfig
new file mode 100644
index 0000000..d43ed57
--- /dev/null
+++ b/arch/mips/configs/ddb5476_defconfig
@@ -0,0 +1,726 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:02 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+CONFIG_DDB5476=y
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_I8259=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_DDB5XXX_COMMON=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+CONFIG_HAVE_STD_PC_SERIAL_PORT=y
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+CONFIG_CPU_R5432=y
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_ISA=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+CONFIG_PCMCIA_PROBE=y
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=y
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=y
+
+#
+# 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_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_IDEPCI is not set
+# CONFIG_IDE_ARM is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=y
+
+#
+# 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON_OLD is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_E1356 is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+
+#
+# Logo configuration
+#
+# CONFIG_LOGO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# 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_EXPORTFS is not set
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE="ip=any"
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC32 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/ddb5477_defconfig b/arch/mips/configs/ddb5477_defconfig
new file mode 100644
index 0000000..5a032cd
--- /dev/null
+++ b/arch/mips/configs/ddb5477_defconfig
@@ -0,0 +1,680 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:02 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+CONFIG_DDB5477=y
+CONFIG_DDB5477_BUS_FREQUENCY=0
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_I8259=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_DDB5XXX_COMMON=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+CONFIG_CPU_R5432=y
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=y
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=y
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=y
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_LAN_SAA9730 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=y
+
+#
+# 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=y
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_EXPORTFS=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE="ip=any"
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig
new file mode 100644
index 0000000..32ada79
--- /dev/null
+++ b/arch/mips/configs/decstation_defconfig
@@ -0,0 +1,660 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:03 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+CONFIG_MACH_DECSTATION=y
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_BOOT_ELF32=y
+CONFIG_MIPS_L1_CACHE_SHIFT=4
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+CONFIG_CPU_R3000=y
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_WB=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_TC=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+CONFIG_SCSI_DECNCR=y
+# CONFIG_SCSI_DECSII is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+CONFIG_DECLANCE=y
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+
+#
+# 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_DZ=y
+CONFIG_SERIAL_DZ_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD is not set
+# CONFIG_EXPORTFS 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=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+CONFIG_ULTRIX_PARTITION=y
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig
new file mode 100644
index 0000000..52074a20
--- /dev/null
+++ b/arch/mips/configs/e55_defconfig
@@ -0,0 +1,683 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:03 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+CONFIG_MACH_VR41XX=y
+# CONFIG_NEC_CMBVR4133 is not set
+CONFIG_CASIO_E55=y
+# CONFIG_IBM_WORKPAD is not set
+# CONFIG_TANBAC_TB0226 is not set
+# CONFIG_TANBAC_TB0229 is not set
+# CONFIG_VICTOR_MPC30X is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_VRC4171 is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+CONFIG_CPU_VR41XX=y
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_ISA=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+CONFIG_PCMCIA_PROBE=y
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# 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_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_IDE_ARM is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input 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
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+
+#
+# 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+
+#
+# ISA-based Watchdog Cards
+#
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_WDT is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=y
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_LOCKD=y
+CONFIG_EXPORTFS=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC32 is not set
+CONFIG_LIBCRC32C=m
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/ev64120_defconfig b/arch/mips/configs/ev64120_defconfig
new file mode 100644
index 0000000..360e842
--- /dev/null
+++ b/arch/mips/configs/ev64120_defconfig
@@ -0,0 +1,672 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:03 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_KMOD is not set
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+CONFIG_MIPS_EV64120=y
+# CONFIG_EVB_PCI1 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_MIPS_GT64120=y
+# CONFIG_SYSCLK_75 is not set
+# CONFIG_SYSCLK_83 is not set
+CONFIG_SYSCLK_100=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+CONFIG_CPU_R5000=y
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=y
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPPOE is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+
+#
+# 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# 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_EXPORTFS is not set
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs rw nfsroot=192.168.1.1:/mnt/disk2/fs.gal ip=192.168.1.211:192.168.1.1:::gt::"
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC32 is not set
+CONFIG_LIBCRC32C=m
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/ev96100_defconfig b/arch/mips/configs/ev96100_defconfig
new file mode 100644
index 0000000..657a950
--- /dev/null
+++ b/arch/mips/configs/ev96100_defconfig
@@ -0,0 +1,626 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:03 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_KMOD is not set
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+CONFIG_MIPS_EV96100=y
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_IRQ_CPU=y
+CONFIG_MIPS_GT64120=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_MIPS_GT96100=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+CONFIG_CPU_RM7000=y
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_BOARD_SCACHE=y
+CONFIG_RM7000_CPU_SCACHE=y
+CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+# CONFIG_PCI is not set
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+CONFIG_MIPS_GT96100ETH=y
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+
+#
+# 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# 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_EXPORTFS is not set
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC32 is not set
+CONFIG_LIBCRC32C=m
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig
new file mode 100644
index 0000000..3fb102e
--- /dev/null
+++ b/arch/mips/configs/ip22_defconfig
@@ -0,0 +1,962 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:04 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+CONFIG_SGI_IP22=y
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_ARC=y
+CONFIG_DMA_NONCOHERENT=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_IRQ_CPU=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_ARC32=y
+CONFIG_BOOT_ELF32=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+CONFIG_ARC_CONSOLE=y
+CONFIG_ARC_PROMLIB=y
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+CONFIG_CPU_R5000=y
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_BOARD_SCACHE=y
+CONFIG_IP22_CPU_SCACHE=y
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+# CONFIG_EISA is not set
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=m
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+CONFIG_SGIWD93_SCSI=y
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+CONFIG_IP_TCPDIAG_IPV6=y
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_CT_ACCT=y
+CONFIG_IP_NF_CONNTRACK_MARK=y
+# CONFIG_IP_NF_CT_PROTO_SCTP is not set
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_REALM=m
+CONFIG_IP_NF_MATCH_SCTP=m
+CONFIG_IP_NF_MATCH_COMMENT=m
+CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_CONNMARK=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_TARGET_NOTRACK=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_LIMIT=m
+CONFIG_IP6_NF_MATCH_MAC=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_MULTIPORT=m
+CONFIG_IP6_NF_MATCH_OWNER=m
+CONFIG_IP6_NF_MATCH_MARK=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_AHESP=m
+CONFIG_IP6_NF_MATCH_LENGTH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_TARGET_MARK=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+CONFIG_NET_DIVERT=y
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_QOS=y
+CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+# CONFIG_CLS_U32_PERF is not set
+# CONFIG_NET_CLS_IND is not set
+# CONFIG_CLS_U32_MARK is not set
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_CLS_POLICE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_ETHERTAP=m
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+CONFIG_SGISEEQ=y
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=m
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input 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
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=m
+CONFIG_MOUSE_SERIAL=m
+# CONFIG_MOUSE_VSXXXAA 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_IP22_ZILOG=m
+CONFIG_SERIAL_CORE=m
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_INDYDOG=m
+# CONFIG_RTC is not set
+CONFIG_SGI_DS1286=m
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+CONFIG_RAW_DRIVER=m
+CONFIG_MAX_RAW_DEVS=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_SGI_NEWPORT_CONSOLE=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+CONFIG_LOGO_SGI_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=m
+# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+# CONFIG_XFS_RT is not set
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+# CONFIG_XFS_POSIX_ACL is not set
+CONFIG_MINIX_FS=m
+# CONFIG_ROMFS_FS is not set
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=m
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=m
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+CONFIG_EFS_FS=m
+# 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=m
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V4 is not set
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_SMB_NLS_REMOTE="cp437"
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_NCP_FS is not set
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC32=m
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
new file mode 100644
index 0000000..1347229
--- /dev/null
+++ b/arch/mips/configs/ip27_defconfig
@@ -0,0 +1,827 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:04 2005
+#
+CONFIG_MIPS=y
+CONFIG_MIPS64=y
+CONFIG_64BIT=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_LOCK_KERNEL=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=15
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# 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_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+CONFIG_SGI_IP27=y
+# CONFIG_SGI_SN0_N_MODE is not set
+CONFIG_DISCONTIGMEM=y
+CONFIG_NUMA=y
+# CONFIG_MAPPED_KERNEL is not set
+# CONFIG_REPLICATE_KTEXT is not set
+# CONFIG_REPLICATE_EXHANDLERS is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_ARC=y
+CONFIG_DMA_IP27=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_MIPS_L1_CACHE_SHIFT=7
+CONFIG_ARC64=y
+CONFIG_BOOT_ELF64=y
+CONFIG_QL_ISP_A64=y
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+CONFIG_CPU_R10000=y
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=64
+# CONFIG_PREEMPT is not set
+# CONFIG_MIPS_INSANE_LARGE is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_BUILD_ELF64 is not set
+CONFIG_MIPS32_COMPAT=y
+CONFIG_COMPAT=y
+CONFIG_MIPS32_O32=y
+# CONFIG_MIPS32_N32 is not set
+CONFIG_BINFMT_ELF32=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=y
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+CONFIG_SCSI_QLOGIC_ISP=y
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLA2XXX=y
+# CONFIG_SCSI_QLA21XX is not set
+# CONFIG_SCSI_QLA22XX is not set
+# CONFIG_SCSI_QLA2300 is not set
+# CONFIG_SCSI_QLA2322 is not set
+# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=y
+CONFIG_MD_RAID1=y
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID5=y
+CONFIG_MD_RAID6=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# 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_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_QOS=y
+CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+# CONFIG_CLS_U32_PERF is not set
+# CONFIG_NET_CLS_IND is not set
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_CLS_POLICE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_SGI_IOC3_ETH=y
+CONFIG_SGI_IOC3_ETH_HW_RX_CSUM=y
+CONFIG_SGI_IOC3_ETH_HW_TX_CSUM=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Userland interfaces
+#
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+
+#
+# Input Device Drivers
+#
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+CONFIG_SGI_IP27_RTC=y
+# 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_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+CONFIG_JBD_DEBUG=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+# CONFIG_XFS_RT is not set
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# 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 is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_EXPORTFS is not set
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig
new file mode 100644
index 0000000..bdf1415
--- /dev/null
+++ b/arch/mips/configs/ip32_defconfig
@@ -0,0 +1,750 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:04 2005
+#
+CONFIG_MIPS=y
+CONFIG_MIPS64=y
+CONFIG_64BIT=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+CONFIG_SGI_IP32=y
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_ARC=y
+CONFIG_DMA_IP32=y
+CONFIG_OWN_DMA=y
+CONFIG_DMA_NONCOHERENT=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_ARC32=y
+CONFIG_BOOT_ELF32=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+CONFIG_ARC_MEMORY=y
+CONFIG_ARC_PROMLIB=y
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+CONFIG_CPU_R5000=y
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_BOARD_SCACHE=y
+CONFIG_R5000_CPU_SCACHE=y
+CONFIG_RM7000_CPU_SCACHE=y
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+# CONFIG_BUILD_ELF64 is not set
+CONFIG_MIPS32_COMPAT=y
+CONFIG_COMPAT=y
+CONFIG_MIPS32_O32=y
+# CONFIG_MIPS32_N32 is not set
+CONFIG_BINFMT_ELF32=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CDROM_PKTCDVD=y
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=y
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_CHR_DEV_OSST=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=y
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+CONFIG_SCSI_AIC7XXX=y
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=8
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+CONFIG_AIC7XXX_DEBUG_ENABLE=y
+CONFIG_AIC7XXX_DEBUG_MASK=0
+CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLA2XXX=y
+# CONFIG_SCSI_QLA21XX is not set
+# CONFIG_SCSI_QLA22XX is not set
+# CONFIG_SCSI_QLA2300 is not set
+# CONFIG_SCSI_QLA2322 is not set
+# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+CONFIG_SGI_O2MACE_ETH=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_MACEPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=y
+
+#
+# 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# 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_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC32 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/it8172_defconfig b/arch/mips/configs/it8172_defconfig
new file mode 100644
index 0000000..1ca7746
--- /dev/null
+++ b/arch/mips/configs/it8172_defconfig
@@ -0,0 +1,740 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:05 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+CONFIG_MIPS_ITE8172=y
+# CONFIG_IT8172_REVC is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_ITE_BOARD_GEN=y
+CONFIG_IT8172_CIR=y
+CONFIG_IT8712=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+CONFIG_CPU_NEVADA=y
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+# CONFIG_PCI is not set
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_PARTITIONS is not set
+# CONFIG_MTD_CONCAT is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+# CONFIG_MTD_BLOCK is not set
+# CONFIG_MTD_BLOCK_RO is not set
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_XIP is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x8000000
+CONFIG_MTD_PHYSMAP_LEN=0x2000000
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# 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_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+
+#
+# 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_QTRONIX_KEYBOARD is not set
+# CONFIG_IT8172_SCR0 is not set
+# CONFIG_IT8172_SCR1 is not set
+# CONFIG_ITE_GPIO is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+# CONFIG_SND is not set
+
+#
+# Open Sound System
+#
+CONFIG_SOUND_PRIME=y
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_SONICVIBES is not set
+CONFIG_SOUND_IT8172=y
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_OSS is not set
+# CONFIG_SOUND_AD1980 is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_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 is not set
+# 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_EXPORTFS is not set
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC32 is not set
+CONFIG_LIBCRC32C=m
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/ivr_defconfig b/arch/mips/configs/ivr_defconfig
new file mode 100644
index 0000000..c6eef70
--- /dev/null
+++ b/arch/mips/configs/ivr_defconfig
@@ -0,0 +1,686 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:05 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+CONFIG_MIPS_IVR=y
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_ITE_BOARD_GEN=y
+CONFIG_IT8172_CIR=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+CONFIG_CPU_NEVADA=y
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# 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_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_IDEPCI is not set
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+
+#
+# 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_QTRONIX_KEYBOARD=y
+# CONFIG_IT8172_SCR0 is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# 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_EXPORTFS is not set
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC32 is not set
+CONFIG_LIBCRC32C=m
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/jaguar-atx_defconfig b/arch/mips/configs/jaguar-atx_defconfig
new file mode 100644
index 0000000..757c4e8
--- /dev/null
+++ b/arch/mips/configs/jaguar-atx_defconfig
@@ -0,0 +1,620 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:05 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+CONFIG_MOMENCO_JAGUAR_ATX=y
+CONFIG_JAGUAR_DMALOW=y
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_LIMITED_DMA=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_IRQ_CPU=y
+CONFIG_IRQ_CPU_RM7K=y
+CONFIG_IRQ_MV64340=y
+CONFIG_PCI_MARVELL=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_BOOT_ELF32=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+CONFIG_CPU_RM9000=y
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_BOARD_SCACHE=y
+CONFIG_RM7000_CPU_SCACHE=y
+CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_HIGHMEM=y
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET 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 is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_DGRS is not set
+CONFIG_EEPRO100=y
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+CONFIG_MV643XX_ETH=y
+CONFIG_MV643XX_ETH_0=y
+CONFIG_MV643XX_ETH_1=y
+CONFIG_MV643XX_ETH_2=y
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Userland interfaces
+#
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+# CONFIG_SERIO is not set
+# CONFIG_SERIO_I8042 is not set
+
+#
+# Input Device Drivers
+#
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVPTS_FS_XATTR is not set
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_HFSPLUS_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 is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+# CONFIG_EXPORTFS is not set
+CONFIG_SUNRPC=y
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC32 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig
new file mode 100644
index 0000000..e5a6139
--- /dev/null
+++ b/arch/mips/configs/jmr3927_defconfig
@@ -0,0 +1,696 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:06 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+CONFIG_TOSHIBA_JMR3927=y
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_MIPS_TX3927=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+CONFIG_TOSHIBA_BOARDS=y
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+CONFIG_CPU_TX39XX=y
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+CONFIG_RTC_DS1742=y
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=y
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=y
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=y
+
+#
+# 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_DIGI is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+# CONFIG_SYNCLINK is not set
+# CONFIG_SYNCLINKMP is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+# CONFIG_SERIAL_TX3912 is not set
+CONFIG_TXX927_SERIAL=y
+CONFIG_TXX927_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_TXX9 is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_UNIX98_PTYS is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON_OLD is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_E1356 is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+
+#
+# Logo configuration
+#
+# CONFIG_LOGO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# 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_EXPORTFS is not set
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC32 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/lasat200_defconfig b/arch/mips/configs/lasat200_defconfig
new file mode 100644
index 0000000..1e76978
--- /dev/null
+++ b/arch/mips/configs/lasat200_defconfig
@@ -0,0 +1,791 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:06 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+CONFIG_LASAT=y
+CONFIG_PICVUE=y
+CONFIG_PICVUE_PROC=y
+CONFIG_DS1603=y
+CONFIG_LASAT_SYSCTL=y
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_MIPS_NILE4=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_MIPS_GT64120=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+CONFIG_CPU_R5000=y
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_BOARD_SCACHE=y
+CONFIG_R5000_CPU_SCACHE=y
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_PCI_NAMES is not set
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_AMDSTD_RETRY=0
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_LASAT=y
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND 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_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# 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_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+CONFIG_BLK_DEV_CMD64X=y
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK_DEV is not set
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input 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
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+
+#
+# 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_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_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_EXPORTFS is not set
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig
new file mode 100644
index 0000000..61fb9fb
--- /dev/null
+++ b/arch/mips/configs/malta_defconfig
@@ -0,0 +1,1132 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:53:14 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+CONFIG_MIPS_MALTA=y
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_I8259=y
+CONFIG_MIPS_BONITO64=y
+CONFIG_MIPS_MSC=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_MIPS_BOARDS_GEN=y
+CONFIG_MIPS_GT64120=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_BOOT_ELF32=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+CONFIG_HAVE_STD_PC_SERIAL_PORT=y
+
+#
+# CPU selection
+#
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+
+#
+# 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=m
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# 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_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECD=y
+# 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
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# 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=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=32
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLA2XXX=m
+# CONFIG_SCSI_QLA21XX is not set
+# CONFIG_SCSI_QLA22XX is not set
+# CONFIG_SCSI_QLA2300 is not set
+# CONFIG_SCSI_QLA2322 is not set
+# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID5=m
+CONFIG_MD_RAID6=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_FWMARK=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+CONFIG_IP_TCPDIAG_IPV6=y
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_CT_ACCT=y
+CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CT_PROTO_SCTP=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_PHYSDEV=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_REALM=m
+CONFIG_IP_NF_MATCH_SCTP=m
+CONFIG_IP_NF_MATCH_COMMENT=m
+CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_CONNMARK=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_TARGET_NOTRACK=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_LIMIT=m
+CONFIG_IP6_NF_MATCH_MAC=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_MULTIPORT=m
+CONFIG_IP6_NF_MATCH_OWNER=m
+CONFIG_IP6_NF_MATCH_MARK=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_AHESP=m
+CONFIG_IP6_NF_MATCH_LENGTH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_PHYSDEV=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_TARGET_MARK=m
+CONFIG_IP6_NF_RAW=m
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+# CONFIG_ATM is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=y
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+CONFIG_NET_DIVERT=y
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CLK_JIFFIES=y
+# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
+# CONFIG_NET_SCH_CLK_CPU is not set
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_QOS=y
+CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+# CONFIG_CLS_U32_PERF is not set
+CONFIG_NET_CLS_IND=y
+# CONFIG_CLS_U32_MARK is not set
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_CLS_POLICE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+# CONFIG_ETHERTAP is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=y
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_LAN_SAA9730 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+# CONFIG_XFS_RT is not set
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=y
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=m
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_CRAMFS=m
+CONFIG_VXFS_FS=m
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE 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=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V4 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig
new file mode 100644
index 0000000..31b8f2a
--- /dev/null
+++ b/arch/mips/configs/mpc30x_defconfig
@@ -0,0 +1,694 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:07 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+CONFIG_MACH_VR41XX=y
+# CONFIG_NEC_CMBVR4133 is not set
+# CONFIG_CASIO_E55 is not set
+# CONFIG_IBM_WORKPAD is not set
+# CONFIG_TANBAC_TB0226 is not set
+# CONFIG_TANBAC_TB0229 is not set
+CONFIG_VICTOR_MPC30X=y
+# CONFIG_ZAO_CAPCELLA is not set
+CONFIG_PCI_VR41XX=y
+CONFIG_VRC4173=y
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+CONFIG_CPU_VR41XX=y
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input 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
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+
+#
+# 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# 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_EXPORTFS is not set
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=m
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+CONFIG_CRYPTO_TWOFISH=y
+# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_TEA=m
+# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC32 is not set
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/ocelot_3_defconfig b/arch/mips/configs/ocelot_3_defconfig
new file mode 100644
index 0000000..2cce682
--- /dev/null
+++ b/arch/mips/configs/ocelot_3_defconfig
@@ -0,0 +1,886 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:07 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+CONFIG_MOMENCO_OCELOT_3=y
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_IRQ_CPU=y
+CONFIG_IRQ_CPU_RM7K=y
+CONFIG_IRQ_MV64340=y
+CONFIG_PCI_MARVELL=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_BOOT_ELF32=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+CONFIG_CPU_RM9000=y
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_BOARD_SCACHE=y
+CONFIG_RM7000_CPU_SCACHE=y
+CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_HIGHMEM is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE 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 is not set
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLA2XXX=m
+# CONFIG_SCSI_QLA21XX is not set
+# CONFIG_SCSI_QLA22XX is not set
+# CONFIG_SCSI_QLA2300 is not set
+# CONFIG_SCSI_QLA2322 is not set
+# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+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=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_IP_TCPDIAG=m
+CONFIG_IP_TCPDIAG_IPV6=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_IPV6_TUNNEL is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_CONNTRACK_MARK is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# IPv6: Netfilter Configuration
+#
+# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES is not set
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+# CONFIG_ETHERTAP is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=y
+# CONFIG_E100_NAPI is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_LAN_SAA9730 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+CONFIG_MV643XX_ETH=y
+CONFIG_MV643XX_ETH_0=y
+CONFIG_MV643XX_ETH_1=y
+CONFIG_MV643XX_ETH_2=y
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+CONFIG_FB_MODE_HELPERS=y
+# CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON_OLD is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_E1356 is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# 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 is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_REISERFS_FS_XATTR is not set
+# CONFIG_JFS_FS is not set
+CONFIG_XFS_FS=m
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_SECURITY is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_DEVFS_FS=y
+CONFIG_DEVFS_MOUNT=y
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+CONFIG_EFS_FS=y
+CONFIG_CRAMFS=y
+# 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=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V4 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT 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=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE="ip=any root=nfs"
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/ocelot_c_defconfig b/arch/mips/configs/ocelot_c_defconfig
new file mode 100644
index 0000000..0cbf48a
--- /dev/null
+++ b/arch/mips/configs/ocelot_c_defconfig
@@ -0,0 +1,664 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:07 2005
+#
+CONFIG_MIPS=y
+CONFIG_MIPS64=y
+CONFIG_64BIT=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+CONFIG_MOMENCO_OCELOT_C=y
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_IRQ_CPU=y
+CONFIG_IRQ_MV64340=y
+CONFIG_PCI_MARVELL=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+CONFIG_CPU_RM7000=y
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_BOARD_SCACHE=y
+CONFIG_RM7000_CPU_SCACHE=y
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_BUILD_ELF64 is not set
+CONFIG_MIPS32_COMPAT=y
+CONFIG_COMPAT=y
+CONFIG_MIPS32_O32=y
+CONFIG_MIPS32_N32=y
+CONFIG_BINFMT_ELF32=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CDROM_PKTCDVD=y
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=y
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+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_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_MV643XX_ETH is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=y
+
+#
+# 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=y
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_EXPORTFS=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC32 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/ocelot_defconfig b/arch/mips/configs/ocelot_defconfig
new file mode 100644
index 0000000..4043950
--- /dev/null
+++ b/arch/mips/configs/ocelot_defconfig
@@ -0,0 +1,624 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:08 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+CONFIG_MOMENCO_OCELOT=y
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_IRQ_CPU=y
+CONFIG_IRQ_CPU_RM7K=y
+CONFIG_MIPS_GT64120=y
+CONFIG_SWAP_IO_SPACE=y
+# CONFIG_SYSCLK_75 is not set
+# CONFIG_SYSCLK_83 is not set
+CONFIG_SYSCLK_100=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+CONFIG_CPU_RM7000=y
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_BOARD_SCACHE=y
+CONFIG_RM7000_CPU_SCACHE=y
+CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+# CONFIG_PCI is not set
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=y
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=y
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=y
+
+#
+# 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=y
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_EXPORTFS=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC32 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/ocelot_g_defconfig b/arch/mips/configs/ocelot_g_defconfig
new file mode 100644
index 0000000..3870af4
--- /dev/null
+++ b/arch/mips/configs/ocelot_g_defconfig
@@ -0,0 +1,667 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:08 2005
+#
+CONFIG_MIPS=y
+CONFIG_MIPS64=y
+CONFIG_64BIT=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+CONFIG_MOMENCO_OCELOT_G=y
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_IRQ_CPU=y
+CONFIG_IRQ_CPU_RM7K=y
+CONFIG_PCI_MARVELL=y
+CONFIG_SWAP_IO_SPACE=y
+# CONFIG_SYSCLK_75 is not set
+# CONFIG_SYSCLK_83 is not set
+CONFIG_SYSCLK_100=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+CONFIG_CPU_RM7000=y
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_BOARD_SCACHE=y
+CONFIG_RM7000_CPU_SCACHE=y
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_BUILD_ELF64 is not set
+CONFIG_MIPS32_COMPAT=y
+CONFIG_COMPAT=y
+CONFIG_MIPS32_O32=y
+CONFIG_MIPS32_N32=y
+CONFIG_BINFMT_ELF32=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CDROM_PKTCDVD=y
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=y
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+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_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_GALILEO_64240_ETH=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=y
+
+#
+# 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=y
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_EXPORTFS=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC32 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/osprey_defconfig b/arch/mips/configs/osprey_defconfig
new file mode 100644
index 0000000..989cb9e
--- /dev/null
+++ b/arch/mips/configs/osprey_defconfig
@@ -0,0 +1,618 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:08 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+CONFIG_NEC_OSPREY=y
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+CONFIG_VR4181=y
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+CONFIG_CPU_VR41XX=y
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+
+#
+# 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=y
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_EXPORTFS=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE="ip=bootp ether=46,0x03fe0300,eth0"
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC32 is not set
+CONFIG_LIBCRC32C=m
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig
new file mode 100644
index 0000000..6cdabd5
--- /dev/null
+++ b/arch/mips/configs/pb1100_defconfig
@@ -0,0 +1,826 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:08 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+CONFIG_SOC_AU1X00=y
+# CONFIG_SOC_AU1000 is not set
+CONFIG_SOC_AU1100=y
+# CONFIG_SOC_AU1500 is not set
+# CONFIG_SOC_AU1550 is not set
+# CONFIG_MIPS_PB1000 is not set
+CONFIG_MIPS_PB1100=y
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SWAP_IO_SPACE=y
+# CONFIG_AU1X00_USB_DEVICE is not set
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+# CONFIG_PCI is not set
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=m
+
+#
+# PC-card bridges
+#
+# CONFIG_TCIC is not set
+# CONFIG_PCMCIA_AU1X00 is not set
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_AMDSTD_RETRY=0
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PB1100=y
+CONFIG_MTD_PB1500_BOOT=y
+CONFIG_MTD_PB1500_USER=y
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_CONNTRACK_MARK=y
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_MIPS_AU1X00_ENET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# 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 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+
+#
+# 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_AU1X00_GPIO is not set
+# CONFIG_TS_AU1X00_ADS7846 is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AU1X00 is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+CONFIG_SYNCLINK_CS=m
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+# CONFIG_EXT2_FS_SECURITY is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=m
+# 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 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=m
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_EXPORTFS=m
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT 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=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=m
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+CONFIG_CRYPTO_TWOFISH=y
+# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_TEA=m
+# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig
new file mode 100644
index 0000000..2aebbd2
--- /dev/null
+++ b/arch/mips/configs/pb1500_defconfig
@@ -0,0 +1,855 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:09 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+CONFIG_SOC_AU1X00=y
+# CONFIG_SOC_AU1000 is not set
+# CONFIG_SOC_AU1100 is not set
+CONFIG_SOC_AU1500=y
+# CONFIG_SOC_AU1550 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+CONFIG_MIPS_PB1500=y
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_COHERENT=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_AU1X00_USB_DEVICE is not set
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_64BIT_PHYS_ADDR=y
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=m
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+# CONFIG_YENTA is not set
+CONFIG_PD6729=m
+# CONFIG_I82092 is not set
+# CONFIG_TCIC is not set
+# CONFIG_PCMCIA_AU1X00 is not set
+CONFIG_PCCARD_NONSTATIC=m
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# 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_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_CONNTRACK_MARK=y
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_MIPS_AU1X00_ENET=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# 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 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+
+#
+# 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
+# CONFIG_AU1X00_GPIO is not set
+# CONFIG_TS_AU1X00_ADS7846 is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_AU1X00=y
+CONFIG_SERIAL_AU1X00_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+CONFIG_SYNCLINK_CS=m
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+# CONFIG_EXT2_FS_SECURITY is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_CRAMFS=m
+# 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 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=m
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_EXPORTFS=m
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT 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=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=m
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+CONFIG_CRYPTO_TWOFISH=y
+# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_TEA=m
+# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig
new file mode 100644
index 0000000..9e21edc
--- /dev/null
+++ b/arch/mips/configs/pb1550_defconfig
@@ -0,0 +1,847 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:09 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+CONFIG_SOC_AU1X00=y
+# CONFIG_SOC_AU1000 is not set
+# CONFIG_SOC_AU1100 is not set
+# CONFIG_SOC_AU1500 is not set
+CONFIG_SOC_AU1550=y
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+CONFIG_MIPS_PB1550=y
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_COHERENT=y
+CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_64BIT_PHYS_ADDR=y
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=m
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+# CONFIG_YENTA is not set
+CONFIG_PD6729=m
+# CONFIG_I82092 is not set
+# CONFIG_TCIC is not set
+# CONFIG_PCMCIA_AU1X00 is not set
+CONFIG_PCCARD_NONSTATIC=m
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# 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_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+CONFIG_IP_NF_CONNTRACK_MARK=y
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+CONFIG_MIPS_AU1X00_ENET=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# 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 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+
+#
+# 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
+# CONFIG_AU1X00_GPIO is not set
+# CONFIG_TS_AU1X00_ADS7846 is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_AU1X00=y
+CONFIG_SERIAL_AU1X00_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+CONFIG_SYNCLINK_CS=m
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+# CONFIG_EXT2_FS_SECURITY is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_CRAMFS=m
+# 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 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=m
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_EXPORTFS=m
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT 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=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=m
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+CONFIG_CRYPTO_TWOFISH=y
+# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_TEA=m
+# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig
new file mode 100644
index 0000000..d0c85a4
--- /dev/null
+++ b/arch/mips/configs/rm200_defconfig
@@ -0,0 +1,1383 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:09 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+CONFIG_SNI_RM200_PCI=y
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_ARC=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_I8259=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_ARC32=y
+CONFIG_BOOT_ELF32=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+CONFIG_HAVE_STD_PC_SERIAL_PORT=y
+CONFIG_ARC_CONSOLE=y
+CONFIG_ARC_MEMORY=y
+CONFIG_ARC_PROMLIB=y
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+CONFIG_CPU_R4X00=y
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_PCI_NAMES is not set
+CONFIG_ISA=y
+# CONFIG_EISA is not set
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+CONFIG_PCMCIA_PROBE=y
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=m
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_PC_CML1=m
+CONFIG_PARPORT_SERIAL=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+# CONFIG_PARPORT_OTHER is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=m
+# CONFIG_BLK_DEV_XD is not set
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PARPORT=m
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_BPCK6=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+# CONFIG_PARIDE_EPATC8 is not set
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_SX8=m
+CONFIG_BLK_DEV_UB=m
+CONFIG_BLK_DEV_RAM=m
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=y
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AHA1542 is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_IN2000 is not set
+CONFIG_MEGARAID_NEWGEN=y
+CONFIG_MEGARAID_MM=m
+CONFIG_MEGARAID_MAILBOX=m
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+# CONFIG_SCSI_NCR53C406A is not set
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLA2XXX=y
+# CONFIG_SCSI_QLA21XX is not set
+# CONFIG_SCSI_QLA22XX is not set
+# CONFIG_SCSI_QLA2300 is not set
+# CONFIG_SCSI_QLA2322 is not set
+# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID5=m
+# CONFIG_MD_RAID6 is not set
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_CRYPT is not set
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=m
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=m
+CONFIG_UNIX=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+CONFIG_IP_TCPDIAG_IPV6=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+# CONFIG_IP_NF_CT_ACCT is not set
+CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CT_PROTO_SCTP=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_PHYSDEV=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_REALM=m
+CONFIG_IP_NF_MATCH_SCTP=m
+CONFIG_IP_NF_MATCH_COMMENT=m
+CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_CONNMARK=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_TARGET_NOTRACK=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_LIMIT=m
+CONFIG_IP6_NF_MATCH_MAC=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_MULTIPORT=m
+CONFIG_IP6_NF_MATCH_OWNER=m
+CONFIG_IP6_NF_MATCH_MARK=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_AHESP=m
+CONFIG_IP6_NF_MATCH_LENGTH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_PHYSDEV=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_TARGET_MARK=m
+CONFIG_IP6_NF_RAW=m
+
+#
+# DECnet: Netfilter Configuration
+#
+CONFIG_DECNET_NF_GRABULATOR=m
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+# CONFIG_BRIDGE_EBT_ULOG is not set
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+CONFIG_BRIDGE=m
+# CONFIG_VLAN_8021Q is not set
+CONFIG_DECNET=m
+# CONFIG_DECNET_ROUTER 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
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CLK_JIFFIES=y
+# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
+# CONFIG_NET_SCH_CLK_CPU is not set
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_QOS=y
+CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+# CONFIG_CLS_U32_PERF is not set
+# CONFIG_NET_CLS_IND is not set
+# CONFIG_CLS_U32_MARK is not set
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_CLS_POLICE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+CONFIG_HAMRADIO=y
+
+#
+# Packet Radio protocols
+#
+CONFIG_AX25=m
+CONFIG_AX25_DAMA_SLAVE=y
+CONFIG_NETROM=m
+CONFIG_ROSE=m
+
+#
+# AX.25 network device drivers
+#
+CONFIG_MKISS=m
+CONFIG_6PACK=m
+CONFIG_BPQETHER=m
+# CONFIG_DMASCC is not set
+# CONFIG_SCC is not set
+# CONFIG_BAYCOM_SER_FDX is not set
+# CONFIG_BAYCOM_SER_HDX is not set
+# CONFIG_BAYCOM_PAR is not set
+# CONFIG_BAYCOM_EPP is not set
+# CONFIG_YAM is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_ETHERTAP=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_ISA=y
+# CONFIG_E2100 is not set
+# CONFIG_EWRK3 is not set
+# CONFIG_EEXPRESS is not set
+# CONFIG_EEXPRESS_PRO is not set
+# CONFIG_HPLAN_PLUS is not set
+# CONFIG_HPLAN is not set
+# CONFIG_LP486E is not set
+# CONFIG_ETH16I is not set
+CONFIG_NE2000=m
+# CONFIG_ZNET is not set
+# CONFIG_SEEQ8005 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=y
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_DGRS is not set
+CONFIG_EEPRO100=m
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_LAN_SAA9730 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+CONFIG_VIA_VELOCITY=m
+# CONFIG_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PLIP=m
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input 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
+CONFIG_SERIO_PARKBD=m
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_INPORT is not set
+# CONFIG_MOUSE_LOGIBM is not set
+# CONFIG_MOUSE_PC110PAD is not set
+# CONFIG_MOUSE_VSXXXAA 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_MULTIPORT=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=m
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+CONFIG_PRINTER=m
+# CONFIG_LP_CONSOLE is not set
+CONFIG_PPDEV=m
+CONFIG_TIPAR=m
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_RTC=m
+# 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_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+CONFIG_W1=m
+CONFIG_W1_MATROX=m
+CONFIG_W1_DS9490=m
+CONFIG_W1_DS9490_BRIDGE=m
+CONFIG_W1_THERM=m
+CONFIG_W1_SMEM=m
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB=m
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_UHCI_HCD=m
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_BLUETOOTH_TTY=m
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_RW_DETECT is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_HP8200e=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=m
+CONFIG_USB_HIDINPUT=y
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_USB_HIDDEV=y
+
+#
+# USB HID Boot Protocol drivers
+#
+CONFIG_USB_KBD=m
+CONFIG_USB_MOUSE=m
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+# CONFIG_USB_MTOUCH is not set
+CONFIG_USB_EGALAX=m
+CONFIG_USB_XPAD=m
+# CONFIG_USB_ATI_REMOTE is not set
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+
+#
+# USB Multimedia devices
+#
+CONFIG_USB_DABUSB=m
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+
+#
+# USB Host-to-Host Cables
+#
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_GENESYS=y
+CONFIG_USB_NET1080=y
+CONFIG_USB_PL2301=y
+CONFIG_USB_KC2190=y
+
+#
+# Intelligent USB Devices/Gadgets
+#
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_ZAURUS=y
+CONFIG_USB_CDCETHER=y
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_AX8817X=y
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_SAFE=m
+CONFIG_USB_SERIAL_SAFE_PADDED=y
+# CONFIG_USB_SERIAL_TI is not set
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETSERVO=m
+# CONFIG_USB_IDMOUSE is not set
+CONFIG_USB_TEST=m
+
+#
+# USB ATM/DSL drivers
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=m
+# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+# CONFIG_XFS_RT is not set
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+# CONFIG_XFS_POSIX_ACL is not set
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+# CONFIG_QUOTA is not set
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=m
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=m
+# CONFIG_NTFS_DEBUG is not set
+# CONFIG_NTFS_RW is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+CONFIG_ADFS_FS=m
+# CONFIG_ADFS_FS_RW is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+# CONFIG_HFSPLUS_FS is not set
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_CRAMFS=m
+CONFIG_VXFS_FS=m
+CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V4 is not set
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+CONFIG_CODA_FS_OLD_API=y
+CONFIG_AFS_FS=m
+CONFIG_RXRPC=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+# CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_TEST=m
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig
new file mode 100644
index 0000000..84978b7
--- /dev/null
+++ b/arch/mips/configs/sb1250-swarm_defconfig
@@ -0,0 +1,734 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:10 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_LOCK_KERNEL=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=15
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SOC_AU1X00 is not set
+CONFIG_SIBYTE_SB1xxx_SOC=y
+CONFIG_SIBYTE_SWARM=y
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_UNKNOWN is not set
+CONFIG_SIBYTE_BOARD=y
+CONFIG_SIBYTE_SB1250=y
+CONFIG_CPU_SB1_PASS_1=y
+# CONFIG_CPU_SB1_PASS_2_1250 is not set
+# CONFIG_CPU_SB1_PASS_2_2 is not set
+# CONFIG_CPU_SB1_PASS_4 is not set
+# CONFIG_CPU_SB1_PASS_2_112x is not set
+# CONFIG_CPU_SB1_PASS_3 is not set
+CONFIG_SIBYTE_HAS_LDT=y
+# CONFIG_SIMULATION is not set
+CONFIG_SIBYTE_CFE=y
+# CONFIG_SIBYTE_CFE_CONSOLE is not set
+# CONFIG_SIBYTE_BUS_WATCHER is not set
+# CONFIG_SIBYTE_SB1250_PROF is not set
+# CONFIG_SIBYTE_TBPROF is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_COHERENT=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_BOOT_ELF32=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+CONFIG_CPU_SB1=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+# CONFIG_SIBYTE_DMA_PAGEOPS is not set
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_SB1_PASS_1_WORKAROUNDS=y
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_HIGHMEM is not set
+CONFIG_SMP=y
+CONFIG_NR_CPUS=2
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=9220
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# 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_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_IDETAPE=y
+CONFIG_BLK_DEV_IDEFLOPPY=y
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_IDEPCI is not set
+CONFIG_BLK_DEV_IDE_SWARM=y
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+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=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+CONFIG_NET_SB1250_MAC=y
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Userland interfaces
+#
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+
+#
+# Input Device Drivers
+#
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_ROCKETPORT is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+# CONFIG_SYNCLINK is not set
+# CONFIG_SYNCLINKMP is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_STALDRV is not set
+CONFIG_SIBYTE_SB1250_DUART=y
+CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVPTS_FS_XATTR is not set
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# 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_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+# CONFIG_SB1XXX_CORELIS is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_TEA=m
+# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig
new file mode 100644
index 0000000..7c718a4
--- /dev/null
+++ b/arch/mips/configs/sead_defconfig
@@ -0,0 +1,493 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:10 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+CONFIG_MIPS_SEAD=y
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_MIPS_BOARDS_GEN=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=18432
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=y
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Networking support
+#
+# CONFIG_NET is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=y
+
+#
+# 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_UNIX98_PTYS is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC32 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig
new file mode 100644
index 0000000..e01727c
--- /dev/null
+++ b/arch/mips/configs/tb0226_defconfig
@@ -0,0 +1,763 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:12 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+CONFIG_MACH_VR41XX=y
+# CONFIG_NEC_CMBVR4133 is not set
+# CONFIG_CASIO_E55 is not set
+# CONFIG_IBM_WORKPAD is not set
+CONFIG_TANBAC_TB0226=y
+# CONFIG_TANBAC_TB0229 is not set
+# CONFIG_VICTOR_MPC30X is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+CONFIG_CPU_VR41XX=y
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+# CONFIG_PCI is not set
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=m
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# 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_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+CONFIG_BLK_DEV_IDESCSI=y
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=y
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK_DEV=m
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input 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
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+
+#
+# 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+
+#
+# Logo configuration
+#
+# CONFIG_LOGO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+# CONFIG_SND is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+CONFIG_ROMFS_FS=m
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_CRAMFS=m
+# 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=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V4 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_SMB_NLS_REMOTE="cp932"
+# 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=m
+# 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=m
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=m
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC32 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/tb0229_defconfig b/arch/mips/configs/tb0229_defconfig
new file mode 100644
index 0000000..c6ba3de2
--- /dev/null
+++ b/arch/mips/configs/tb0229_defconfig
@@ -0,0 +1,775 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:12 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+CONFIG_MACH_VR41XX=y
+# CONFIG_NEC_CMBVR4133 is not set
+# CONFIG_CASIO_E55 is not set
+# CONFIG_IBM_WORKPAD is not set
+# CONFIG_TANBAC_TB0226 is not set
+CONFIG_TANBAC_TB0229=y
+CONFIG_TANBAC_TB0219=y
+# CONFIG_VICTOR_MPC30X is not set
+# CONFIG_ZAO_CAPCELLA is not set
+CONFIG_PCI_VR41XX=y
+# CONFIG_VRC4173 is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+CONFIG_CPU_VR41XX=y
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK_DEV=m
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+# CONFIG_NET_IPGRE_BROADCAST is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=y
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+CONFIG_EEPRO100=y
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_LAN_SAA9730 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPPOE=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input 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
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+
+#
+# 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# 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=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+CONFIG_JFS_FS=m
+# CONFIG_JFS_POSIX_ACL is not set
+# CONFIG_JFS_SECURITY is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_XFS_FS=y
+# CONFIG_XFS_RT is not set
+CONFIG_XFS_QUOTA=y
+# CONFIG_XFS_SECURITY is not set
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_MINIX_FS is not set
+CONFIG_ROMFS_FS=m
+# CONFIG_QUOTA is not set
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_CRAMFS=m
+# 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=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V4 is not set
+CONFIG_NFSD_TCP=y
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_SMB_NLS_REMOTE="cp932"
+# 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=m
+# 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=m
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=m
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE="mem=64M console=ttyS0,38400 ip=bootp root=/dev/nfs"
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig
new file mode 100644
index 0000000..915c43b
--- /dev/null
+++ b/arch/mips/configs/workpad_defconfig
@@ -0,0 +1,687 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:12 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+CONFIG_MACH_VR41XX=y
+# CONFIG_NEC_CMBVR4133 is not set
+# CONFIG_CASIO_E55 is not set
+CONFIG_IBM_WORKPAD=y
+# CONFIG_TANBAC_TB0226 is not set
+# CONFIG_TANBAC_TB0229 is not set
+# CONFIG_VICTOR_MPC30X is not set
+# CONFIG_ZAO_CAPCELLA is not set
+CONFIG_VRC4171=y
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+CONFIG_CPU_VR41XX=y
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_ISA=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+CONFIG_PCMCIA_PROBE=y
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# 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_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_IDE_ARM is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input 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
+# CONFIG_SERIO_LIBPS2 is not set
+CONFIG_SERIO_RAW=m
+
+#
+# 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+
+#
+# ISA-based Watchdog Cards
+#
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_WDT is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=y
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_LOCKD=y
+CONFIG_EXPORTFS=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC32 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig
new file mode 100644
index 0000000..562f2b8
--- /dev/null
+++ b/arch/mips/configs/yosemite_defconfig
@@ -0,0 +1,615 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:49:13 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+CONFIG_CLEAN_COMPILE=y
+CONFIG_LOCK_KERNEL=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+CONFIG_PMC_YOSEMITE=y
+# CONFIG_HYPERTRANSPORT is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_COHERENT=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_IRQ_CPU=y
+CONFIG_IRQ_CPU_RM7K=y
+CONFIG_IRQ_CPU_RM9K=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+CONFIG_CPU_RM9000=y
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_HIGHMEM=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=2
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER 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_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=m
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=m
+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 is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+CONFIG_TITAN_GE=y
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Userland interfaces
+#
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+# CONFIG_SERIO is not set
+# CONFIG_SERIO_I8042 is not set
+
+#
+# Input Device Drivers
+#
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+CONFIG_GEN_RTC=y
+CONFIG_GEN_RTC_X=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVPTS_FS_XATTR is not set
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_HFSPLUS_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 is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+# CONFIG_EXPORTFS is not set
+CONFIG_SUNRPC=y
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_HIGHMEM is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_KGDB is not set
+# CONFIG_RUNTIME_DEBUG is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC32 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/ddb5xxx/common/Makefile b/arch/mips/ddb5xxx/common/Makefile
new file mode 100644
index 0000000..bc44e30
--- /dev/null
+++ b/arch/mips/ddb5xxx/common/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the common code of NEC DDB-Vrc5xxx board
+#
+
+obj-y	 += nile4.o prom.o rtc_ds1386.o
diff --git a/arch/mips/ddb5xxx/common/nile4.c b/arch/mips/ddb5xxx/common/nile4.c
new file mode 100644
index 0000000..7ec7d90
--- /dev/null
+++ b/arch/mips/ddb5xxx/common/nile4.c
@@ -0,0 +1,130 @@
+/*
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/ddb5xxx/common/nile4.c
+ *     misc low-level routines for vrc-5xxx controllers.
+ *
+ * derived from original code by Geert Uytterhoeven <geert@sonycom.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+u32
+ddb_calc_pdar(u32 phys, u32 size, int width,
+	      int on_memory_bus, int pci_visible)
+{
+        u32 maskbits;
+        u32 widthbits;
+
+        switch (size) {
+#if 0                           /* We don't support 4 GB yet */
+        case 0x100000000:       /* 4 GB */
+                maskbits = 4;
+                break;
+#endif
+        case 0x80000000:        /* 2 GB */
+                maskbits = 5;
+                break;
+        case 0x40000000:        /* 1 GB */
+                maskbits = 6;
+                break;
+        case 0x20000000:        /* 512 MB */
+                maskbits = 7;
+                break;
+        case 0x10000000:        /* 256 MB */
+                maskbits = 8;
+                break;
+        case 0x08000000:        /* 128 MB */
+                maskbits = 9;
+                break;
+        case 0x04000000:        /* 64 MB */
+                maskbits = 10;
+                break;
+        case 0x02000000:        /* 32 MB */
+                maskbits = 11;
+                break;
+        case 0x01000000:        /* 16 MB */
+                maskbits = 12;
+                break;
+        case 0x00800000:        /* 8 MB */
+                maskbits = 13;
+                break;
+        case 0x00400000:        /* 4 MB */
+                maskbits = 14;
+                break;
+        case 0x00200000:        /* 2 MB */
+                maskbits = 15;
+                break;
+        case 0:         /* OFF */
+                maskbits = 0;
+                break;
+        default:
+                panic("nile4_set_pdar: unsupported size %p", (void *) size);
+        }
+        switch (width) {
+        case 8:
+                widthbits = 0;
+                break;
+        case 16:
+                widthbits = 1;
+                break;
+        case 32:
+                widthbits = 2;
+                break;
+        case 64:
+                widthbits = 3;
+                break;
+        default:
+                panic("nile4_set_pdar: unsupported width %d", width);
+        }
+
+	return maskbits | (on_memory_bus ? 0x10 : 0) |
+		(pci_visible ? 0x20 : 0) | (widthbits << 6) |
+		(phys & 0xffe00000);
+}
+
+void
+ddb_set_pdar(u32 pdar, u32 phys, u32 size, int width,
+	     int on_memory_bus, int pci_visible)
+{
+	u32 temp= ddb_calc_pdar(phys, size, width, on_memory_bus, pci_visible);
+	ddb_out32(pdar, temp);
+	ddb_out32(pdar + 4, 0);
+
+        /*
+         * When programming a PDAR, the register should be read immediately
+         * after writing it. This ensures that address decoders are properly
+         * configured.
+	 * [jsun] is this really necessary?
+         */
+        ddb_in32(pdar);
+        ddb_in32(pdar + 4);
+}
+
+/*
+ * routines that mess with PCIINITx registers
+ */
+
+void ddb_set_pmr(u32 pmr, u32 type, u32 addr, u32 options)
+{
+        switch (type) {
+        case DDB_PCICMD_IACK: /* PCI Interrupt Acknowledge */
+        case DDB_PCICMD_IO:   /* PCI I/O Space */
+        case DDB_PCICMD_MEM:  /* PCI Memory Space */
+        case DDB_PCICMD_CFG:  /* PCI Configuration Space */
+                break;
+        default:
+                panic("nile4_set_pmr: invalid type %d", type);
+        }
+        ddb_out32(pmr, (type << 1) | (addr & 0xffe00000) | options );
+        ddb_out32(pmr + 4, 0);
+}
diff --git a/arch/mips/ddb5xxx/common/prom.c b/arch/mips/ddb5xxx/common/prom.c
new file mode 100644
index 0000000..b8d1f74
--- /dev/null
+++ b/arch/mips/ddb5xxx/common/prom.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/ddb5xxx/ddb5xxx.h>
+#include <asm/debug.h>
+
+const char *get_system_type(void)
+{
+	switch (mips_machtype) {
+	case MACH_NEC_DDB5074:		return "NEC DDB Vrc-5074";
+	case MACH_NEC_DDB5476:		return "NEC DDB Vrc-5476";
+	case MACH_NEC_DDB5477:		return "NEC DDB Vrc-5477";
+	case MACH_NEC_ROCKHOPPER:	return "NEC Rockhopper";
+	case MACH_NEC_ROCKHOPPERII:     return "NEC RockhopperII";
+	default:			return "Unknown NEC board";
+	}
+}
+
+#if defined(CONFIG_DDB5477)
+void ddb5477_runtime_detection(void);
+#endif
+
+/* [jsun@junsun.net] PMON passes arguments in C main() style */
+void __init prom_init(void)
+{
+	int argc = fw_arg0;
+	char **arg = (char**) fw_arg1;
+	int i;
+
+	/* if user passes kernel args, ignore the default one */
+	if (argc > 1)
+		arcs_cmdline[0] = '\0';
+
+	/* arg[0] is "g", the rest is boot parameters */
+	for (i = 1; i < argc; i++) {
+		if (strlen(arcs_cmdline) + strlen(arg[i] + 1)
+		    >= sizeof(arcs_cmdline))
+			break;
+		strcat(arcs_cmdline, arg[i]);
+		strcat(arcs_cmdline, " ");
+	}
+
+	mips_machgroup = MACH_GROUP_NEC_DDB;
+
+#if defined(CONFIG_DDB5074)
+	mips_machtype = MACH_NEC_DDB5074;
+	add_memory_region(0, DDB_SDRAM_SIZE, BOOT_MEM_RAM);
+#elif defined(CONFIG_DDB5476)
+	mips_machtype = MACH_NEC_DDB5476;
+	add_memory_region(0, DDB_SDRAM_SIZE, BOOT_MEM_RAM);
+#elif defined(CONFIG_DDB5477)
+	ddb5477_runtime_detection();
+	add_memory_region(0, board_ram_size, BOOT_MEM_RAM);
+#endif
+}
+
+unsigned long __init prom_free_prom_memory(void)
+{
+	return 0;
+}
+
+#if defined(CONFIG_DDB5477)
+
+#define DEFAULT_LCS1_BASE 0x19000000
+#define TESTVAL1 'K'
+#define TESTVAL2 'S'
+
+int board_ram_size;
+void ddb5477_runtime_detection(void)
+{
+	volatile char *test_offset;
+	char saved_test_byte;
+
+        /* Determine if this is a DDB5477 board, or a BSB-VR0300
+           base board.  We can tell by checking for the location of
+           the NVRAM.  It lives at the beginning of LCS1 on the DDB5477,
+           and the beginning of LCS1 on the BSB-VR0300 is flash memory.
+           The first 2K of the NVRAM are reserved, so don't we'll poke
+           around just after that.
+         */
+
+	/* We can only use the PCI bus to distinquish between
+	   the Rockhopper and RockhopperII backplanes and this must
+	   wait until ddb5477_board_init() in setup.c after the 5477
+	   is initialized.  So, until then handle
+	   both Rockhopper and RockhopperII backplanes as Rockhopper 1
+	 */
+
+        test_offset = (char *)KSEG1ADDR(DEFAULT_LCS1_BASE + 0x800);
+        saved_test_byte = *test_offset;
+
+        *test_offset = TESTVAL1;
+        if (*test_offset != TESTVAL1) {
+                /* We couldn't set our test value, so it must not be NVRAM,
+                   so it's a BSB_VR0300 */
+		mips_machtype = MACH_NEC_ROCKHOPPER;
+        } else {
+                /* We may have gotten lucky, and the TESTVAL1 was already
+                   stored at the test location, so we must check a second
+                   test value */
+                *test_offset = TESTVAL2;
+                if (*test_offset != TESTVAL2) {
+                        /* OK, we couldn't set this value either, so it must
+                           definately be a BSB_VR0300 */
+			mips_machtype = MACH_NEC_ROCKHOPPER;
+                } else {
+                        /* We could change the value twice, so it must be
+                        NVRAM, so it's a DDB_VRC5477 */
+			mips_machtype = MACH_NEC_DDB5477;
+                }
+        }
+        /* Restore the original byte */
+        *test_offset = saved_test_byte;
+
+	/* before we know a better way, we will trust PMON for getting
+	 * RAM size
+	 */
+	board_ram_size = 1 << (36 - (ddb_in32(DDB_SDRAM0) & 0xf));
+
+	db_run(printk("DDB run-time detection : %s, %d MB RAM\n",
+				mips_machtype == MACH_NEC_DDB5477 ?
+				"DDB5477" : "Rockhopper",
+				board_ram_size >> 20));
+
+	/* we can't handle ram size > 128 MB */
+	db_assert(board_ram_size <= (128 << 20));
+}
+#endif
diff --git a/arch/mips/ddb5xxx/common/rtc_ds1386.c b/arch/mips/ddb5xxx/common/rtc_ds1386.c
new file mode 100644
index 0000000..f5b1150
--- /dev/null
+++ b/arch/mips/ddb5xxx/common/rtc_ds1386.c
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/ddb5xxx/common/rtc_ds1386.c
+ *     low-level RTC hookups for s for Dallas 1396 chip.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+
+/*
+ * This file exports a function, rtc_ds1386_init(), which expects an
+ * uncached base address as the argument.  It will set the two function
+ * pointers expected by the MIPS generic timer code.
+ */
+
+#include <linux/types.h>
+#include <linux/time.h>
+#include <linux/bcd.h>
+
+#include <asm/time.h>
+#include <asm/addrspace.h>
+
+#include <asm/mc146818rtc.h>
+#include <asm/debug.h>
+
+#define	EPOCH		2000
+
+#define	READ_RTC(x)	*(volatile unsigned char*)(rtc_base+x)
+#define	WRITE_RTC(x, y)	*(volatile unsigned char*)(rtc_base+x) = y
+
+static unsigned long rtc_base;
+
+static unsigned long
+rtc_ds1386_get_time(void)
+{
+	u8 byte;
+	u8 temp;
+	unsigned int year, month, day, hour, minute, second;
+
+	/* let us freeze external registers */
+	byte = READ_RTC(0xB);
+	byte &= 0x3f;
+	WRITE_RTC(0xB, byte);
+
+	/* read time data */
+	year = BCD2BIN(READ_RTC(0xA)) + EPOCH;
+	month = BCD2BIN(READ_RTC(0x9) & 0x1f);
+	day = BCD2BIN(READ_RTC(0x8));
+	minute = BCD2BIN(READ_RTC(0x2));
+	second = BCD2BIN(READ_RTC(0x1));
+
+	/* hour is special - deal with it later */
+	temp = READ_RTC(0x4);
+
+	/* enable time transfer */
+	byte |= 0x80;
+	WRITE_RTC(0xB, byte);
+
+	/* calc hour */
+	if (temp & 0x40) {
+		/* 12 hour format */
+		hour = BCD2BIN(temp & 0x1f);
+		if (temp & 0x20) hour += 12; 		/* PM */
+	} else {
+		/* 24 hour format */
+		hour = BCD2BIN(temp & 0x3f);
+	}
+
+	return mktime(year, month, day, hour, minute, second);
+}
+
+static int
+rtc_ds1386_set_time(unsigned long t)
+{
+	struct rtc_time tm;
+	u8 byte;
+	u8 temp;
+	u8 year, month, day, hour, minute, second;
+
+	/* let us freeze external registers */
+	byte = READ_RTC(0xB);
+	byte &= 0x3f;
+	WRITE_RTC(0xB, byte);
+
+	/* convert */
+	to_tm(t, &tm);
+
+
+	/* check each field one by one */
+	year = BIN2BCD(tm.tm_year - EPOCH);
+	if (year != READ_RTC(0xA)) {
+		WRITE_RTC(0xA, year);
+	}
+
+	temp = READ_RTC(0x9);
+	month = BIN2BCD(tm.tm_mon+1);	/* tm_mon starts from 0 to 11 */
+	if (month != (temp & 0x1f)) {
+		WRITE_RTC( 0x9,
+			   (month & 0x1f) | (temp & ~0x1f) );
+	}
+
+	day = BIN2BCD(tm.tm_mday);
+	if (day != READ_RTC(0x8)) {
+		WRITE_RTC(0x8, day);
+	}
+
+	temp = READ_RTC(0x4);
+	if (temp & 0x40) {
+		/* 12 hour format */
+		hour = 0x40;
+		if (tm.tm_hour > 12) {
+			hour |= 0x20 | (BIN2BCD(hour-12) & 0x1f);
+		} else {
+			hour |= BIN2BCD(tm.tm_hour);
+		}
+	} else {
+		/* 24 hour format */
+		hour = BIN2BCD(tm.tm_hour) & 0x3f;
+	}
+	if (hour != temp) WRITE_RTC(0x4, hour);
+
+	minute = BIN2BCD(tm.tm_min);
+	if (minute != READ_RTC(0x2)) {
+		WRITE_RTC(0x2, minute);
+	}
+
+	second = BIN2BCD(tm.tm_sec);
+	if (second != READ_RTC(0x1)) {
+		WRITE_RTC(0x1, second);
+	}
+
+	return 0;
+}
+
+void
+rtc_ds1386_init(unsigned long base)
+{
+	unsigned char byte;
+
+	/* remember the base */
+	rtc_base = base;
+	db_assert((rtc_base & 0xe0000000) == KSEG1);
+
+	/* turn on RTC if it is not on */
+	byte = READ_RTC(0x9);
+	if (byte & 0x80) {
+		byte &= 0x7f;
+		WRITE_RTC(0x9, byte);
+	}
+
+	/* enable time transfer */
+	byte = READ_RTC(0xB);
+	byte |= 0x80;
+	WRITE_RTC(0xB, byte);
+
+	/* set the function pointers */
+	rtc_get_time = rtc_ds1386_get_time;
+	rtc_set_time = rtc_ds1386_set_time;
+}
diff --git a/arch/mips/ddb5xxx/ddb5074/Makefile b/arch/mips/ddb5xxx/ddb5074/Makefile
new file mode 100644
index 0000000..488206b
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5074/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the NEC DDB Vrc-5074 specific kernel interface routines
+# under Linux.
+#
+
+obj-y			+= setup.o irq.o int-handler.o nile4_pic.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/ddb5xxx/ddb5074/int-handler.S b/arch/mips/ddb5xxx/ddb5074/int-handler.S
new file mode 100644
index 0000000..a786441
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5074/int-handler.S
@@ -0,0 +1,120 @@
+/*
+ *  arch/mips/ddb5074/int-handler.S -- NEC DDB Vrc-5074 interrupt handler
+ *
+ *  Based on arch/mips/sgi/kernel/indyIRQ.S
+ *
+ *  Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ *
+ *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
+ *                     Sony Software Development Center Europe (SDCE), Brussels
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/* A lot of complication here is taken away because:
+ *
+ * 1) We handle one interrupt and return, sitting in a loop and moving across
+ *    all the pending IRQ bits in the cause register is _NOT_ the answer, the
+ *    common case is one pending IRQ so optimize in that direction.
+ *
+ * 2) We need not check against bits in the status register IRQ mask, that
+ *    would make this routine slow as hell.
+ *
+ * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
+ *    between like BSD spl() brain-damage.
+ *
+ * Furthermore, the IRQs on the INDY look basically (barring software IRQs
+ * which we don't use at all) like:
+ *
+ *	MIPS IRQ	Source
+ *      --------        ------
+ *             0	Software (ignored)
+ *             1        Software (ignored)
+ *             2        Local IRQ level zero
+ *             3        Local IRQ level one
+ *             4        8254 Timer zero
+ *             5        8254 Timer one
+ *             6        Bus Error
+ *             7        R4k timer (what we use)
+ *
+ * We handle the IRQ according to _our_ priority which is:
+ *
+ * Highest ----     R4k Timer
+ *                  Local IRQ zero
+ *                  Local IRQ one
+ *                  Bus Error
+ *                  8254 Timer zero
+ * Lowest  ----     8254 Timer one
+ *
+ * then we just return, if multiple IRQs are pending then we will just take
+ * another exception, big deal.
+ */
+
+	.text
+	.set	noreorder
+	.set	noat
+	.align	5
+	NESTED(ddbIRQ, PT_SIZE, sp)
+	SAVE_ALL
+	CLI
+	.set	at
+	mfc0	s0, CP0_CAUSE		# get irq mask
+
+#if 1
+	mfc0	t2,CP0_STATUS		# get enabled interrupts
+	and	s0,t2			# isolate allowed ones
+#endif
+	/* First we check for r4k counter/timer IRQ. */
+	andi	a0, s0, CAUSEF_IP2	# delay slot, check local level zero
+	beq	a0, zero, 1f
+	 andi	a0, s0, CAUSEF_IP3	# delay slot, check local level one
+
+	/* Wheee, local level zero interrupt. */
+	jal	ddb_local0_irqdispatch
+	 move	a0, sp			# delay slot
+
+	j	ret_from_irq
+	 nop				# delay slot
+
+1:
+	beq	a0, zero, 1f
+	 andi	a0, s0, CAUSEF_IP6	# delay slot, check bus error
+
+	/* Wheee, local level one interrupt. */
+	move	a0, sp
+	jal	ddb_local1_irqdispatch
+	 nop
+
+	j	ret_from_irq
+	 nop
+
+1:
+	beq	a0, zero, 1f
+	 nop
+
+	/* Wheee, an asynchronous bus error... */
+	move	a0, sp
+	jal	ddb_buserror_irq
+	 nop
+
+	j	ret_from_irq
+	 nop
+
+1:
+	/* Here by mistake?  This is possible, what can happen
+	 * is that by the time we take the exception the IRQ
+	 * pin goes low, so just leave if this is the case.
+	 */
+	andi	a0, s0, (CAUSEF_IP4 | CAUSEF_IP5)
+	beq	a0, zero, 1f
+
+	/* Must be one of the 8254 timers... */
+	move	a0, sp
+	jal	ddb_8254timer_irq
+	 nop
+1:
+	j	ret_from_irq
+	 nop
+	END(ddbIRQ)
diff --git a/arch/mips/ddb5xxx/ddb5074/irq.c b/arch/mips/ddb5xxx/ddb5074/irq.c
new file mode 100644
index 0000000..45088a1
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5074/irq.c
@@ -0,0 +1,159 @@
+/*
+ *  arch/mips/ddb5074/irq.c -- NEC DDB Vrc-5074 interrupt routines
+ *
+ *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
+ *                     Sony Software Development Center Europe (SDCE), Brussels
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+
+#include <asm/i8259.h>
+#include <asm/io.h>
+#include <asm/irq_cpu.h>
+#include <asm/ptrace.h>
+#include <asm/nile4.h>
+#include <asm/ddb5xxx/ddb5xxx.h>
+#include <asm/ddb5xxx/ddb5074.h>
+
+
+extern asmlinkage void ddbIRQ(void);
+
+static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL };
+
+#define M1543_PNP_CONFIG	0x03f0	/* PnP Config Port */
+#define M1543_PNP_INDEX		0x03f0	/* PnP Index Port */
+#define M1543_PNP_DATA		0x03f1	/* PnP Data Port */
+
+#define M1543_PNP_ALT_CONFIG	0x0370	/* Alternative PnP Config Port */
+#define M1543_PNP_ALT_INDEX	0x0370	/* Alternative PnP Index Port */
+#define M1543_PNP_ALT_DATA	0x0371	/* Alternative PnP Data Port */
+
+#define M1543_INT1_MASTER_CTRL	0x0020	/* INT_1 (master) Control Register */
+#define M1543_INT1_MASTER_MASK	0x0021	/* INT_1 (master) Mask Register */
+
+#define M1543_INT1_SLAVE_CTRL	0x00a0	/* INT_1 (slave) Control Register */
+#define M1543_INT1_SLAVE_MASK	0x00a1	/* INT_1 (slave) Mask Register */
+
+#define M1543_INT1_MASTER_ELCR	0x04d0	/* INT_1 (master) Edge/Level Control */
+#define M1543_INT1_SLAVE_ELCR	0x04d1	/* INT_1 (slave) Edge/Level Control */
+
+
+static void m1543_irq_setup(void)
+{
+	/*
+	 *  The ALI M1543 has 13 interrupt inputs, IRQ1..IRQ13.  Not all
+	 *  the possible IO sources in the M1543 are in use by us.  We will
+	 *  use the following mapping:
+	 *
+	 *      IRQ1  - keyboard (default set by M1543)
+	 *      IRQ3  - reserved for UART B (default set by M1543) (note that
+	 *              the schematics for the DDB Vrc-5074 board seem to
+	 *              indicate that IRQ3 is connected to the DS1386
+	 *              watchdog timer interrupt output so we might have
+	 *              a conflict)
+	 *      IRQ4  - reserved for UART A (default set by M1543)
+	 *      IRQ5  - parallel (default set by M1543)
+	 *      IRQ8  - DS1386 time of day (RTC) interrupt
+	 *      IRQ12 - mouse
+	 */
+
+	/*
+	 *  Assing mouse interrupt to IRQ12
+	 */
+
+	/* Enter configuration mode */
+	outb(0x51, M1543_PNP_CONFIG);
+	outb(0x23, M1543_PNP_CONFIG);
+
+	/* Select logical device 7 (Keyboard) */
+	outb(0x07, M1543_PNP_INDEX);
+	outb(0x07, M1543_PNP_DATA);
+
+	/* Select IRQ12 */
+	outb(0x72, M1543_PNP_INDEX);
+	outb(0x0c, M1543_PNP_DATA);
+
+	outb(0x30, M1543_PNP_INDEX);
+	printk("device 7, 0x30: %02x\n",inb(M1543_PNP_DATA));
+
+	outb(0x70, M1543_PNP_INDEX);
+	printk("device 7, 0x70: %02x\n",inb(M1543_PNP_DATA));
+
+	/* Leave configration mode */
+	outb(0xbb, M1543_PNP_CONFIG);
+
+
+}
+
+void ddb_local0_irqdispatch(struct pt_regs *regs)
+{
+	u32 mask;
+	int nile4_irq;
+
+	mask = nile4_get_irq_stat(0);
+
+	/* Handle the timer interrupt first */
+#if 0
+	if (mask & (1 << NILE4_INT_GPT)) {
+		do_IRQ(nile4_to_irq(NILE4_INT_GPT), regs);
+		mask &= ~(1 << NILE4_INT_GPT);
+	}
+#endif
+	for (nile4_irq = 0; mask; nile4_irq++, mask >>= 1)
+		if (mask & 1) {
+			if (nile4_irq == NILE4_INT_INTE) {
+				int i8259_irq;
+
+				nile4_clear_irq(NILE4_INT_INTE);
+				i8259_irq = nile4_i8259_iack();
+				do_IRQ(i8259_irq, regs);
+			} else
+				do_IRQ(nile4_to_irq(nile4_irq), regs);
+
+		}
+}
+
+void ddb_local1_irqdispatch(void)
+{
+	printk("ddb_local1_irqdispatch called\n");
+}
+
+void ddb_buserror_irq(void)
+{
+	printk("ddb_buserror_irq called\n");
+}
+
+void ddb_8254timer_irq(void)
+{
+	printk("ddb_8254timer_irq called\n");
+}
+
+void __init arch_init_irq(void)
+{
+	/* setup cascade interrupts */
+	setup_irq(NILE4_IRQ_BASE  + NILE4_INT_INTE, &irq_cascade);
+	setup_irq(CPU_IRQ_BASE + CPU_NILE4_CASCADE, &irq_cascade);
+
+	set_except_vector(0, ddbIRQ);
+
+	nile4_irq_setup(NILE4_IRQ_BASE);
+	m1543_irq_setup();
+	init_i8259_irqs();
+
+
+	printk("CPU_IRQ_BASE: %d\n",CPU_IRQ_BASE);
+
+	mips_cpu_irq_init(CPU_IRQ_BASE);
+
+	printk("enabling 8259 cascade\n");
+
+	ddb5074_led_hex(0);
+
+	/* Enable the interrupt cascade */
+	nile4_enable_irq(NILE4_IRQ_BASE+IRQ_I8259_CASCADE);
+}
diff --git a/arch/mips/ddb5xxx/ddb5074/nile4_pic.c b/arch/mips/ddb5xxx/ddb5074/nile4_pic.c
new file mode 100644
index 0000000..68c127c
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5074/nile4_pic.c
@@ -0,0 +1,287 @@
+/*
+ *  arch/mips/ddb5476/nile4.c --
+ *  	low-level PIC code for NEC Vrc-5476 (Nile 4)
+ *
+ *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
+ *                     Sony Software Development Center Europe (SDCE), Brussels
+ *
+ *  Copyright 2001 MontaVista Software Inc.
+ *  Author: jsun@mvista.com or jsun@junsun.net
+ *
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+
+#include <asm/addrspace.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+static int irq_base;
+
+/*
+ *  Interrupt Programming
+ */
+void nile4_map_irq(int nile4_irq, int cpu_irq)
+{
+	u32 offset, t;
+
+	offset = DDB_INTCTRL;
+	if (nile4_irq >= 8) {
+		offset += 4;
+		nile4_irq -= 8;
+	}
+	t = ddb_in32(offset);
+	t &= ~(7 << (nile4_irq * 4));
+	t |= cpu_irq << (nile4_irq * 4);
+	ddb_out32(offset, t);
+}
+
+void nile4_map_irq_all(int cpu_irq)
+{
+	u32 all, t;
+
+	all = cpu_irq;
+	all |= all << 4;
+	all |= all << 8;
+	all |= all << 16;
+	t = ddb_in32(DDB_INTCTRL);
+	t &= 0x88888888;
+	t |= all;
+	ddb_out32(DDB_INTCTRL, t);
+	t = ddb_in32(DDB_INTCTRL + 4);
+	t &= 0x88888888;
+	t |= all;
+	ddb_out32(DDB_INTCTRL + 4, t);
+}
+
+void nile4_enable_irq(unsigned int nile4_irq)
+{
+	u32 offset, t;
+
+	nile4_irq-=irq_base;
+
+	ddb5074_led_hex(8);
+
+	offset = DDB_INTCTRL;
+	if (nile4_irq >= 8) {
+		offset += 4;
+		nile4_irq -= 8;
+	}
+	ddb5074_led_hex(9);
+	t = ddb_in32(offset);
+	ddb5074_led_hex(0xa);
+	t |= 8 << (nile4_irq * 4);
+	ddb_out32(offset, t);
+	ddb5074_led_hex(0xb);
+}
+
+void nile4_disable_irq(unsigned int nile4_irq)
+{
+	u32 offset, t;
+
+	nile4_irq-=irq_base;
+
+	offset = DDB_INTCTRL;
+	if (nile4_irq >= 8) {
+		offset += 4;
+		nile4_irq -= 8;
+	}
+	t = ddb_in32(offset);
+	t &= ~(8 << (nile4_irq * 4));
+	ddb_out32(offset, t);
+}
+
+void nile4_disable_irq_all(void)
+{
+	ddb_out32(DDB_INTCTRL, 0);
+	ddb_out32(DDB_INTCTRL + 4, 0);
+}
+
+u16 nile4_get_irq_stat(int cpu_irq)
+{
+	return ddb_in16(DDB_INTSTAT0 + cpu_irq * 2);
+}
+
+void nile4_enable_irq_output(int cpu_irq)
+{
+	u32 t;
+
+	t = ddb_in32(DDB_INTSTAT1 + 4);
+	t |= 1 << (16 + cpu_irq);
+	ddb_out32(DDB_INTSTAT1, t);
+}
+
+void nile4_disable_irq_output(int cpu_irq)
+{
+	u32 t;
+
+	t = ddb_in32(DDB_INTSTAT1 + 4);
+	t &= ~(1 << (16 + cpu_irq));
+	ddb_out32(DDB_INTSTAT1, t);
+}
+
+void nile4_set_pci_irq_polarity(int pci_irq, int high)
+{
+	u32 t;
+
+	t = ddb_in32(DDB_INTPPES);
+	if (high)
+		t &= ~(1 << (pci_irq * 2));
+	else
+		t |= 1 << (pci_irq * 2);
+	ddb_out32(DDB_INTPPES, t);
+}
+
+void nile4_set_pci_irq_level_or_edge(int pci_irq, int level)
+{
+	u32 t;
+
+	t = ddb_in32(DDB_INTPPES);
+	if (level)
+		t |= 2 << (pci_irq * 2);
+	else
+		t &= ~(2 << (pci_irq * 2));
+	ddb_out32(DDB_INTPPES, t);
+}
+
+void nile4_clear_irq(int nile4_irq)
+{
+	nile4_irq-=irq_base;
+	ddb_out32(DDB_INTCLR, 1 << nile4_irq);
+}
+
+void nile4_clear_irq_mask(u32 mask)
+{
+	ddb_out32(DDB_INTCLR, mask);
+}
+
+u8 nile4_i8259_iack(void)
+{
+	u8 irq;
+	u32 reg;
+
+	/* Set window 0 for interrupt acknowledge */
+	reg = ddb_in32(DDB_PCIINIT0);
+
+	ddb_set_pmr(DDB_PCIINIT0, DDB_PCICMD_IACK, 0, DDB_PCI_ACCESS_32);
+	irq = *(volatile u8 *) KSEG1ADDR(DDB_PCI_IACK_BASE);
+	/* restore window 0 for PCI I/O space */
+	// ddb_set_pmr(DDB_PCIINIT0, DDB_PCICMD_IO, 0, DDB_PCI_ACCESS_32);
+	ddb_out32(DDB_PCIINIT0, reg);
+
+	/* i8269.c set the base vector to be 0x0 */
+	return irq ;
+}
+
+static unsigned int nile4_irq_startup(unsigned int irq) {
+
+	nile4_enable_irq(irq);
+	return 0;
+
+}
+
+static void nile4_ack_irq(unsigned int irq) {
+
+    ddb5074_led_hex(4);
+
+	nile4_clear_irq(irq);
+    ddb5074_led_hex(2);
+	nile4_disable_irq(irq);
+
+    ddb5074_led_hex(0);
+}
+
+static void nile4_irq_end(unsigned int irq) {
+
+	ddb5074_led_hex(3);
+	if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+	ddb5074_led_hex(5);
+		nile4_enable_irq(irq);
+	ddb5074_led_hex(7);
+	}
+
+	ddb5074_led_hex(1);
+}
+
+#define nile4_irq_shutdown nile4_disable_irq
+
+static hw_irq_controller nile4_irq_controller = {
+    "nile4",
+    nile4_irq_startup,
+    nile4_irq_shutdown,
+    nile4_enable_irq,
+    nile4_disable_irq,
+    nile4_ack_irq,
+    nile4_irq_end,
+    NULL
+};
+
+void nile4_irq_setup(u32 base) {
+
+	int i;
+
+	irq_base=base;
+
+	/* Map all interrupts to CPU int #0 */
+	nile4_map_irq_all(0);
+
+	/* PCI INTA#-E# must be level triggered */
+	nile4_set_pci_irq_level_or_edge(0, 1);
+	nile4_set_pci_irq_level_or_edge(1, 1);
+	nile4_set_pci_irq_level_or_edge(2, 1);
+	nile4_set_pci_irq_level_or_edge(3, 1);
+	nile4_set_pci_irq_level_or_edge(4, 1);
+
+	/* PCI INTA#-D# must be active low, INTE# must be active high */
+	nile4_set_pci_irq_polarity(0, 0);
+	nile4_set_pci_irq_polarity(1, 0);
+	nile4_set_pci_irq_polarity(2, 0);
+	nile4_set_pci_irq_polarity(3, 0);
+	nile4_set_pci_irq_polarity(4, 1);
+
+
+	for (i = 0; i < 16; i++) {
+		nile4_clear_irq(i);
+		nile4_disable_irq(i);
+	}
+
+	/* Enable CPU int #0 */
+	nile4_enable_irq_output(0);
+
+	for (i= base; i< base + NUM_NILE4_INTERRUPTS; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &nile4_irq_controller;
+	}
+}
+
+#if defined(CONFIG_RUNTIME_DEBUG)
+void nile4_dump_irq_status(void)
+{
+	printk(KERN_DEBUG "
+	       CPUSTAT = %p:%p\n", (void *) ddb_in32(DDB_CPUSTAT + 4),
+	       (void *) ddb_in32(DDB_CPUSTAT));
+	printk(KERN_DEBUG "
+	       INTCTRL = %p:%p\n", (void *) ddb_in32(DDB_INTCTRL + 4),
+	       (void *) ddb_in32(DDB_INTCTRL));
+	printk(KERN_DEBUG
+	       "INTSTAT0 = %p:%p\n",
+	       (void *) ddb_in32(DDB_INTSTAT0 + 4),
+	       (void *) ddb_in32(DDB_INTSTAT0));
+	printk(KERN_DEBUG
+	       "INTSTAT1 = %p:%p\n",
+	       (void *) ddb_in32(DDB_INTSTAT1 + 4),
+	       (void *) ddb_in32(DDB_INTSTAT1));
+	printk(KERN_DEBUG
+	       "INTCLR = %p:%p\n", (void *) ddb_in32(DDB_INTCLR + 4),
+	       (void *) ddb_in32(DDB_INTCLR));
+	printk(KERN_DEBUG
+	       "INTPPES = %p:%p\n", (void *) ddb_in32(DDB_INTPPES + 4),
+	       (void *) ddb_in32(DDB_INTPPES));
+}
+
+#endif
diff --git a/arch/mips/ddb5xxx/ddb5074/setup.c b/arch/mips/ddb5xxx/ddb5074/setup.c
new file mode 100644
index 0000000..a73a597
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5074/setup.c
@@ -0,0 +1,235 @@
+/*
+ *  arch/mips/ddb5074/setup.c -- NEC DDB Vrc-5074 setup routines
+ *
+ *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
+ *                     Sony Software Development Center Europe (SDCE), Brussels
+ */
+#include <linux/init.h>
+#include <linux/kbd_ll.h>
+#include <linux/kernel.h>
+#include <linux/kdev_t.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/ide.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+
+#include <asm/addrspace.h>
+#include <asm/bcache.h>
+#include <asm/irq.h>
+#include <asm/reboot.h>
+#include <asm/gdb-stub.h>
+#include <asm/time.h>
+#include <asm/nile4.h>
+#include <asm/ddb5xxx/ddb5074.h>
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+static void (*back_to_prom) (void) = (void (*)(void)) 0xbfc00000;
+
+static void ddb_machine_restart(char *command)
+{
+	u32 t;
+
+	/* PCI cold reset */
+	t = nile4_in32(NILE4_PCICTRL + 4);
+	t |= 0x40000000;
+	nile4_out32(NILE4_PCICTRL + 4, t);
+	/* CPU cold reset */
+	t = nile4_in32(NILE4_CPUSTAT);
+	t |= 1;
+	nile4_out32(NILE4_CPUSTAT, t);
+	/* Call the PROM */
+	back_to_prom();
+}
+
+static void ddb_machine_halt(void)
+{
+	printk("DDB Vrc-5074 halted.\n");
+	do {
+	} while (1);
+}
+
+static void ddb_machine_power_off(void)
+{
+	printk("DDB Vrc-5074 halted. Please turn off the power.\n");
+	do {
+	} while (1);
+}
+
+extern void rtc_ds1386_init(unsigned long base);
+
+extern void (*board_timer_setup) (struct irqaction * irq);
+
+static void __init ddb_timer_init(struct irqaction *irq)
+{
+	/* set the clock to 1 Hz */
+	nile4_out32(NILE4_T2CTRL, 1000000);
+	/* enable the General-Purpose Timer */
+	nile4_out32(NILE4_T2CTRL + 4, 0x00000001);
+	/* reset timer */
+	nile4_out32(NILE4_T2CNTR, 0);
+	/* enable interrupt */
+	setup_irq(nile4_to_irq(NILE4_INT_GPT), irq);
+	nile4_enable_irq(nile4_to_irq(NILE4_INT_GPT));
+	change_c0_status(ST0_IM,
+		          IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4);
+
+}
+
+static void __init ddb_time_init(void)
+{
+	/* we have ds1396 RTC chip */
+	rtc_ds1386_init(KSEG1ADDR(DDB_PCI_MEM_BASE));
+}
+
+
+
+static void __init ddb5074_setup(void)
+{
+	set_io_port_base(NILE4_PCI_IO_BASE);
+	isa_slot_offset = NILE4_PCI_MEM_BASE;
+	board_timer_setup = ddb_timer_init;
+	board_time_init = ddb_time_init;
+
+
+	_machine_restart = ddb_machine_restart;
+	_machine_halt = ddb_machine_halt;
+	_machine_power_off = ddb_machine_power_off;
+
+	ddb_out32(DDB_BAR0, 0);
+
+	ddb_set_pmr(DDB_PCIINIT0, DDB_PCICMD_IO, 0, 0x10);
+	ddb_set_pmr(DDB_PCIINIT1, DDB_PCICMD_MEM, DDB_PCI_MEM_BASE , 0x10);
+
+	/* Reboot on panic */
+	panic_timeout = 180;
+}
+
+early_initcall(ddb5074_setup);
+
+#define USE_NILE4_SERIAL	0
+
+#if USE_NILE4_SERIAL
+#define ns16550_in(reg)		nile4_in8((reg)*8)
+#define ns16550_out(reg, val)	nile4_out8((reg)*8, (val))
+#else
+#define NS16550_BASE		(NILE4_PCI_IO_BASE+0x03f8)
+static inline u8 ns16550_in(u32 reg)
+{
+	return *(volatile u8 *) (NS16550_BASE + reg);
+}
+
+static inline void ns16550_out(u32 reg, u8 val)
+{
+	*(volatile u8 *) (NS16550_BASE + reg) = val;
+}
+#endif
+
+#define NS16550_RBR		0
+#define NS16550_THR		0
+#define NS16550_DLL		0
+#define NS16550_IER		1
+#define NS16550_DLM		1
+#define NS16550_FCR		2
+#define NS16550_IIR		2
+#define NS16550_LCR		3
+#define NS16550_MCR		4
+#define NS16550_LSR		5
+#define NS16550_MSR		6
+#define NS16550_SCR		7
+
+#define NS16550_LSR_DR		0x01	/* Data ready */
+#define NS16550_LSR_OE		0x02	/* Overrun */
+#define NS16550_LSR_PE		0x04	/* Parity error */
+#define NS16550_LSR_FE		0x08	/* Framing error */
+#define NS16550_LSR_BI		0x10	/* Break */
+#define NS16550_LSR_THRE	0x20	/* Xmit holding register empty */
+#define NS16550_LSR_TEMT	0x40	/* Xmitter empty */
+#define NS16550_LSR_ERR		0x80	/* Error */
+
+
+void _serinit(void)
+{
+#if USE_NILE4_SERIAL
+	ns16550_out(NS16550_LCR, 0x80);
+	ns16550_out(NS16550_DLM, 0x00);
+	ns16550_out(NS16550_DLL, 0x36);	/* 9600 baud */
+	ns16550_out(NS16550_LCR, 0x00);
+	ns16550_out(NS16550_LCR, 0x03);
+	ns16550_out(NS16550_FCR, 0x47);
+#else
+	/* done by PMON */
+#endif
+}
+
+void _putc(char c)
+{
+	while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_THRE));
+	ns16550_out(NS16550_THR, c);
+	if (c == '\n') {
+		while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_THRE));
+		ns16550_out(NS16550_THR, '\r');
+	}
+}
+
+void _puts(const char *s)
+{
+	char c;
+	while ((c = *s++))
+		_putc(c);
+}
+
+char _getc(void)
+{
+	while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_DR));
+	return ns16550_in(NS16550_RBR);
+}
+
+int _testc(void)
+{
+	return (ns16550_in(NS16550_LSR) & NS16550_LSR_DR) != 0;
+}
+
+
+/*
+ *  Hexadecimal 7-segment LED
+ */
+void ddb5074_led_hex(int hex)
+{
+	outb(hex, 0x80);
+}
+
+
+/*
+ *  LEDs D2 and D3, connected to the GPIO pins of the PMU in the ALi M1543
+ */
+struct pci_dev *pci_pmu = NULL;
+
+void ddb5074_led_d2(int on)
+{
+	u8 t;
+
+	if (pci_pmu) {
+		pci_read_config_byte(pci_pmu, 0x7e, &t);
+		if (on)
+			t &= 0x7f;
+		else
+			t |= 0x80;
+		pci_write_config_byte(pci_pmu, 0x7e, t);
+	}
+}
+
+void ddb5074_led_d3(int on)
+{
+	u8 t;
+
+	if (pci_pmu) {
+		pci_read_config_byte(pci_pmu, 0x7e, &t);
+		if (on)
+			t &= 0xbf;
+		else
+			t |= 0x40;
+		pci_write_config_byte(pci_pmu, 0x7e, t);
+	}
+}
diff --git a/arch/mips/ddb5xxx/ddb5476/Makefile b/arch/mips/ddb5xxx/ddb5476/Makefile
new file mode 100644
index 0000000..61eec36
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5476/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for the NEC DDB Vrc-5476 specific kernel interface routines
+# under Linux.
+#
+
+obj-y			+= setup.o irq.o int-handler.o nile4_pic.o vrc5476_irq.o
+obj-$(CONFIG_KGDB)	+= dbg_io.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/ddb5xxx/ddb5476/dbg_io.c b/arch/mips/ddb5xxx/ddb5476/dbg_io.c
new file mode 100644
index 0000000..85e9e50
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5476/dbg_io.c
@@ -0,0 +1,136 @@
+/*
+ * kgdb io functions for DDB5476.  We use the second serial port.
+ *
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+/* ======================= CONFIG ======================== */
+
+/* [jsun] we use the second serial port for kdb */
+#define         BASE                    0xa60002f8
+#define         MAX_BAUD                115200
+
+/* distance in bytes between two serial registers */
+#define         REG_OFFSET              1
+
+/*
+ * 0 - kgdb does serial init
+ * 1 - kgdb skip serial init
+ */
+static int remoteDebugInitialized = 0;
+
+/*
+ * the default baud rate *if* kgdb does serial init
+ */
+#define		BAUD_DEFAULT		UART16550_BAUD_38400
+
+/* ======================= END OF CONFIG ======================== */
+
+typedef unsigned char uint8;
+typedef unsigned int uint32;
+
+#define         UART16550_BAUD_2400             2400
+#define         UART16550_BAUD_4800             4800
+#define         UART16550_BAUD_9600             9600
+#define         UART16550_BAUD_19200            19200
+#define         UART16550_BAUD_38400            38400
+#define         UART16550_BAUD_57600            57600
+#define         UART16550_BAUD_115200           115200
+
+#define         UART16550_PARITY_NONE           0
+#define         UART16550_PARITY_ODD            0x08
+#define         UART16550_PARITY_EVEN           0x18
+#define         UART16550_PARITY_MARK           0x28
+#define         UART16550_PARITY_SPACE          0x38
+
+#define         UART16550_DATA_5BIT             0x0
+#define         UART16550_DATA_6BIT             0x1
+#define         UART16550_DATA_7BIT             0x2
+#define         UART16550_DATA_8BIT             0x3
+
+#define         UART16550_STOP_1BIT             0x0
+#define         UART16550_STOP_2BIT             0x4
+
+/* register offset */
+#define         OFS_RCV_BUFFER          0
+#define         OFS_TRANS_HOLD          0
+#define         OFS_SEND_BUFFER         0
+#define         OFS_INTR_ENABLE         (1*REG_OFFSET)
+#define         OFS_INTR_ID             (2*REG_OFFSET)
+#define         OFS_DATA_FORMAT         (3*REG_OFFSET)
+#define         OFS_LINE_CONTROL        (3*REG_OFFSET)
+#define         OFS_MODEM_CONTROL       (4*REG_OFFSET)
+#define         OFS_RS232_OUTPUT        (4*REG_OFFSET)
+#define         OFS_LINE_STATUS         (5*REG_OFFSET)
+#define         OFS_MODEM_STATUS        (6*REG_OFFSET)
+#define         OFS_RS232_INPUT         (6*REG_OFFSET)
+#define         OFS_SCRATCH_PAD         (7*REG_OFFSET)
+
+#define         OFS_DIVISOR_LSB         (0*REG_OFFSET)
+#define         OFS_DIVISOR_MSB         (1*REG_OFFSET)
+
+
+/* memory-mapped read/write of the port */
+#define         UART16550_READ(y)    (*((volatile uint8*)(BASE + y)))
+#define         UART16550_WRITE(y, z)  ((*((volatile uint8*)(BASE + y))) = z)
+
+void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
+{
+        /* disable interrupts */
+        UART16550_WRITE(OFS_INTR_ENABLE, 0);
+
+        /* set up buad rate */
+        {
+                uint32 divisor;
+
+                /* set DIAB bit */
+                UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
+
+                /* set divisor */
+                divisor = MAX_BAUD / baud;
+                UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
+                UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
+
+                /* clear DIAB bit */
+                UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
+        }
+
+        /* set data format */
+        UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
+}
+
+
+uint8 getDebugChar(void)
+{
+        if (!remoteDebugInitialized) {
+                remoteDebugInitialized = 1;
+                debugInit(BAUD_DEFAULT,
+                          UART16550_DATA_8BIT,
+                          UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+        }
+
+        while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
+        return UART16550_READ(OFS_RCV_BUFFER);
+}
+
+
+int putDebugChar(uint8 byte)
+{
+        if (!remoteDebugInitialized) {
+                remoteDebugInitialized = 1;
+                debugInit(BAUD_DEFAULT,
+                          UART16550_DATA_8BIT,
+                          UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+        }
+
+        while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
+        UART16550_WRITE(OFS_SEND_BUFFER, byte);
+        return 1;
+}
diff --git a/arch/mips/ddb5xxx/ddb5476/int-handler.S b/arch/mips/ddb5xxx/ddb5476/int-handler.S
new file mode 100644
index 0000000..12c292e
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5476/int-handler.S
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * First-level interrupt dispatcher for ddb5476
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+#include <asm/ddb5xxx/ddb5476.h>
+
+/*
+ * first level interrupt dispatcher for ocelot board -
+ * We check for the timer first, then check PCI ints A and D.
+ * Then check for serial IRQ and fall through.
+ */
+	.align	5
+	NESTED(ddb5476_handle_int, PT_SIZE, sp)
+	SAVE_ALL
+	CLI
+	.set	at
+	.set	noreorder
+	mfc0	t0, CP0_CAUSE
+	mfc0	t2, CP0_STATUS
+
+	and	t0, t2
+
+        andi    t1, t0, STATUSF_IP7     /* cpu timer */
+        bnez    t1, ll_cpu_ip7
+        andi    t1, t0, STATUSF_IP2	/* vrc5476 & i8259 */
+        bnez    t1, ll_cpu_ip2
+        andi    t1, t0, STATUSF_IP3
+        bnez    t1, ll_cpu_ip3
+        andi    t1, t0, STATUSF_IP4
+        bnez    t1, ll_cpu_ip4
+        andi    t1, t0, STATUSF_IP5
+        bnez    t1, ll_cpu_ip5
+        andi    t1, t0, STATUSF_IP6
+        bnez    t1, ll_cpu_ip6
+        andi    t1, t0, STATUSF_IP0     /* software int 0 */
+        bnez    t1, ll_cpu_ip0
+        andi    t1, t0, STATUSF_IP1     /* software int 1 */
+        bnez    t1, ll_cpu_ip1
+        nop
+
+	.set	reorder
+
+	/* wrong alarm or masked ... */
+	// j	spurious_interrupt
+	move 	a0, sp
+	jal	vrc5476_irq_dispatch
+	j	ret_from_irq
+	nop
+
+	.align	5
+
+ll_cpu_ip0:
+	li	a0, CPU_IRQ_BASE + 0
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+ll_cpu_ip1:
+	li	a0, CPU_IRQ_BASE + 1
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+ll_cpu_ip2:		/* jump to second-level dispatching */
+	move	a0, sp
+	jal	vrc5476_irq_dispatch
+	j	ret_from_irq
+
+ll_cpu_ip3:
+	li	a0, CPU_IRQ_BASE + 3
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+ll_cpu_ip4:
+	li	a0, CPU_IRQ_BASE + 4
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+ll_cpu_ip5:
+	li	a0, CPU_IRQ_BASE + 5
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+ll_cpu_ip6:
+	li	a0, CPU_IRQ_BASE + 6
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+ll_cpu_ip7:
+	li	a0, CPU_IRQ_BASE + 7
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+	END(ddb5476_handle_int)
diff --git a/arch/mips/ddb5xxx/ddb5476/irq.c b/arch/mips/ddb5xxx/ddb5476/irq.c
new file mode 100644
index 0000000..5388b58
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5476/irq.c
@@ -0,0 +1,143 @@
+/*
+ *  arch/mips/ddb5476/irq.c -- NEC DDB Vrc-5476 interrupt routines
+ *
+ *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
+ *                     Sony Software Development Center Europe (SDCE), Brussels
+ *
+ * Re-write the whole thing to use new irq.c file.
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+
+#include <asm/i8259.h>
+#include <asm/io.h>
+#include <asm/ptrace.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+#define M1543_PNP_CONFIG	0x03f0	/* PnP Config Port */
+#define M1543_PNP_INDEX		0x03f0	/* PnP Index Port */
+#define M1543_PNP_DATA		0x03f1	/* PnP Data Port */
+
+#define M1543_PNP_ALT_CONFIG	0x0370	/* Alternative PnP Config Port */
+#define M1543_PNP_ALT_INDEX	0x0370	/* Alternative PnP Index Port */
+#define M1543_PNP_ALT_DATA	0x0371	/* Alternative PnP Data Port */
+
+#define M1543_INT1_MASTER_CTRL	0x0020	/* INT_1 (master) Control Register */
+#define M1543_INT1_MASTER_MASK	0x0021	/* INT_1 (master) Mask Register */
+
+#define M1543_INT1_SLAVE_CTRL	0x00a0	/* INT_1 (slave) Control Register */
+#define M1543_INT1_SLAVE_MASK	0x00a1	/* INT_1 (slave) Mask Register */
+
+#define M1543_INT1_MASTER_ELCR	0x04d0	/* INT_1 (master) Edge/Level Control */
+#define M1543_INT1_SLAVE_ELCR	0x04d1	/* INT_1 (slave) Edge/Level Control */
+
+static void m1543_irq_setup(void)
+{
+	/*
+	 *  The ALI M1543 has 13 interrupt inputs, IRQ1..IRQ13.  Not all
+	 *  the possible IO sources in the M1543 are in use by us.  We will
+	 *  use the following mapping:
+	 *
+	 *      IRQ1  - keyboard (default set by M1543)
+	 *      IRQ3  - reserved for UART B (default set by M1543) (note that
+	 *              the schematics for the DDB Vrc-5476 board seem to
+	 *              indicate that IRQ3 is connected to the DS1386
+	 *              watchdog timer interrupt output so we might have
+	 *              a conflict)
+	 *      IRQ4  - reserved for UART A (default set by M1543)
+	 *      IRQ5  - parallel (default set by M1543)
+	 *      IRQ8  - DS1386 time of day (RTC) interrupt
+	 *      IRQ9  - USB (hardwired in ddb_setup)
+	 *      IRQ10 - PMU (hardwired in ddb_setup)
+	 *      IRQ12 - mouse
+	 *      IRQ14,15 - IDE controller (need to be confirmed, jsun)
+	 */
+
+	/*
+	 *  Assing mouse interrupt to IRQ12
+	 */
+
+	/* Enter configuration mode */
+	outb(0x51, M1543_PNP_CONFIG);
+	outb(0x23, M1543_PNP_CONFIG);
+
+	/* Select logical device 7 (Keyboard) */
+	outb(0x07, M1543_PNP_INDEX);
+	outb(0x07, M1543_PNP_DATA);
+
+	/* Select IRQ12 */
+	outb(0x72, M1543_PNP_INDEX);
+	outb(0x0c, M1543_PNP_DATA);
+
+	/* Leave configration mode */
+	outb(0xbb, M1543_PNP_CONFIG);
+}
+
+static void nile4_irq_setup(void)
+{
+	int i;
+
+	/* Map all interrupts to CPU int #0 (IP2) */
+	nile4_map_irq_all(0);
+
+	/* PCI INTA#-E# must be level triggered */
+	nile4_set_pci_irq_level_or_edge(0, 1);
+	nile4_set_pci_irq_level_or_edge(1, 1);
+	nile4_set_pci_irq_level_or_edge(2, 1);
+	nile4_set_pci_irq_level_or_edge(3, 1);
+
+	/* PCI INTA#, B#, D# must be active low, INTC# must be active high */
+	nile4_set_pci_irq_polarity(0, 0);
+	nile4_set_pci_irq_polarity(1, 0);
+	nile4_set_pci_irq_polarity(2, 1);
+	nile4_set_pci_irq_polarity(3, 0);
+
+	for (i = 0; i < 16; i++)
+		nile4_clear_irq(i);
+
+	/* Enable CPU int #0 */
+	nile4_enable_irq_output(0);
+
+	/* memory resource acquire in ddb_setup */
+}
+
+static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL };
+static struct irqaction irq_error = { no_action, 0, CPU_MASK_NONE, "error", NULL, NULL };
+
+extern asmlinkage void ddb5476_handle_int(void);
+extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
+extern void mips_cpu_irq_init(u32 irq_base);
+extern void vrc5476_irq_init(u32 irq_base);
+
+void __init arch_init_irq(void)
+{
+	/* hardware initialization */
+	nile4_irq_setup();
+	m1543_irq_setup();
+
+	/* controller setup */
+	init_i8259_irqs();
+	vrc5476_irq_init(VRC5476_IRQ_BASE);
+	mips_cpu_irq_init(CPU_IRQ_BASE);
+
+	/* setup cascade interrupts */
+	setup_irq(VRC5476_IRQ_BASE + VRC5476_I8259_CASCADE, &irq_cascade);
+	setup_irq(CPU_IRQ_BASE + CPU_VRC5476_CASCADE, &irq_cascade);
+
+	/* setup error interrupts for debugging */
+	setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_CPCE, &irq_error);
+	setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_CNTD, &irq_error);
+	setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_MCE, &irq_error);
+	setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_LBRT, &irq_error);
+	setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCIS, &irq_error);
+	setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCI, &irq_error);
+
+	/* setup the grandpa intr vector */
+	set_except_vector(0, ddb5476_handle_int);
+}
diff --git a/arch/mips/ddb5xxx/ddb5476/nile4_pic.c b/arch/mips/ddb5xxx/ddb5476/nile4_pic.c
new file mode 100644
index 0000000..e930cee
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5476/nile4_pic.c
@@ -0,0 +1,190 @@
+/*
+ *  arch/mips/ddb5476/nile4.c --
+ *  	low-level PIC code for NEC Vrc-5476 (Nile 4)
+ *
+ *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
+ *                     Sony Software Development Center Europe (SDCE), Brussels
+ *
+ *  Copyright 2001 MontaVista Software Inc.
+ *  Author: jsun@mvista.com or jsun@junsun.net
+ *
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+
+/*
+ *  Interrupt Programming
+ */
+void nile4_map_irq(int nile4_irq, int cpu_irq)
+{
+	u32 offset, t;
+
+	offset = DDB_INTCTRL;
+	if (nile4_irq >= 8) {
+		offset += 4;
+		nile4_irq -= 8;
+	}
+	t = ddb_in32(offset);
+	t &= ~(7 << (nile4_irq * 4));
+	t |= cpu_irq << (nile4_irq * 4);
+	ddb_out32(offset, t);
+}
+
+void nile4_map_irq_all(int cpu_irq)
+{
+	u32 all, t;
+
+	all = cpu_irq;
+	all |= all << 4;
+	all |= all << 8;
+	all |= all << 16;
+	t = ddb_in32(DDB_INTCTRL);
+	t &= 0x88888888;
+	t |= all;
+	ddb_out32(DDB_INTCTRL, t);
+	t = ddb_in32(DDB_INTCTRL + 4);
+	t &= 0x88888888;
+	t |= all;
+	ddb_out32(DDB_INTCTRL + 4, t);
+}
+
+void nile4_enable_irq(int nile4_irq)
+{
+	u32 offset, t;
+
+	offset = DDB_INTCTRL;
+	if (nile4_irq >= 8) {
+		offset += 4;
+		nile4_irq -= 8;
+	}
+	t = ddb_in32(offset);
+	t |= 8 << (nile4_irq * 4);
+	ddb_out32(offset, t);
+}
+
+void nile4_disable_irq(int nile4_irq)
+{
+	u32 offset, t;
+
+	offset = DDB_INTCTRL;
+	if (nile4_irq >= 8) {
+		offset += 4;
+		nile4_irq -= 8;
+	}
+	t = ddb_in32(offset);
+	t &= ~(8 << (nile4_irq * 4));
+	ddb_out32(offset, t);
+}
+
+void nile4_disable_irq_all(void)
+{
+	ddb_out32(DDB_INTCTRL, 0);
+	ddb_out32(DDB_INTCTRL + 4, 0);
+}
+
+u16 nile4_get_irq_stat(int cpu_irq)
+{
+	return ddb_in16(DDB_INTSTAT0 + cpu_irq * 2);
+}
+
+void nile4_enable_irq_output(int cpu_irq)
+{
+	u32 t;
+
+	t = ddb_in32(DDB_INTSTAT1 + 4);
+	t |= 1 << (16 + cpu_irq);
+	ddb_out32(DDB_INTSTAT1, t);
+}
+
+void nile4_disable_irq_output(int cpu_irq)
+{
+	u32 t;
+
+	t = ddb_in32(DDB_INTSTAT1 + 4);
+	t &= ~(1 << (16 + cpu_irq));
+	ddb_out32(DDB_INTSTAT1, t);
+}
+
+void nile4_set_pci_irq_polarity(int pci_irq, int high)
+{
+	u32 t;
+
+	t = ddb_in32(DDB_INTPPES);
+	if (high)
+		t &= ~(1 << (pci_irq * 2));
+	else
+		t |= 1 << (pci_irq * 2);
+	ddb_out32(DDB_INTPPES, t);
+}
+
+void nile4_set_pci_irq_level_or_edge(int pci_irq, int level)
+{
+	u32 t;
+
+	t = ddb_in32(DDB_INTPPES);
+	if (level)
+		t |= 2 << (pci_irq * 2);
+	else
+		t &= ~(2 << (pci_irq * 2));
+	ddb_out32(DDB_INTPPES, t);
+}
+
+void nile4_clear_irq(int nile4_irq)
+{
+	ddb_out32(DDB_INTCLR, 1 << nile4_irq);
+}
+
+void nile4_clear_irq_mask(u32 mask)
+{
+	ddb_out32(DDB_INTCLR, mask);
+}
+
+u8 nile4_i8259_iack(void)
+{
+	u8 irq;
+	u32 reg;
+
+	/* Set window 0 for interrupt acknowledge */
+	reg = ddb_in32(DDB_PCIINIT0);
+
+	ddb_set_pmr(DDB_PCIINIT0, DDB_PCICMD_IACK, 0, DDB_PCI_ACCESS_32);
+	irq = *(volatile u8 *) KSEG1ADDR(DDB_PCI_IACK_BASE);
+	/* restore window 0 for PCI I/O space */
+	// ddb_set_pmr(DDB_PCIINIT0, DDB_PCICMD_IO, 0, DDB_PCI_ACCESS_32);
+	ddb_out32(DDB_PCIINIT0, reg);
+
+	/* i8269.c set the base vector to be 0x0 */
+	return irq + I8259_IRQ_BASE;
+}
+
+#if defined(CONFIG_RUNTIME_DEBUG)
+void nile4_dump_irq_status(void)
+{
+	printk(KERN_DEBUG "
+	       CPUSTAT = %p:%p\n", (void *) ddb_in32(DDB_CPUSTAT + 4),
+	       (void *) ddb_in32(DDB_CPUSTAT));
+	printk(KERN_DEBUG "
+	       INTCTRL = %p:%p\n", (void *) ddb_in32(DDB_INTCTRL + 4),
+	       (void *) ddb_in32(DDB_INTCTRL));
+	printk(KERN_DEBUG
+	       "INTSTAT0 = %p:%p\n",
+	       (void *) ddb_in32(DDB_INTSTAT0 + 4),
+	       (void *) ddb_in32(DDB_INTSTAT0));
+	printk(KERN_DEBUG
+	       "INTSTAT1 = %p:%p\n",
+	       (void *) ddb_in32(DDB_INTSTAT1 + 4),
+	       (void *) ddb_in32(DDB_INTSTAT1));
+	printk(KERN_DEBUG
+	       "INTCLR = %p:%p\n", (void *) ddb_in32(DDB_INTCLR + 4),
+	       (void *) ddb_in32(DDB_INTCLR));
+	printk(KERN_DEBUG
+	       "INTPPES = %p:%p\n", (void *) ddb_in32(DDB_INTPPES + 4),
+	       (void *) ddb_in32(DDB_INTPPES));
+}
+#endif
diff --git a/arch/mips/ddb5xxx/ddb5476/setup.c b/arch/mips/ddb5xxx/ddb5476/setup.c
new file mode 100644
index 0000000..71531f8
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5476/setup.c
@@ -0,0 +1,297 @@
+/*
+ *  arch/mips/ddb5476/setup.c -- NEC DDB Vrc-5476 setup routines
+ *
+ *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
+ *                     Sony Software Development Center Europe (SDCE), Brussels
+ */
+#include <linux/init.h>
+#include <linux/kbd_ll.h>
+#include <linux/kernel.h>
+#include <linux/kdev_t.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+
+#include <asm/addrspace.h>
+#include <asm/bcache.h>
+#include <asm/irq.h>
+#include <asm/reboot.h>
+#include <asm/gdb-stub.h>
+#include <asm/time.h>
+#include <asm/debug.h>
+#include <asm/traps.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+// #define USE_CPU_COUNTER_TIMER	/* whether we use cpu counter */
+
+#ifdef USE_CPU_COUNTER_TIMER
+
+#define CPU_COUNTER_FREQUENCY           83000000
+#else
+/* otherwise we use general purpose timer */
+#define TIMER_FREQUENCY			83000000
+#define TIMER_BASE			DDB_T2CTRL
+#define TIMER_IRQ			(VRC5476_IRQ_BASE + VRC5476_IRQ_GPT)
+#endif
+
+static void (*back_to_prom) (void) = (void (*)(void)) 0xbfc00000;
+
+static void ddb_machine_restart(char *command)
+{
+	u32 t;
+
+	/* PCI cold reset */
+	t = ddb_in32(DDB_PCICTRL + 4);
+	t |= 0x40000000;
+	ddb_out32(DDB_PCICTRL + 4, t);
+	/* CPU cold reset */
+	t = ddb_in32(DDB_CPUSTAT);
+	t |= 1;
+	ddb_out32(DDB_CPUSTAT, t);
+	/* Call the PROM */
+	back_to_prom();
+}
+
+static void ddb_machine_halt(void)
+{
+	printk(KERN_NOTICE "DDB Vrc-5476 halted.\n");
+	while (1);
+}
+
+static void ddb_machine_power_off(void)
+{
+	printk(KERN_NOTICE "DDB Vrc-5476 halted. Please turn off the power.\n");
+	while (1);
+}
+
+extern void rtc_ds1386_init(unsigned long base);
+
+static void __init ddb_time_init(void)
+{
+#if defined(USE_CPU_COUNTER_TIMER)
+	mips_hpt_frequency = CPU_COUNTER_FREQUENCY;
+#endif
+
+	/* we have ds1396 RTC chip */
+	rtc_ds1386_init(KSEG1ADDR(DDB_PCI_MEM_BASE));
+}
+
+
+extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
+static void __init ddb_timer_setup(struct irqaction *irq)
+{
+#if defined(USE_CPU_COUNTER_TIMER)
+
+	unsigned int count;
+
+	/* we are using the cpu counter for timer interrupts */
+	setup_irq(CPU_IRQ_BASE + 7, irq);
+
+	/* to generate the first timer interrupt */
+	count = read_c0_count();
+	write_c0_compare(count + 1000);
+
+#else
+
+	ddb_out32(TIMER_BASE, TIMER_FREQUENCY/HZ);
+	ddb_out32(TIMER_BASE+4, 0x1);	/* enable timer */
+	setup_irq(TIMER_IRQ, irq);
+#endif
+}
+
+static struct {
+	struct resource dma1;
+	struct resource timer;
+	struct resource rtc;
+	struct resource dma_page_reg;
+	struct resource dma2;
+} ddb5476_ioport = {
+	{
+	"dma1", 0x00, 0x1f, IORESOURCE_BUSY}, {
+	"timer", 0x40, 0x5f, IORESOURCE_BUSY}, {
+	"rtc", 0x70, 0x7f, IORESOURCE_BUSY}, {
+	"dma page reg", 0x80, 0x8f, IORESOURCE_BUSY}, {
+	"dma2", 0xc0, 0xdf, IORESOURCE_BUSY}
+};
+
+static struct {
+	struct resource nile4;
+} ddb5476_iomem = {
+	{ "Nile 4", DDB_BASE, DDB_BASE + DDB_SIZE - 1, IORESOURCE_BUSY}
+};
+
+
+static void ddb5476_board_init(void);
+
+static void __init ddb5476_setup(void)
+{
+	set_io_port_base(KSEG1ADDR(DDB_PCI_IO_BASE));
+
+	board_time_init = ddb_time_init;
+	board_timer_setup = ddb_timer_setup;
+
+	_machine_restart = ddb_machine_restart;
+	_machine_halt = ddb_machine_halt;
+	_machine_power_off = ddb_machine_power_off;
+
+	/* request io port/mem resources  */
+	if (request_resource(&ioport_resource, &ddb5476_ioport.dma1) ||
+	    request_resource(&ioport_resource, &ddb5476_ioport.timer) ||
+	    request_resource(&ioport_resource, &ddb5476_ioport.rtc) ||
+	    request_resource(&ioport_resource,
+			     &ddb5476_ioport.dma_page_reg)
+	    || request_resource(&ioport_resource, &ddb5476_ioport.dma2)
+	    || request_resource(&iomem_resource, &ddb5476_iomem.nile4)) {
+		printk
+		    ("ddb_setup - requesting oo port resources failed.\n");
+		for (;;);
+	}
+
+	/* Reboot on panic */
+	panic_timeout = 180;
+
+	/* [jsun] we need to set BAR0 so that SDRAM 0 appears at 0x0 in PCI */
+	/* *(long*)0xbfa00218 = 0x8; */
+
+	/* board initialization stuff */
+	ddb5476_board_init();
+}
+
+early_initcall(ddb5476_setup);
+
+/*
+ * We don't trust bios.  We essentially does hardware re-initialization
+ * as complete as possible, as far as we know we can safely do.
+ */
+static void ddb5476_board_init(void)
+{
+	/* ----------- setup PDARs ------------ */
+	/* check SDRAM0, whether we are on MEM bus does not matter */
+	db_assert((ddb_in32(DDB_SDRAM0) & 0xffffffef) ==
+		  ddb_calc_pdar(DDB_SDRAM_BASE, DDB_SDRAM_SIZE, 32, 0, 1));
+
+	/* SDRAM1 should be turned off.  What is this for anyway ? */
+	db_assert( (ddb_in32(DDB_SDRAM1) & 0xf) == 0);
+
+	/* flash 1&2, DDB status, DDB control */
+	ddb_set_pdar(DDB_DCS2, DDB_DCS2_BASE, DDB_DCS2_SIZE, 16, 0, 0);
+	ddb_set_pdar(DDB_DCS3, DDB_DCS3_BASE, DDB_DCS3_SIZE, 16, 0, 0);
+	ddb_set_pdar(DDB_DCS4, DDB_DCS4_BASE, DDB_DCS4_SIZE, 8, 0, 0);
+	ddb_set_pdar(DDB_DCS5, DDB_DCS5_BASE, DDB_DCS5_SIZE, 8, 0, 0);
+
+	/* shut off other pdar so they don't accidentally get into the way */
+	ddb_set_pdar(DDB_DCS6, 0xffffffff, 0, 32, 0, 0);
+	ddb_set_pdar(DDB_DCS7, 0xffffffff, 0, 32, 0, 0);
+	ddb_set_pdar(DDB_DCS8, 0xffffffff, 0, 32, 0, 0);
+
+	/* verify VRC5477 base addr */
+	/* don't care about some details */
+	db_assert((ddb_in32(DDB_INTCS) & 0xffffff0f) ==
+		  ddb_calc_pdar(DDB_INTCS_BASE, DDB_INTCS_SIZE, 8, 0, 0));
+
+	/* verify BOOT ROM addr */
+	/* don't care about some details */
+	db_assert((ddb_in32(DDB_BOOTCS) & 0xffffff0f) ==
+		  ddb_calc_pdar(DDB_BOOTCS_BASE, DDB_BOOTCS_SIZE, 8, 0, 0));
+
+	/* setup PCI windows - window1 for MEM/config, window0 for IO */
+	ddb_set_pdar(DDB_PCIW0, DDB_PCI_IO_BASE, DDB_PCI_IO_SIZE, 32, 0, 1);
+	ddb_set_pmr(DDB_PCIINIT0, DDB_PCICMD_IO, 0, DDB_PCI_ACCESS_32);
+
+	ddb_set_pdar(DDB_PCIW1, DDB_PCI_MEM_BASE, DDB_PCI_MEM_SIZE, 32, 0, 1);
+	ddb_set_pmr(DDB_PCIINIT1, DDB_PCICMD_MEM, DDB_PCI_MEM_BASE, DDB_PCI_ACCESS_32);
+
+	/* ----------- setup PDARs ------------ */
+	/* this is problematic - it will reset Aladin which cause we loose
+	 * serial port, and we don't know how to set up Aladin chip again.
+	 */
+	// ddb_pci_reset_bus();
+
+	ddb_out32(DDB_BAR0, 0x00000008);
+
+	ddb_out32(DDB_BARC, 0xffffffff);
+	ddb_out32(DDB_BARB, 0xffffffff);
+	ddb_out32(DDB_BAR1, 0xffffffff);
+	ddb_out32(DDB_BAR2, 0xffffffff);
+	ddb_out32(DDB_BAR3, 0xffffffff);
+	ddb_out32(DDB_BAR4, 0xffffffff);
+	ddb_out32(DDB_BAR5, 0xffffffff);
+	ddb_out32(DDB_BAR6, 0xffffffff);
+	ddb_out32(DDB_BAR7, 0xffffffff);
+	ddb_out32(DDB_BAR8, 0xffffffff);
+
+	/* ----------- switch PCI1 to PCI CONFIG space  ------------ */
+	ddb_set_pdar(DDB_PCIW1, DDB_PCI_CONFIG_BASE, DDB_PCI_CONFIG_SIZE, 32, 0, 1);
+	ddb_set_pmr(DDB_PCIINIT1, DDB_PCICMD_CFG, 0x0, DDB_PCI_ACCESS_32);
+
+	/* ----- M1543 PCI setup ------ */
+
+	/* we know M1543 PCI-ISA controller is at addr:18 */
+	/* xxxx1010 makes USB at addr:13 and PMU at addr:14 */
+	*(volatile unsigned char *) 0xa8040072 &= 0xf0;
+	*(volatile unsigned char *) 0xa8040072 |= 0xa;
+
+	/* setup USB interrupt to IRQ 9, (bit 0:3 - 0001)
+	 * no IOCHRDY signal, (bit 7 - 1)
+	 * M1543C & M7101 VID and Subsys Device ID are read-only (bit 6 - 1)
+	 * Make USB Master INTAJ level to edge conversion (bit 4 - 1)
+	 */
+	*(unsigned char *) 0xa8040074 = 0xd1;
+
+	/* setup PMU(SCI to IRQ 10 (bit 0:3 - 0011)
+	 * SCI routing to IRQ 13 disabled (bit 7 - 1)
+	 * SCI interrupt level to edge conversion bypassed (bit 4 - 0)
+	 */
+	*(unsigned char *) 0xa8040076 = 0x83;
+
+	/* setup IDE controller
+	 * enable IDE controller (bit 6 - 1)
+	 * IDE IDSEL to be addr:24 (bit 4:5 - 11)
+	 * no IDE ATA Secondary Bus Signal Pad Control (bit 3 - 0)
+	 * no IDE ATA Primary Bus Signal Pad Control (bit 2 - 0)
+	 * primary IRQ is 14, secondary is 15 (bit 1:0 - 01
+	 */
+	// *(unsigned char*)0xa8040058 = 0x71;
+	// *(unsigned char*)0xa8040058 = 0x79;
+	// *(unsigned char*)0xa8040058 = 0x74;              // use SIRQ, primary tri-state
+	*(unsigned char *) 0xa8040058 = 0x75;	// primary tri-state
+
+#if 0
+	/* this is not necessary if M5229 does not use SIRQ */
+	*(unsigned char *) 0xa8040044 = 0x0d;	// primary to IRQ 14
+	*(unsigned char *) 0xa8040075 = 0x0d;	// secondary to IRQ 14
+#endif
+
+	/* enable IDE in the M5229 config register 0x50 (bit 0 - 1) */
+	/* M5229 IDSEL is addr:24; see above setting */
+	*(unsigned char *) 0xa9000050 |= 0x1;
+
+	/* enable bus master (bit 2)  and IO decoding  (bit 0) */
+	*(unsigned char *) 0xa9000004 |= 0x5;
+
+	/* enable native, copied from arch/ppc/k2boot/head.S */
+	/* TODO - need volatile, need to be portable */
+	*(unsigned char *) 0xa9000009 = 0xff;
+
+	/* ----- end of M1543 PCI setup ------ */
+
+	/* ----- reset on-board ether chip  ------ */
+	*((volatile u32 *) 0xa8020004) |= 1;	/* decode I/O */
+	*((volatile u32 *) 0xa8020010) = 0;	/* set BAR address */
+
+	/* send reset command */
+	*((volatile u32 *) 0xa6000000) = 1;	/* do a soft reset */
+
+	/* disable ether chip */
+	*((volatile u32 *) 0xa8020004) = 0;	/* disable any decoding */
+
+	/* put it into sleep */
+	*((volatile u32 *) 0xa8020040) = 0x80000000;
+
+	/* ----- end of reset on-board ether chip  ------ */
+
+	/* ----------- switch PCI1 back to PCI MEM space  ------------ */
+	ddb_set_pdar(DDB_PCIW1, DDB_PCI_MEM_BASE, DDB_PCI_MEM_SIZE, 32, 0, 1);
+	ddb_set_pmr(DDB_PCIINIT1, DDB_PCICMD_MEM, DDB_PCI_MEM_BASE, DDB_PCI_ACCESS_32);
+}
diff --git a/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c b/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c
new file mode 100644
index 0000000..a77682b
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c
@@ -0,0 +1,112 @@
+/*
+ * The irq controller for vrc5476.
+ *
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+
+#include <asm/system.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+static int irq_base;
+
+static void vrc5476_irq_enable(uint irq)
+{
+	nile4_enable_irq(irq - irq_base);
+}
+
+static void vrc5476_irq_disable(uint irq)
+{
+	nile4_disable_irq(irq - irq_base);
+}
+
+static unsigned int vrc5476_irq_startup(uint irq)
+{
+	nile4_enable_irq(irq - irq_base);
+	return 0;
+}
+
+#define vrc5476_irq_shutdown	vrc5476_irq_disable
+
+static void vrc5476_irq_ack(uint irq)
+{
+	nile4_clear_irq(irq - irq_base);
+	nile4_disable_irq(irq - irq_base);
+}
+
+static void vrc5476_irq_end(uint irq)
+{
+	if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		vrc5476_irq_enable(irq);
+}
+
+static hw_irq_controller vrc5476_irq_controller = {
+	"vrc5476",
+	vrc5476_irq_startup,
+	vrc5476_irq_shutdown,
+	vrc5476_irq_enable,
+	vrc5476_irq_disable,
+	vrc5476_irq_ack,
+	vrc5476_irq_end,
+	NULL				/* no affinity stuff for UP */
+};
+
+void __init
+vrc5476_irq_init(u32 base)
+{
+	u32 i;
+
+	irq_base = base;
+	for (i= base; i< base + NUM_VRC5476_IRQ; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &vrc5476_irq_controller;
+	}
+}
+
+
+asmlinkage void
+vrc5476_irq_dispatch(struct pt_regs *regs)
+{
+	extern void spurious_interrupt(void);
+
+	u32 mask;
+	int nile4_irq;
+
+	mask = nile4_get_irq_stat(0);
+
+	/* quick check for possible time interrupt */
+	if (mask & (1 << VRC5476_IRQ_GPT)) {
+		do_IRQ(VRC5476_IRQ_BASE + VRC5476_IRQ_GPT, regs);
+		return;
+	}
+
+	/* check for i8259 interrupts */
+	if (mask & (1 << VRC5476_I8259_CASCADE)) {
+		int i8259_irq = nile4_i8259_iack();
+		do_IRQ(I8259_IRQ_BASE + i8259_irq, regs);
+		return;
+	}
+
+	/* regular nile4 interrupts (we should not really have any */
+	for (nile4_irq = 0; mask; nile4_irq++, mask >>= 1) {
+		if (mask & 1) {
+			do_IRQ(VRC5476_IRQ_BASE + nile4_irq, regs);
+			return;
+		}
+	}
+	spurious_interrupt();
+}
diff --git a/arch/mips/ddb5xxx/ddb5477/Makefile b/arch/mips/ddb5xxx/ddb5477/Makefile
new file mode 100644
index 0000000..b79b43c
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5477/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for NEC DDB-Vrc5477 board
+#
+
+obj-y	 		+= int-handler.o irq.o irq_5477.o setup.o lcd44780.o
+
+obj-$(CONFIG_RUNTIME_DEBUG) 	+= debug.o
+obj-$(CONFIG_KGDB)		+= kgdb_io.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/ddb5xxx/ddb5477/debug.c b/arch/mips/ddb5xxx/ddb5477/debug.c
new file mode 100644
index 0000000..68919d5
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5477/debug.c
@@ -0,0 +1,160 @@
+/***********************************************************************
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/ddb5xxx/ddb5477/debug.c
+ *     vrc5477 specific debug routines.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ ***********************************************************************
+ */
+
+#include <linux/kernel.h>
+
+#include <asm/mipsregs.h>
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+typedef struct {
+       const char *regname;
+       unsigned regaddr;
+} Register;
+
+void jsun_show_regs(char *name, Register *regs)
+{
+	int i;
+
+	printk("\nshow regs: %s\n", name);
+	for(i=0;regs[i].regname!= NULL; i++) {
+		printk("%-16s= %08x\t\t(@%08x)\n",
+		       regs[i].regname,
+		       *(unsigned *)(regs[i].regaddr),
+		       regs[i].regaddr);
+	}
+}
+
+static Register int_regs[] = {
+	{"DDB_INTCTRL0", DDB_BASE + DDB_INTCTRL0},
+	{"DDB_INTCTRL1", DDB_BASE + DDB_INTCTRL1},
+	{"DDB_INTCTRL2", DDB_BASE + DDB_INTCTRL2},
+	{"DDB_INTCTRL3", DDB_BASE + DDB_INTCTRL3},
+	{"DDB_INT0STAT", DDB_BASE + DDB_INT0STAT},
+	{"DDB_INT1STAT", DDB_BASE + DDB_INT1STAT},
+	{"DDB_INT2STAT", DDB_BASE + DDB_INT2STAT},
+	{"DDB_INT3STAT", DDB_BASE + DDB_INT3STAT},
+	{"DDB_INT4STAT", DDB_BASE + DDB_INT4STAT},
+	{"DDB_NMISTAT", DDB_BASE + DDB_NMISTAT},
+	{"DDB_INTPPES0", DDB_BASE + DDB_INTPPES0},
+	{"DDB_INTPPES1", DDB_BASE + DDB_INTPPES1},
+	{NULL, 0x0}
+};
+
+void vrc5477_show_int_regs()
+{
+	jsun_show_regs("interrupt registers", int_regs);
+	printk("CPU CAUSE = %08x\n", read_c0_cause());
+	printk("CPU STATUS = %08x\n", read_c0_status());
+}
+static Register pdar_regs[] = {
+        {"DDB_SDRAM0", DDB_BASE + DDB_SDRAM0},
+        {"DDB_SDRAM1", DDB_BASE + DDB_SDRAM1},
+        {"DDB_LCS0", DDB_BASE + DDB_LCS0},
+        {"DDB_LCS1", DDB_BASE + DDB_LCS1},
+        {"DDB_LCS2", DDB_BASE + DDB_LCS2},
+        {"DDB_INTCS", DDB_BASE + DDB_INTCS},
+        {"DDB_BOOTCS", DDB_BASE + DDB_BOOTCS},
+        {"DDB_PCIW0", DDB_BASE + DDB_PCIW0},
+        {"DDB_PCIW1", DDB_BASE + DDB_PCIW1},
+        {"DDB_IOPCIW0", DDB_BASE + DDB_IOPCIW0},
+        {"DDB_IOPCIW1", DDB_BASE + DDB_IOPCIW1},
+        {NULL, 0x0}
+};
+void vrc5477_show_pdar_regs(void)
+{
+        jsun_show_regs("PDAR regs", pdar_regs);
+}
+
+static Register bar_regs[] = {
+        {"DDB_BARC0", DDB_BASE + DDB_BARC0},
+        {"DDB_BARM010", DDB_BASE + DDB_BARM010},
+        {"DDB_BARM230", DDB_BASE + DDB_BARM230},
+        {"DDB_BAR00", DDB_BASE + DDB_BAR00},
+        {"DDB_BAR10", DDB_BASE + DDB_BAR10},
+        {"DDB_BAR20", DDB_BASE + DDB_BAR20},
+        {"DDB_BAR30", DDB_BASE + DDB_BAR30},
+        {"DDB_BAR40", DDB_BASE + DDB_BAR40},
+        {"DDB_BAR50", DDB_BASE + DDB_BAR50},
+        {"DDB_BARB0", DDB_BASE + DDB_BARB0},
+        {"DDB_BARC1", DDB_BASE + DDB_BARC1},
+        {"DDB_BARM011", DDB_BASE + DDB_BARM011},
+        {"DDB_BARM231", DDB_BASE + DDB_BARM231},
+        {"DDB_BAR01", DDB_BASE + DDB_BAR01},
+        {"DDB_BAR11", DDB_BASE + DDB_BAR11},
+        {"DDB_BAR21", DDB_BASE + DDB_BAR21},
+        {"DDB_BAR31", DDB_BASE + DDB_BAR31},
+        {"DDB_BAR41", DDB_BASE + DDB_BAR41},
+        {"DDB_BAR51", DDB_BASE + DDB_BAR51},
+        {"DDB_BARB1", DDB_BASE + DDB_BARB1},
+        {NULL, 0x0}
+};
+void vrc5477_show_bar_regs(void)
+{
+        jsun_show_regs("BAR regs", bar_regs);
+}
+
+static Register pci_regs[] = {
+        {"DDB_PCIW0", DDB_BASE + DDB_PCIW0},
+        {"DDB_PCIW1", DDB_BASE + DDB_PCIW1},
+        {"DDB_PCIINIT00", DDB_BASE + DDB_PCIINIT00},
+        {"DDB_PCIINIT10", DDB_BASE + DDB_PCIINIT10},
+        {"DDB_PCICTL0_L", DDB_BASE + DDB_PCICTL0_L},
+        {"DDB_PCICTL0_H", DDB_BASE + DDB_PCICTL0_H},
+        {"DDB_PCIARB0_L", DDB_BASE + DDB_PCIARB0_L},
+        {"DDB_PCIARB0_H", DDB_BASE + DDB_PCIARB0_H},
+        {"DDB_PCISWP0", DDB_BASE + DDB_PCISWP0},
+        {"DDB_PCIERR0", DDB_BASE + DDB_PCIERR0},
+        {"DDB_IOPCIW0", DDB_BASE + DDB_IOPCIW0},
+        {"DDB_IOPCIW1", DDB_BASE + DDB_IOPCIW1},
+        {"DDB_PCIINIT01", DDB_BASE + DDB_PCIINIT01},
+        {"DDB_PCIINIT11", DDB_BASE + DDB_PCIINIT11},
+        {"DDB_PCICTL1_L", DDB_BASE + DDB_PCICTL1_L},
+        {"DDB_PCICTL1_H", DDB_BASE + DDB_PCICTL1_H},
+        {"DDB_PCIARB1_L", DDB_BASE + DDB_PCIARB1_L},
+        {"DDB_PCIARB1_H", DDB_BASE + DDB_PCIARB1_H},
+        {"DDB_PCISWP1", DDB_BASE + DDB_PCISWP1},
+        {"DDB_PCIERR1", DDB_BASE + DDB_PCIERR1},
+        {NULL, 0x0}
+};
+void vrc5477_show_pci_regs(void)
+{
+        jsun_show_regs("PCI regs", pci_regs);
+}
+
+static Register lb_regs[] = {
+        {"DDB_LCNFG", DDB_BASE + DDB_LCNFG},
+        {"DDB_LCST0", DDB_BASE + DDB_LCST0},
+        {"DDB_LCST1", DDB_BASE + DDB_LCST1},
+        {"DDB_LCST2", DDB_BASE + DDB_LCST2},
+        {"DDB_ERRADR", DDB_BASE + DDB_ERRADR},
+        {"DDB_ERRCS", DDB_BASE + DDB_ERRCS},
+        {"DDB_BTM", DDB_BASE + DDB_BTM},
+        {"DDB_BCST", DDB_BASE + DDB_BCST},
+        {NULL, 0x0}
+};
+void vrc5477_show_lb_regs(void)
+{
+        jsun_show_regs("Local Bus regs", lb_regs);
+}
+
+void vrc5477_show_all_regs(void)
+{
+	vrc5477_show_pdar_regs();
+	vrc5477_show_pci_regs();
+	vrc5477_show_bar_regs();
+	vrc5477_show_int_regs();
+	vrc5477_show_lb_regs();
+}
diff --git a/arch/mips/ddb5xxx/ddb5477/int-handler.S b/arch/mips/ddb5xxx/ddb5477/int-handler.S
new file mode 100644
index 0000000..a2502a1
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5477/int-handler.S
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * First-level interrupt dispatcher for ddb5477
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/ddb5xxx/ddb5477.h>
+
+/*
+ * first level interrupt dispatcher for ocelot board -
+ * We check for the timer first, then check PCI ints A and D.
+ * Then check for serial IRQ and fall through.
+ */
+	.align	5
+	NESTED(ddb5477_handle_int, PT_SIZE, sp)
+	SAVE_ALL
+	CLI
+	.set	at
+	.set	noreorder
+	mfc0	t0, CP0_CAUSE
+	mfc0	t2, CP0_STATUS
+
+	and	t0, t2
+
+	andi	t1, t0, STATUSF_IP7	/* cpu timer */
+	bnez	t1, ll_cputimer_irq
+	andi	t1, t0, (STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 | STATUSF_IP5 | STATUSF_IP6 )
+	bnez	t1, ll_vrc5477_irq
+	andi	t1, t0, STATUSF_IP0	/* software int 0 */
+	bnez	t1, ll_cpu_ip0
+	andi	t1, t0, STATUSF_IP1	/* software int 1 */
+	bnez	t1, ll_cpu_ip1
+	nop
+	.set	reorder
+
+	/* wrong alarm or masked ... */
+	j	spurious_interrupt
+	nop
+	END(ddb5477_handle_int)
+
+	.align	5
+
+ll_vrc5477_irq:
+	move	a0, sp
+	jal	vrc5477_irq_dispatch
+	j	ret_from_irq
+
+ll_cputimer_irq:
+	li	a0, CPU_IRQ_BASE + 7
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+
+ll_cpu_ip0:
+	li	a0, CPU_IRQ_BASE + 0
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+ll_cpu_ip1:
+	li	a0, CPU_IRQ_BASE + 1
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
diff --git a/arch/mips/ddb5xxx/ddb5477/irq.c b/arch/mips/ddb5xxx/ddb5477/irq.c
new file mode 100644
index 0000000..5f027bf
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5477/irq.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ *  arch/mips/ddb5xxx/ddb5477/irq.c
+ *     The irq setup and misc routines for DDB5476.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+
+#include <asm/i8259.h>
+#include <asm/system.h>
+#include <asm/mipsregs.h>
+#include <asm/debug.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+
+/*
+ * IRQ mapping
+ *
+ *  0-7: 8 CPU interrupts
+ *	0 -	software interrupt 0
+ *	1 - 	software interrupt 1
+ *	2 - 	most Vrc5477 interrupts are routed to this pin
+ *	3 - 	(optional) some other interrupts routed to this pin for debugg
+ *	4 - 	not used
+ *	5 - 	not used
+ *	6 - 	not used
+ *	7 - 	cpu timer (used by default)
+ *
+ *  8-39: 32 Vrc5477 interrupt sources
+ *	(refer to the Vrc5477 manual)
+ */
+
+#define	PCI0			DDB_INTPPES0
+#define	PCI1			DDB_INTPPES1
+
+#define	ACTIVE_LOW		1
+#define	ACTIVE_HIGH		0
+
+#define	LEVEL_SENSE		2
+#define	EDGE_TRIGGER		0
+
+#define	INTA			0
+#define	INTB			1
+#define	INTC			2
+#define	INTD			3
+#define	INTE			4
+
+static inline void
+set_pci_int_attr(u32 pci, u32 intn, u32 active, u32 trigger)
+{
+	u32 reg_value;
+	u32 reg_bitmask;
+
+	reg_value = ddb_in32(pci);
+	reg_bitmask = 0x3 << (intn * 2);
+
+	reg_value &= ~reg_bitmask;
+	reg_value |= (active | trigger) << (intn * 2);
+	ddb_out32(pci, reg_value);
+}
+
+extern void vrc5477_irq_init(u32 base);
+extern void mips_cpu_irq_init(u32 base);
+extern asmlinkage void ddb5477_handle_int(void);
+extern int setup_irq(unsigned int irq, struct irqaction *irqaction);  
+static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL };
+
+void __init arch_init_irq(void)
+{
+	/* by default, we disable all interrupts and route all vrc5477
+	 * interrupts to pin 0 (irq 2) */
+	ddb_out32(DDB_INTCTRL0, 0);
+	ddb_out32(DDB_INTCTRL1, 0);
+	ddb_out32(DDB_INTCTRL2, 0);
+	ddb_out32(DDB_INTCTRL3, 0);
+
+	clear_c0_status(0xff00);
+	set_c0_status(0x0400);
+
+	/* setup PCI interrupt attributes */
+	set_pci_int_attr(PCI0, INTA, ACTIVE_LOW, LEVEL_SENSE);
+	set_pci_int_attr(PCI0, INTB, ACTIVE_LOW, LEVEL_SENSE);
+	if (mips_machtype == MACH_NEC_ROCKHOPPERII) 
+		set_pci_int_attr(PCI0, INTC, ACTIVE_HIGH, LEVEL_SENSE);
+	else
+		set_pci_int_attr(PCI0, INTC, ACTIVE_LOW, LEVEL_SENSE);
+	set_pci_int_attr(PCI0, INTD, ACTIVE_LOW, LEVEL_SENSE);
+	set_pci_int_attr(PCI0, INTE, ACTIVE_LOW, LEVEL_SENSE);
+
+	set_pci_int_attr(PCI1, INTA, ACTIVE_LOW, LEVEL_SENSE);
+	set_pci_int_attr(PCI1, INTB, ACTIVE_LOW, LEVEL_SENSE);
+	set_pci_int_attr(PCI1, INTC, ACTIVE_LOW, LEVEL_SENSE);
+	set_pci_int_attr(PCI1, INTD, ACTIVE_LOW, LEVEL_SENSE);
+	set_pci_int_attr(PCI1, INTE, ACTIVE_LOW, LEVEL_SENSE);
+
+	/*
+	 * for debugging purpose, we enable several error interrupts
+	 * and route them to pin 1. (IP3)
+	 */
+	/* cpu parity check - 0 */
+	ll_vrc5477_irq_route(0, 1); ll_vrc5477_irq_enable(0);
+	/* cpu no-target decode - 1 */
+	ll_vrc5477_irq_route(1, 1); ll_vrc5477_irq_enable(1);
+	/* local bus read time-out - 7 */
+	ll_vrc5477_irq_route(7, 1); ll_vrc5477_irq_enable(7);
+	/* PCI SERR# - 14 */
+	ll_vrc5477_irq_route(14, 1); ll_vrc5477_irq_enable(14);
+	/* PCI internal error - 15 */
+	ll_vrc5477_irq_route(15, 1); ll_vrc5477_irq_enable(15);
+	/* IOPCI SERR# - 30 */
+	ll_vrc5477_irq_route(30, 1); ll_vrc5477_irq_enable(30);
+	/* IOPCI internal error - 31 */
+	ll_vrc5477_irq_route(31, 1); ll_vrc5477_irq_enable(31);
+
+	/* init all controllers */
+	init_i8259_irqs();
+	mips_cpu_irq_init(CPU_IRQ_BASE);
+	vrc5477_irq_init(VRC5477_IRQ_BASE);
+
+
+	/* setup cascade interrupts */
+	setup_irq(VRC5477_IRQ_BASE + VRC5477_I8259_CASCADE, &irq_cascade);
+	setup_irq(CPU_IRQ_BASE + CPU_VRC5477_CASCADE, &irq_cascade);      
+
+	/* hook up the first-level interrupt handler */
+	set_except_vector(0, ddb5477_handle_int);
+}
+
+u8 i8259_interrupt_ack(void)
+{
+	u8 irq;
+	u32 reg;
+
+	/* Set window 0 for interrupt acknowledge */
+	reg = ddb_in32(DDB_PCIINIT10);
+
+	ddb_set_pmr(DDB_PCIINIT10, DDB_PCICMD_IACK, 0, DDB_PCI_ACCESS_32);
+	irq = *(volatile u8 *) KSEG1ADDR(DDB_PCI_IACK_BASE);
+	ddb_out32(DDB_PCIINIT10, reg);
+
+	/* i8259.c set the base vector to be 0x0 */
+	return irq + I8259_IRQ_BASE;
+}
+/*
+ * the first level int-handler will jump here if it is a vrc5477 irq
+ */
+#define	NUM_5477_IRQS	32
+asmlinkage void
+vrc5477_irq_dispatch(struct pt_regs *regs)
+{
+	u32 intStatus;
+	u32 bitmask;
+	u32 i;
+
+	db_assert(ddb_in32(DDB_INT2STAT) == 0);
+	db_assert(ddb_in32(DDB_INT3STAT) == 0);
+	db_assert(ddb_in32(DDB_INT4STAT) == 0);
+	db_assert(ddb_in32(DDB_NMISTAT) == 0);
+
+	if (ddb_in32(DDB_INT1STAT) != 0) {
+#if defined(CONFIG_RUNTIME_DEBUG)
+		vrc5477_show_int_regs();
+#endif
+		panic("error interrupt has happened.");
+	}
+
+	intStatus = ddb_in32(DDB_INT0STAT);
+
+	if (mips_machtype == MACH_NEC_ROCKHOPPERII) {
+		/* check for i8259 interrupts */
+		if (intStatus & (1 << VRC5477_I8259_CASCADE)) {
+			int i8259_irq = i8259_interrupt_ack();
+			do_IRQ(I8259_IRQ_BASE + i8259_irq, regs);
+			return;
+		}
+	}
+
+	for (i=0, bitmask=1; i<= NUM_5477_IRQS; bitmask <<=1, i++) {
+		/* do we need to "and" with the int mask? */
+		if (intStatus & bitmask) {
+			do_IRQ(VRC5477_IRQ_BASE + i, regs);
+			return;
+		}
+	}
+}
diff --git a/arch/mips/ddb5xxx/ddb5477/irq_5477.c b/arch/mips/ddb5xxx/ddb5477/irq_5477.c
new file mode 100644
index 0000000..0d5e706
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5477/irq_5477.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ *  arch/mips/ddb5xxx/ddb5477/irq_5477.c
+ *     This file defines the irq handler for Vrc5477.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+/*
+ * Vrc5477 defines 32 IRQs.
+ *
+ * This file exports one function:
+ *	vrc5477_irq_init(u32 irq_base);
+ */
+
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+
+#include <asm/debug.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+/* number of total irqs supported by Vrc5477 */
+#define	NUM_5477_IRQ		32
+
+static int vrc5477_irq_base = -1;
+
+
+static void
+vrc5477_irq_enable(unsigned int irq)
+{
+	db_assert(vrc5477_irq_base != -1);
+	db_assert(irq >= vrc5477_irq_base);
+	db_assert(irq < vrc5477_irq_base+ NUM_5477_IRQ);
+
+	ll_vrc5477_irq_enable(irq - vrc5477_irq_base);
+}
+
+static void
+vrc5477_irq_disable(unsigned int irq)
+{
+	db_assert(vrc5477_irq_base != -1);
+	db_assert(irq >= vrc5477_irq_base);
+	db_assert(irq < vrc5477_irq_base + NUM_5477_IRQ);
+
+	ll_vrc5477_irq_disable(irq - vrc5477_irq_base);
+}
+
+static unsigned int vrc5477_irq_startup(unsigned int irq)
+{
+	vrc5477_irq_enable(irq);
+	return 0;
+}
+
+#define	vrc5477_irq_shutdown	vrc5477_irq_disable
+
+static void
+vrc5477_irq_ack(unsigned int irq)
+{
+	db_assert(vrc5477_irq_base != -1);
+	db_assert(irq >= vrc5477_irq_base);
+	db_assert(irq < vrc5477_irq_base+ NUM_5477_IRQ);
+
+	/* clear the interrupt bit */
+	/* some irqs require the driver to clear the sources */
+	ddb_out32(DDB_INTCLR32, 1 << (irq - vrc5477_irq_base));
+
+	/* disable interrupt - some handler will re-enable the irq
+	 * and if the interrupt is leveled, we will have infinite loop
+	 */
+	ll_vrc5477_irq_disable(irq - vrc5477_irq_base);
+}
+
+static void
+vrc5477_irq_end(unsigned int irq)
+{
+	db_assert(vrc5477_irq_base != -1);
+	db_assert(irq >= vrc5477_irq_base);
+	db_assert(irq < vrc5477_irq_base + NUM_5477_IRQ);
+
+	if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		ll_vrc5477_irq_enable( irq - vrc5477_irq_base);
+}
+
+hw_irq_controller vrc5477_irq_controller = {
+	"vrc5477_irq",
+	vrc5477_irq_startup,
+	vrc5477_irq_shutdown,
+	vrc5477_irq_enable,
+	vrc5477_irq_disable,
+	vrc5477_irq_ack,
+	vrc5477_irq_end,
+	NULL			/* no affinity stuff for UP */
+};
+
+void __init vrc5477_irq_init(u32 irq_base)
+{
+	u32 i;
+
+	for (i= irq_base; i< irq_base+ NUM_5477_IRQ; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &vrc5477_irq_controller;
+	}
+
+	vrc5477_irq_base = irq_base;
+}
+
+void ll_vrc5477_irq_route(int vrc5477_irq, int ip)
+{
+	u32 reg_value;
+	u32 reg_bitmask;
+	u32 reg_index;
+
+	db_assert(vrc5477_irq >= 0);
+	db_assert(vrc5477_irq < NUM_5477_IRQ);
+	db_assert(ip >= 0);
+	db_assert((ip < 5) || (ip == 6));
+
+	reg_index = DDB_INTCTRL0 + vrc5477_irq/8*4;
+	reg_value = ddb_in32(reg_index);
+	reg_bitmask = 7 << (vrc5477_irq % 8 * 4);
+	reg_value &= ~reg_bitmask;
+	reg_value |= ip << (vrc5477_irq % 8 * 4);
+	ddb_out32(reg_index, reg_value);
+}
+
+void ll_vrc5477_irq_enable(int vrc5477_irq)
+{
+	u32 reg_value;
+	u32 reg_bitmask;
+	u32 reg_index;
+
+	db_assert(vrc5477_irq >= 0);
+	db_assert(vrc5477_irq < NUM_5477_IRQ);
+
+	reg_index = DDB_INTCTRL0 + vrc5477_irq/8*4;
+	reg_value = ddb_in32(reg_index);
+	reg_bitmask = 8 << (vrc5477_irq % 8 * 4);
+	db_assert((reg_value & reg_bitmask) == 0);
+	ddb_out32(reg_index, reg_value | reg_bitmask);
+}
+
+void ll_vrc5477_irq_disable(int vrc5477_irq)
+{
+	u32 reg_value;
+	u32 reg_bitmask;
+	u32 reg_index;
+
+	db_assert(vrc5477_irq >= 0);
+	db_assert(vrc5477_irq < NUM_5477_IRQ);
+
+	reg_index = DDB_INTCTRL0 + vrc5477_irq/8*4;
+	reg_value = ddb_in32(reg_index);
+	reg_bitmask = 8 << (vrc5477_irq % 8 * 4);
+
+	/* we assert that the interrupt is enabled (perhaps over-zealous) */
+	db_assert( (reg_value & reg_bitmask) != 0);
+	ddb_out32(reg_index, reg_value & ~reg_bitmask);
+}
diff --git a/arch/mips/ddb5xxx/ddb5477/kgdb_io.c b/arch/mips/ddb5xxx/ddb5477/kgdb_io.c
new file mode 100644
index 0000000..1d18d59
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5477/kgdb_io.c
@@ -0,0 +1,136 @@
+/*
+ * kgdb io functions for DDB5477.  We use the second serial port (upper one).
+ *
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+/* ======================= CONFIG ======================== */
+
+/* [jsun] we use the second serial port for kdb */
+#define         BASE                    0xbfa04240
+#define         MAX_BAUD                115200
+
+/* distance in bytes between two serial registers */
+#define         REG_OFFSET              8
+
+/*
+ * 0 - kgdb does serial init
+ * 1 - kgdb skip serial init
+ */
+static int remoteDebugInitialized = 0;
+
+/*
+ * the default baud rate *if* kgdb does serial init
+ */
+#define		BAUD_DEFAULT		UART16550_BAUD_38400
+
+/* ======================= END OF CONFIG ======================== */
+
+typedef unsigned char uint8;
+typedef unsigned int uint32;
+
+#define         UART16550_BAUD_2400             2400
+#define         UART16550_BAUD_4800             4800
+#define         UART16550_BAUD_9600             9600
+#define         UART16550_BAUD_19200            19200
+#define         UART16550_BAUD_38400            38400
+#define         UART16550_BAUD_57600            57600
+#define         UART16550_BAUD_115200           115200
+
+#define         UART16550_PARITY_NONE           0
+#define         UART16550_PARITY_ODD            0x08
+#define         UART16550_PARITY_EVEN           0x18
+#define         UART16550_PARITY_MARK           0x28
+#define         UART16550_PARITY_SPACE          0x38
+
+#define         UART16550_DATA_5BIT             0x0
+#define         UART16550_DATA_6BIT             0x1
+#define         UART16550_DATA_7BIT             0x2
+#define         UART16550_DATA_8BIT             0x3
+
+#define         UART16550_STOP_1BIT             0x0
+#define         UART16550_STOP_2BIT             0x4
+
+/* register offset */
+#define         OFS_RCV_BUFFER          0
+#define         OFS_TRANS_HOLD          0
+#define         OFS_SEND_BUFFER         0
+#define         OFS_INTR_ENABLE         (1*REG_OFFSET)
+#define         OFS_INTR_ID             (2*REG_OFFSET)
+#define         OFS_DATA_FORMAT         (3*REG_OFFSET)
+#define         OFS_LINE_CONTROL        (3*REG_OFFSET)
+#define         OFS_MODEM_CONTROL       (4*REG_OFFSET)
+#define         OFS_RS232_OUTPUT        (4*REG_OFFSET)
+#define         OFS_LINE_STATUS         (5*REG_OFFSET)
+#define         OFS_MODEM_STATUS        (6*REG_OFFSET)
+#define         OFS_RS232_INPUT         (6*REG_OFFSET)
+#define         OFS_SCRATCH_PAD         (7*REG_OFFSET)
+
+#define         OFS_DIVISOR_LSB         (0*REG_OFFSET)
+#define         OFS_DIVISOR_MSB         (1*REG_OFFSET)
+
+
+/* memory-mapped read/write of the port */
+#define         UART16550_READ(y)    (*((volatile uint8*)(BASE + y)))
+#define         UART16550_WRITE(y, z)  ((*((volatile uint8*)(BASE + y))) = z)
+
+void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
+{
+        /* disable interrupts */
+        UART16550_WRITE(OFS_INTR_ENABLE, 0);
+
+        /* set up buad rate */
+        {
+                uint32 divisor;
+
+                /* set DIAB bit */
+                UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
+
+                /* set divisor */
+                divisor = MAX_BAUD / baud;
+                UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
+                UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
+
+                /* clear DIAB bit */
+                UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
+        }
+
+        /* set data format */
+        UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
+}
+
+
+uint8 getDebugChar(void)
+{
+        if (!remoteDebugInitialized) {
+                remoteDebugInitialized = 1;
+                debugInit(BAUD_DEFAULT,
+                          UART16550_DATA_8BIT,
+                          UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+        }
+
+        while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
+        return UART16550_READ(OFS_RCV_BUFFER);
+}
+
+
+int putDebugChar(uint8 byte)
+{
+        if (!remoteDebugInitialized) {
+                remoteDebugInitialized = 1;
+                debugInit(BAUD_DEFAULT,
+                          UART16550_DATA_8BIT,
+                          UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+        }
+
+        while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
+        UART16550_WRITE(OFS_SEND_BUFFER, byte);
+        return 1;
+}
diff --git a/arch/mips/ddb5xxx/ddb5477/lcd44780.c b/arch/mips/ddb5xxx/ddb5477/lcd44780.c
new file mode 100644
index 0000000..35c6c22
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5477/lcd44780.c
@@ -0,0 +1,92 @@
+/*
+ * lcd44780.c
+ * Simple "driver" for a memory-mapped 44780-style LCD display.
+ *
+ * Copyright 2001 Bradley D. LaRonde <brad@ltc.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#define LCD44780_COMMAND   ((volatile unsigned char *)0xbe020000)
+#define LCD44780_DATA      ((volatile unsigned char *)0xbe020001)
+
+#define LCD44780_4BIT_1LINE        0x20
+#define LCD44780_4BIT_2LINE        0x28
+#define LCD44780_8BIT_1LINE        0x30
+#define LCD44780_8BIT_2LINE        0x38
+#define LCD44780_MODE_DEC          0x04
+#define LCD44780_MODE_DEC_SHIFT    0x05
+#define LCD44780_MODE_INC          0x06
+#define LCD44780_MODE_INC_SHIFT    0x07
+#define LCD44780_SCROLL_LEFT       0x18
+#define LCD44780_SCROLL_RIGHT      0x1e
+#define LCD44780_CURSOR_UNDERLINE  0x0e
+#define LCD44780_CURSOR_BLOCK      0x0f
+#define LCD44780_CURSOR_OFF        0x0c
+#define LCD44780_CLEAR             0x01
+#define LCD44780_BLANK             0x08
+#define LCD44780_RESTORE           0x0c  // Same as CURSOR_OFF
+#define LCD44780_HOME              0x02
+#define LCD44780_LEFT              0x10
+#define LCD44780_RIGHT             0x14
+
+void lcd44780_wait(void)
+{
+	int i, j;
+	for(i=0; i < 400; i++)
+		for(j=0; j < 10000; j++);
+}
+
+void lcd44780_command(unsigned char c)
+{
+	*LCD44780_COMMAND = c;
+	lcd44780_wait();
+}
+
+void lcd44780_data(unsigned char c)
+{
+	*LCD44780_DATA = c;
+	lcd44780_wait();
+}
+
+void lcd44780_puts(const char* s)
+{
+	int i,j;
+	int pos = 0;
+
+	lcd44780_command(LCD44780_CLEAR);
+	while(*s) {
+		lcd44780_data(*s);
+		s++;
+		pos++;
+		if (pos == 8) {
+		  /* We must write 32 of spaces to get cursor to 2nd line */
+		  for (j=0; j<32; j++) {
+		    lcd44780_data(' ');
+		  }
+		}
+		if (pos == 16) {
+		  /* We have filled all 16 character positions, so stop
+		     outputing data */
+		  break;
+		}
+	}
+#ifdef LCD44780_PUTS_PAUSE
+	for(i = 1; i < 2000; i++)
+		lcd44780_wait();
+#endif
+}
+
+void lcd44780_init(void)
+{
+	// The display on the RockHopper is physically a single
+	// 16 char line (two 8 char lines concatenated).  bdl
+	lcd44780_command(LCD44780_8BIT_2LINE);
+	lcd44780_command(LCD44780_MODE_INC);
+	lcd44780_command(LCD44780_CURSOR_BLOCK);
+	lcd44780_command(LCD44780_CLEAR);
+}
diff --git a/arch/mips/ddb5xxx/ddb5477/lcd44780.h b/arch/mips/ddb5xxx/ddb5477/lcd44780.h
new file mode 100644
index 0000000..cf2f0f7
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5477/lcd44780.h
@@ -0,0 +1,15 @@
+/*
+ * lcd44780.h
+ * Simple "driver" for a memory-mapped 44780-style LCD display.
+ *
+ * Copyright 2001 Bradley D. LaRonde <brad@ltc.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+void lcd44780_puts(const char* s);
+void lcd44780_init(void);
diff --git a/arch/mips/ddb5xxx/ddb5477/setup.c b/arch/mips/ddb5xxx/ddb5477/setup.c
new file mode 100644
index 0000000..15c6e54
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5477/setup.c
@@ -0,0 +1,405 @@
+/*
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * arch/mips/ddb5xxx/ddb5477/setup.c
+ *     Setup file for DDB5477.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/ide.h>
+#include <linux/fs.h>
+#include <linux/ioport.h>
+#include <linux/param.h>	/* for HZ */
+#include <linux/major.h>
+#include <linux/kdev_t.h>
+#include <linux/root_dev.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/addrspace.h>
+#include <asm/time.h>
+#include <asm/bcache.h>
+#include <asm/irq.h>
+#include <asm/reboot.h>
+#include <asm/gdb-stub.h>
+#include <asm/traps.h>
+#include <asm/debug.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+#include "lcd44780.h"
+
+
+#define	USE_CPU_COUNTER_TIMER	/* whether we use cpu counter */
+
+#define	SP_TIMER_BASE			DDB_SPT1CTRL_L
+#define	SP_TIMER_IRQ			VRC5477_IRQ_SPT1
+
+static int bus_frequency = CONFIG_DDB5477_BUS_FREQUENCY*1000;
+
+static void ddb_machine_restart(char *command)
+{
+	static void (*back_to_prom) (void) = (void (*)(void)) 0xbfc00000;
+
+	u32 t;
+
+	/* PCI cold reset */
+	ddb_pci_reset_bus();
+
+	/* CPU cold reset */
+	t = ddb_in32(DDB_CPUSTAT);
+	db_assert((t&1));
+	ddb_out32(DDB_CPUSTAT, t);
+
+	/* Call the PROM */
+	back_to_prom();
+}
+
+static void ddb_machine_halt(void)
+{
+	printk("DDB Vrc-5477 halted.\n");
+	while (1);
+}
+
+static void ddb_machine_power_off(void)
+{
+	printk("DDB Vrc-5477 halted. Please turn off the power.\n");
+	while (1);
+}
+
+extern void rtc_ds1386_init(unsigned long base);
+
+static unsigned int __init detect_bus_frequency(unsigned long rtc_base)
+{
+	unsigned int freq;
+	unsigned char c;
+	unsigned int t1, t2;
+	unsigned i;
+
+	ddb_out32(SP_TIMER_BASE, 0xffffffff);
+	ddb_out32(SP_TIMER_BASE+4, 0x1);
+	ddb_out32(SP_TIMER_BASE+8, 0xffffffff);
+
+	/* check if rtc is running */
+	c= *(volatile unsigned char*)rtc_base;
+	for(i=0; (c == *(volatile unsigned char*)rtc_base) && (i<100000000); i++);
+	if (c == *(volatile unsigned char*)rtc_base) {
+		printk("Failed to detect bus frequency.  Use default 83.3MHz.\n");
+		return 83333000;
+	}
+
+	c= *(volatile unsigned char*)rtc_base;
+	while (c == *(volatile unsigned char*)rtc_base);
+	/* we are now at the turn of 1/100th second, if no error. */
+	t1 = ddb_in32(SP_TIMER_BASE+8);
+
+	for (i=0; i< 10; i++) {
+		c= *(volatile unsigned char*)rtc_base;
+		while (c == *(volatile unsigned char*)rtc_base);
+		/* we are now at the turn of another 1/100th second */
+		t2 = ddb_in32(SP_TIMER_BASE+8);
+	}
+
+	ddb_out32(SP_TIMER_BASE+4, 0x0);	/* disable it again */
+
+	freq = (t1 - t2)*10;
+	printk("DDB bus frequency detection : %u \n", freq);
+	return freq;
+}
+
+static void __init ddb_time_init(void)
+{
+	unsigned long rtc_base;
+	unsigned int i;
+
+	/* we have ds1396 RTC chip */
+	if (mips_machtype == MACH_NEC_ROCKHOPPER
+		||  mips_machtype == MACH_NEC_ROCKHOPPERII) {
+		rtc_base = KSEG1ADDR(DDB_LCS2_BASE);
+	} else {
+		rtc_base = KSEG1ADDR(DDB_LCS1_BASE);
+	}
+	rtc_ds1386_init(rtc_base);
+
+	/* do we need to do run-time detection of bus speed? */
+	if (bus_frequency == 0) {
+		bus_frequency = detect_bus_frequency(rtc_base);
+	}
+
+	/* mips_hpt_frequency is 1/2 of the cpu core freq */
+	i =  (read_c0_config() >> 28 ) & 7;
+	if ((current_cpu_data.cputype == CPU_R5432) && (i == 3)) 
+		i = 4;
+	mips_hpt_frequency = bus_frequency*(i+4)/4;
+}
+
+extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
+
+static void __init ddb_timer_setup(struct irqaction *irq)
+{
+#if defined(USE_CPU_COUNTER_TIMER)
+
+        /* we are using the cpu counter for timer interrupts */
+	setup_irq(CPU_IRQ_BASE + 7, irq);
+
+#else
+
+	/* if we use Special purpose timer 1 */
+	ddb_out32(SP_TIMER_BASE, bus_frequency/HZ);
+	ddb_out32(SP_TIMER_BASE+4, 0x1);
+	setup_irq(SP_TIMER_IRQ, irq);
+
+#endif
+}
+
+static void ddb5477_board_init(void);
+
+extern struct pci_controller ddb5477_ext_controller;
+extern struct pci_controller ddb5477_io_controller;
+
+static int  ddb5477_setup(void)
+{
+	/* initialize board - we don't trust the loader */
+        ddb5477_board_init();
+
+	set_io_port_base(KSEG1ADDR(DDB_PCI_IO_BASE));
+
+	board_time_init = ddb_time_init;
+	board_timer_setup = ddb_timer_setup;
+
+	_machine_restart = ddb_machine_restart;
+	_machine_halt = ddb_machine_halt;
+	_machine_power_off = ddb_machine_power_off;
+
+	/* setup resource limits */
+	ioport_resource.end = DDB_PCI0_IO_SIZE + DDB_PCI1_IO_SIZE - 1;
+	iomem_resource.end = 0xffffffff;
+
+	/* Reboot on panic */
+	panic_timeout = 180;
+
+	register_pci_controller (&ddb5477_ext_controller);
+	register_pci_controller (&ddb5477_io_controller);
+
+	return 0;
+}
+
+early_initcall(ddb5477_setup);
+
+static void __init ddb5477_board_init(void)
+{
+	/* ----------- setup PDARs ------------ */
+
+	/* SDRAM should have been set */
+	db_assert(ddb_in32(DDB_SDRAM0) ==
+		    ddb_calc_pdar(DDB_SDRAM_BASE, board_ram_size, 32, 0, 1));
+
+	/* SDRAM1 should be turned off.  What is this for anyway ? */
+	db_assert( (ddb_in32(DDB_SDRAM1) & 0xf) == 0);
+
+	/* Setup local bus. */
+
+	/* Flash U12 PDAR and timing. */
+	ddb_set_pdar(DDB_LCS0, DDB_LCS0_BASE, DDB_LCS0_SIZE, 16, 0, 0);
+	ddb_out32(DDB_LCST0, 0x00090842);
+
+	/* We need to setup LCS1 and LCS2 differently based on the
+	   board_version */
+	if (mips_machtype == MACH_NEC_ROCKHOPPER) {
+		/* Flash U13 PDAR and timing. */
+		ddb_set_pdar(DDB_LCS1, DDB_LCS1_BASE, DDB_LCS1_SIZE, 16, 0, 0);
+		ddb_out32(DDB_LCST1, 0x00090842);
+
+		/* EPLD (NVRAM, switch, LCD, and mezzanie). */
+		ddb_set_pdar(DDB_LCS2, DDB_LCS2_BASE, DDB_LCS2_SIZE, 8, 0, 0);
+	} else {
+		/* misc */
+		ddb_set_pdar(DDB_LCS1, DDB_LCS1_BASE, DDB_LCS1_SIZE, 8, 0, 0);
+		/* mezzanie (?) */
+		ddb_set_pdar(DDB_LCS2, DDB_LCS2_BASE, DDB_LCS2_SIZE, 16, 0, 0);
+	}
+
+	/* verify VRC5477 base addr */
+	db_assert(ddb_in32(DDB_VRC5477) ==
+		  ddb_calc_pdar(DDB_VRC5477_BASE, DDB_VRC5477_SIZE, 32, 0, 1));
+
+	/* verify BOOT ROM addr */
+	db_assert(ddb_in32(DDB_BOOTCS) ==
+		  ddb_calc_pdar(DDB_BOOTCS_BASE, DDB_BOOTCS_SIZE, 8, 0, 0));
+
+	/* setup PCI windows - window0 for MEM/config, window1 for IO */
+	ddb_set_pdar(DDB_PCIW0, DDB_PCI0_MEM_BASE, DDB_PCI0_MEM_SIZE, 32, 0, 1);
+	ddb_set_pdar(DDB_PCIW1, DDB_PCI0_IO_BASE, DDB_PCI0_IO_SIZE, 32, 0, 1);
+	ddb_set_pdar(DDB_IOPCIW0, DDB_PCI1_MEM_BASE, DDB_PCI1_MEM_SIZE, 32, 0, 1);
+	ddb_set_pdar(DDB_IOPCIW1, DDB_PCI1_IO_BASE, DDB_PCI1_IO_SIZE, 32, 0, 1);
+
+	/* ------------ reset PCI bus and BARs ----------------- */
+	ddb_pci_reset_bus();
+
+	ddb_out32(DDB_BARM010, 0x00000008);
+	ddb_out32(DDB_BARM011, 0x00000008);
+
+	ddb_out32(DDB_BARC0, 0xffffffff);
+	ddb_out32(DDB_BARM230, 0xffffffff);
+	ddb_out32(DDB_BAR00, 0xffffffff);
+	ddb_out32(DDB_BAR10, 0xffffffff);
+	ddb_out32(DDB_BAR20, 0xffffffff);
+	ddb_out32(DDB_BAR30, 0xffffffff);
+	ddb_out32(DDB_BAR40, 0xffffffff);
+	ddb_out32(DDB_BAR50, 0xffffffff);
+	ddb_out32(DDB_BARB0, 0xffffffff);
+
+	ddb_out32(DDB_BARC1, 0xffffffff);
+	ddb_out32(DDB_BARM231, 0xffffffff);
+	ddb_out32(DDB_BAR01, 0xffffffff);
+	ddb_out32(DDB_BAR11, 0xffffffff);
+	ddb_out32(DDB_BAR21, 0xffffffff);
+	ddb_out32(DDB_BAR31, 0xffffffff);
+	ddb_out32(DDB_BAR41, 0xffffffff);
+	ddb_out32(DDB_BAR51, 0xffffffff);
+	ddb_out32(DDB_BARB1, 0xffffffff);
+
+	/*
+	 * We use pci master register 0  for memory space / config space
+	 * And we use register 1 for IO space.
+	 * Note that for memory space, we bump up the pci base address
+	 * so that we have 1:1 mapping between PCI memory and cpu physical.
+	 * For PCI IO space, it starts from 0 in PCI IO space but with
+	 * DDB_xx_IO_BASE in CPU physical address space.
+	 */
+	ddb_set_pmr(DDB_PCIINIT00, DDB_PCICMD_MEM, DDB_PCI0_MEM_BASE,
+		    DDB_PCI_ACCESS_32);
+	ddb_set_pmr(DDB_PCIINIT10, DDB_PCICMD_IO, 0, DDB_PCI_ACCESS_32);
+
+	ddb_set_pmr(DDB_PCIINIT01, DDB_PCICMD_MEM, DDB_PCI1_MEM_BASE,
+		    DDB_PCI_ACCESS_32);
+	ddb_set_pmr(DDB_PCIINIT11, DDB_PCICMD_IO, DDB_PCI0_IO_SIZE,
+                    DDB_PCI_ACCESS_32);
+
+
+	/* PCI cross window should be set properly */
+	ddb_set_pdar(DDB_BARP00, DDB_PCI1_MEM_BASE, DDB_PCI1_MEM_SIZE, 32, 0, 1);
+	ddb_set_pdar(DDB_BARP10, DDB_PCI1_IO_BASE, DDB_PCI1_IO_SIZE, 32, 0, 1);
+	ddb_set_pdar(DDB_BARP01, DDB_PCI0_MEM_BASE, DDB_PCI0_MEM_SIZE, 32, 0, 1);
+	ddb_set_pdar(DDB_BARP11, DDB_PCI0_IO_BASE, DDB_PCI0_IO_SIZE, 32, 0, 1);
+
+	if (mips_machtype == MACH_NEC_ROCKHOPPER
+	   ||  mips_machtype == MACH_NEC_ROCKHOPPERII) {
+		/* Disable bus diagnostics. */ 
+		ddb_out32(DDB_PCICTL0_L, 0);
+		ddb_out32(DDB_PCICTL0_H, 0);
+		ddb_out32(DDB_PCICTL1_L, 0);
+		ddb_out32(DDB_PCICTL1_H, 0);         
+	}
+
+	if (mips_machtype == MACH_NEC_ROCKHOPPER) {
+		u16			vid;
+		struct pci_bus		bus;
+		struct pci_dev		dev_m1533;
+		extern struct pci_ops 	ddb5477_ext_pci_ops;
+
+		bus.parent      = NULL;    /* we scan the top level only */
+		bus.ops         = &ddb5477_ext_pci_ops;
+		dev_m1533.bus         = &bus;
+		dev_m1533.sysdata     = NULL;
+		dev_m1533.devfn       = 7*8;     // slot 7: M1533 SouthBridge.
+		pci_read_config_word(&dev_m1533, 0, &vid);
+		if (vid == PCI_VENDOR_ID_AL) {
+			printk("Changing mips_machtype to MACH_NEC_ROCKHOPPERII\n");
+			mips_machtype = MACH_NEC_ROCKHOPPERII;
+		}
+	}
+
+	/* enable USB input buffers */
+	ddb_out32(DDB_PIBMISC, 0x00000007);
+
+	/* For dual-function pins, make them all non-GPIO */
+	ddb_out32(DDB_GIUFUNSEL, 0x0);
+	// ddb_out32(DDB_GIUFUNSEL, 0xfe0fcfff);  /* NEC recommanded value */
+
+	if (mips_machtype == MACH_NEC_ROCKHOPPERII) {
+
+		/* enable IDE controller on Ali chip (south bridge) */
+		u8			temp8;
+		struct pci_bus		bus;
+		struct pci_dev		dev_m1533;
+		struct pci_dev		dev_m5229;
+		extern struct pci_ops 	ddb5477_ext_pci_ops;
+
+		/* Setup M1535 registers */
+		bus.parent      = NULL;    /* we scan the top level only */
+		bus.ops         = &ddb5477_ext_pci_ops;
+		dev_m1533.bus         = &bus;
+		dev_m1533.sysdata     = NULL;
+		dev_m1533.devfn       = 7*8;     // slot 7: M1533 SouthBridge.
+
+		/* setup IDE controller
+		 * enable IDE controller (bit 6 - 1)
+		 * IDE IDSEL to be addr:A15 (bit 4:5 - 11)
+		 * disable IDE ATA Secondary Bus Signal Pad Control (bit 3 - 0)
+		 * enable IDE ATA Primary Bus Signal Pad Control (bit 2 - 1)
+		 */
+		pci_write_config_byte(&dev_m1533, 0x58, 0x74);
+
+		/* 
+		 * positive decode (bit6 -0)
+		 * enable IDE controler interrupt (bit 4 -1)
+		 * setup SIRQ to point to IRQ 14 (bit 3:0 - 1101)
+		 */
+		pci_write_config_byte(&dev_m1533, 0x44, 0x1d);
+
+		/* Setup M5229 registers */
+		dev_m5229.bus = &bus;
+		dev_m5229.sysdata = NULL;
+		dev_m5229.devfn = 4*8;  	// slot 4 (AD15): M5229 IDE 
+
+		/*
+		 * enable IDE in the M5229 config register 0x50 (bit 0 - 1)
+		 * M5229 IDSEL is addr:15; see above setting 
+		 */
+		pci_read_config_byte(&dev_m5229, 0x50, &temp8);
+		pci_write_config_byte(&dev_m5229, 0x50, temp8 | 0x1);
+
+		/* 
+		 * enable bus master (bit 2)  and IO decoding  (bit 0) 
+		 */
+		pci_read_config_byte(&dev_m5229, 0x04, &temp8);
+		pci_write_config_byte(&dev_m5229, 0x04, temp8 | 0x5);
+
+		/*
+		 * enable native, copied from arch/ppc/k2boot/head.S
+		 * TODO - need volatile, need to be portable 
+		 */
+		pci_write_config_byte(&dev_m5229, 0x09, 0xef);
+
+		/* Set Primary Channel Command Block Timing */ 
+		pci_write_config_byte(&dev_m5229, 0x59, 0x31);
+
+		/* 
+		 * Enable primary channel 40-pin cable
+		 * M5229 register 0x4a (bit 0)
+		 */
+		pci_read_config_byte(&dev_m5229, 0x4a, &temp8);
+		pci_write_config_byte(&dev_m5229, 0x4a, temp8 | 0x1);
+	}
+
+	if (mips_machtype == MACH_NEC_ROCKHOPPER
+	   ||  mips_machtype == MACH_NEC_ROCKHOPPERII) {
+		printk("lcd44780: initializing\n");
+		lcd44780_init();
+		lcd44780_puts("MontaVista Linux");
+	}
+}
diff --git a/arch/mips/dec/Makefile b/arch/mips/dec/Makefile
new file mode 100644
index 0000000..688757a
--- /dev/null
+++ b/arch/mips/dec/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for the DECstation family specific parts of the kernel
+#
+
+obj-y		:= ecc-berr.o int-handler.o ioasic-irq.o kn02-irq.o reset.o \
+		   setup.o time.o
+
+obj-$(CONFIG_PROM_CONSOLE)	+= promcon.o
+obj-$(CONFIG_CPU_HAS_WB)	+= wbflush.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/dec/boot/Makefile b/arch/mips/dec/boot/Makefile
new file mode 100644
index 0000000..bcea416
--- /dev/null
+++ b/arch/mips/dec/boot/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for the DECstation family specific parts of the kernel
+#
+
+netboot: all
+	$(LD) -N -G 0 -T ld.ecoff ../../boot/zImage \
+		dec_boot.o ramdisk.img -o nbImage
+
+obj-y	 := decstation.o
+
+clean:
+	rm -f nbImage
diff --git a/arch/mips/dec/boot/decstation.c b/arch/mips/dec/boot/decstation.c
new file mode 100644
index 0000000..56fd427
--- /dev/null
+++ b/arch/mips/dec/boot/decstation.c
@@ -0,0 +1,83 @@
+/*
+ * arch/mips/dec/decstation.c
+ */
+
+#define RELOC
+#define INITRD
+#define DEBUG_BOOT
+
+/*
+ * Magic number indicating REX PROM available on DECSTATION.
+ */
+#define	REX_PROM_MAGIC		0x30464354
+
+#define REX_PROM_CLEARCACHE	0x7c/4
+#define REX_PROM_PRINTF		0x30/4
+
+#define VEC_RESET		0xBFC00000		/* Prom base address */
+#define	PMAX_PROM_ENTRY(x)	(VEC_RESET+((x)*8))	/* Prom jump table */
+#define	PMAX_PROM_PRINTF	PMAX_PROM_ENTRY(17)
+
+#define PARAM	(k_start + 0x2000)
+
+#define LOADER_TYPE (*(unsigned char *) (PARAM+0x210))
+#define INITRD_START (*(unsigned long *) (PARAM+0x218))
+#define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c))
+
+extern int _ftext, _end;		/* begin and end of kernel image */
+extern void kernel_entry(int, char **, unsigned long, int *);
+
+void * memcpy(void * dest, const void *src, unsigned int count)
+{
+	unsigned long *tmp = (unsigned long *) dest, *s = (unsigned long *) src;
+
+	count >>= 2;
+	while (count--)
+		*tmp++ = *s++;
+
+	return dest;
+}
+
+void dec_entry(int argc, char **argv,
+	       unsigned long magic, int *prom_vec)
+{
+	void (*rex_clear_cache)(void);
+	int (*prom_printf)(char *, ...);
+	unsigned long k_start, len;
+
+	/*
+	 * The DS5100 leaves cpu with BEV enabled, clear it.
+	 */
+	asm(	"lui\t$8,0x3000\n\t"
+		"mtc0\t$8,$12\n\t"
+		".section\t.sdata\n\t"
+		".section\t.sbss\n\t"
+		".section\t.text"
+		: : : "$8");
+
+#ifdef DEBUG_BOOT
+	if (magic == REX_PROM_MAGIC) {
+	prom_printf = (int (*)(char *, ...)) *(prom_vec + REX_PROM_PRINTF);
+	} else {
+		prom_printf = (int (*)(char *, ...)) PMAX_PROM_PRINTF;
+	}
+	prom_printf("Launching kernel...\n");
+#endif
+
+	k_start = (unsigned long) (&kernel_entry) & 0xffff0000;
+
+#ifdef RELOC
+	/*
+	 * Now copy kernel image to its destination.
+	 */
+	len = ((unsigned long) (&_end) - k_start);
+	memcpy((void *)k_start, &_ftext, len);
+#endif
+
+	if (magic == REX_PROM_MAGIC) {
+		rex_clear_cache = (void (*)(void)) * (prom_vec + REX_PROM_CLEARCACHE);
+		rex_clear_cache();
+	}
+
+	kernel_entry(argc, argv, magic, prom_vec);
+}
diff --git a/arch/mips/dec/boot/ld.ecoff b/arch/mips/dec/boot/ld.ecoff
new file mode 100644
index 0000000..aaa633d
--- /dev/null
+++ b/arch/mips/dec/boot/ld.ecoff
@@ -0,0 +1,43 @@
+OUTPUT_FORMAT("ecoff-littlemips")
+OUTPUT_ARCH(mips)
+ENTRY(dec_entry)
+SECTIONS
+{
+  . = 0x80200000;
+
+  .text :
+  {
+    _ftext = .;
+    *(.text)
+    *(.fixup)
+  }
+  .rdata :
+  {
+    *(.rodata .rodata.* .rdata)
+  }
+  .data :
+  {
+    . = ALIGN(0x1000);
+    ramdisk.img (.data)
+    *(.data)
+  }
+  .sdata :
+  {
+    *(.sdata)
+  }
+  _gp = .;
+  .sbss :
+  {
+    *(.sbss)
+    *(.scommon)
+  }
+  .bss :
+  {
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  /DISCARD/ : {
+    *(.reginfo .mdebug .note)
+  }
+}
diff --git a/arch/mips/dec/ecc-berr.c b/arch/mips/dec/ecc-berr.c
new file mode 100644
index 0000000..133fb7c
--- /dev/null
+++ b/arch/mips/dec/ecc-berr.c
@@ -0,0 +1,280 @@
+/*
+ *	linux/arch/mips/dec/ecc-berr.c
+ *
+ *	Bus error event handling code for systems equipped with ECC
+ *	handling logic, i.e. DECstation/DECsystem 5000/200 (KN02),
+ *	5000/240 (KN03), 5000/260 (KN05) and DECsystem 5900 (KN03),
+ *	5900/260 (KN05) systems.
+ *
+ *	Copyright (c) 2003  Maciej W. Rozycki
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+
+#include <asm/dec/ecc.h>
+#include <asm/dec/kn02.h>
+#include <asm/dec/kn03.h>
+#include <asm/dec/kn05.h>
+
+static volatile u32 *kn0x_erraddr;
+static volatile u32 *kn0x_chksyn;
+
+static inline void dec_ecc_be_ack(void)
+{
+	*kn0x_erraddr = 0;			/* any write clears the IRQ */
+	iob();
+}
+
+static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
+{
+	static const char excstr[] = "exception";
+	static const char intstr[] = "interrupt";
+	static const char cpustr[] = "CPU";
+	static const char dmastr[] = "DMA";
+	static const char readstr[] = "read";
+	static const char mreadstr[] = "memory read";
+	static const char writestr[] = "write";
+	static const char mwritstr[] = "partial memory write";
+	static const char timestr[] = "timeout";
+	static const char overstr[] = "overrun";
+	static const char eccstr[] = "ECC error";
+
+	const char *kind, *agent, *cycle, *event;
+	const char *status = "", *xbit = "", *fmt = "";
+	dma_addr_t address;
+	u16 syn = 0, sngl;
+
+	int i = 0;
+
+	u32 erraddr = *kn0x_erraddr;
+	u32 chksyn = *kn0x_chksyn;
+	int action = MIPS_BE_FATAL;
+
+	/* For non-ECC ack ASAP, so any subsequent errors get caught. */
+	if ((erraddr & (KN0X_EAR_VALID | KN0X_EAR_ECCERR)) == KN0X_EAR_VALID)
+		dec_ecc_be_ack();
+
+	kind = invoker ? intstr : excstr;
+
+	if (!(erraddr & KN0X_EAR_VALID)) {
+		/* No idea what happened. */
+		printk(KERN_ALERT "Unidentified bus error %s.\n", kind);
+		return action;
+	}
+
+	agent = (erraddr & KN0X_EAR_CPU) ? cpustr : dmastr;
+
+	if (erraddr & KN0X_EAR_ECCERR) {
+		/* An ECC error on a CPU or DMA transaction. */
+		cycle = (erraddr & KN0X_EAR_WRITE) ? mwritstr : mreadstr;
+		event = eccstr;
+	} else {
+		/* A CPU timeout or a DMA overrun. */
+		cycle = (erraddr & KN0X_EAR_WRITE) ? writestr : readstr;
+		event = (erraddr & KN0X_EAR_CPU) ? timestr : overstr;
+	}
+
+	address = erraddr & KN0X_EAR_ADDRESS;
+	/* For ECC errors on reads adjust for MT pipelining. */
+	if ((erraddr & (KN0X_EAR_WRITE | KN0X_EAR_ECCERR)) == KN0X_EAR_ECCERR)
+		address = (address & ~0xfffLL) | ((address - 5) & 0xfffLL);
+	address <<= 2;
+
+	/* Only CPU errors are fixable. */
+	if (erraddr & KN0X_EAR_CPU && is_fixup)
+		action = MIPS_BE_FIXUP;
+
+	if (erraddr & KN0X_EAR_ECCERR) {
+		static const u8 data_sbit[32] = {
+			0x4f, 0x4a, 0x52, 0x54, 0x57, 0x58, 0x5b, 0x5d,
+			0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c, 0x31, 0x34,
+			0x0e, 0x0b, 0x13, 0x15, 0x16, 0x19, 0x1a, 0x1c,
+			0x62, 0x64, 0x67, 0x68, 0x6b, 0x6d, 0x70, 0x75,
+		};
+		static const u8 data_mbit[25] = {
+			0x07, 0x0d, 0x1f,
+			0x2f, 0x32, 0x37, 0x38, 0x3b, 0x3d, 0x3e,
+			0x43, 0x45, 0x46, 0x49, 0x4c, 0x51, 0x5e,
+			0x61, 0x6e, 0x73, 0x76, 0x79, 0x7a, 0x7c, 0x7f,
+		};
+		static const char sbestr[] = "corrected single";
+		static const char dbestr[] = "uncorrectable double";
+		static const char mbestr[] = "uncorrectable multiple";
+
+		if (!(address & 0x4))
+			syn = chksyn;			/* Low bank. */
+		else
+			syn = chksyn >> 16;		/* High bank. */
+
+		if (!(syn & KN0X_ESR_VLDLO)) {
+			/* Ack now, no rewrite will happen. */
+			dec_ecc_be_ack();
+
+			fmt = KERN_ALERT "%s" "invalid.\n";
+		} else {
+			sngl = syn & KN0X_ESR_SNGLO;
+			syn &= KN0X_ESR_SYNLO;
+
+			/*
+			 * Multibit errors may be tagged incorrectly;
+			 * check the syndrome explicitly.
+			 */
+			for (i = 0; i < 25; i++)
+				if (syn == data_mbit[i])
+					break;
+
+			if (i < 25) {
+				status = mbestr;
+			} else if (!sngl) {
+				status = dbestr;
+			} else {
+				volatile u32 *ptr = (void *)KSEG1ADDR(address);
+
+				*ptr = *ptr;		/* Rewrite. */
+				iob();
+
+				status = sbestr;
+				action = MIPS_BE_DISCARD;
+			}
+
+			/* Ack now, now we've rewritten (or not). */
+			dec_ecc_be_ack();
+
+			if (syn && syn == (syn & -syn)) {
+				if (syn == 0x01) {
+					fmt = KERN_ALERT "%s"
+					      "%#04x -- %s bit error "
+					      "at check bit C%s.\n";
+					xbit = "X";
+				} else {
+					fmt = KERN_ALERT "%s"
+					      "%#04x -- %s bit error "
+					      "at check bit C%s%u.\n";
+				}
+				i = syn >> 2;
+			} else {
+				for (i = 0; i < 32; i++)
+					if (syn == data_sbit[i])
+						break;
+				if (i < 32)
+					fmt = KERN_ALERT "%s"
+					      "%#04x -- %s bit error "
+					      "at data bit D%s%u.\n";
+				else
+					fmt = KERN_ALERT "%s"
+					      "%#04x -- %s bit error.\n";
+			}
+		}
+	}
+
+	if (action != MIPS_BE_FIXUP)
+		printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx.\n",
+			kind, agent, cycle, event, address);
+
+	if (action != MIPS_BE_FIXUP && erraddr & KN0X_EAR_ECCERR)
+		printk(fmt, "  ECC syndrome ", syn, status, xbit, i);
+
+	return action;
+}
+
+int dec_ecc_be_handler(struct pt_regs *regs, int is_fixup)
+{
+	return dec_ecc_be_backend(regs, is_fixup, 0);
+}
+
+irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	int action = dec_ecc_be_backend(regs, 0, 1);
+
+	if (action == MIPS_BE_DISCARD)
+		return IRQ_NONE;
+
+	/*
+	 * FIXME: Find affected processes and kill them, otherwise we
+	 * must die.
+	 *
+	 * The interrupt is asynchronously delivered thus EPC and RA
+	 * may be irrelevant, but are printed for a reference.
+	 */
+	printk(KERN_ALERT "Fatal bus interrupt, epc == %08lx, ra == %08lx\n",
+	       regs->cp0_epc, regs->regs[31]);
+	die("Unrecoverable bus error", regs);
+}
+
+
+/*
+ * Initialization differs a bit between KN02 and KN03/KN05, so we
+ * need two variants.  Once set up, all systems can be handled the
+ * same way.
+ */
+static inline void dec_kn02_be_init(void)
+{
+	volatile u32 *csr = (void *)KN02_CSR_BASE;
+	unsigned long flags;
+
+	kn0x_erraddr = (void *)(KN02_SLOT_BASE + KN02_ERRADDR);
+	kn0x_chksyn = (void *)(KN02_SLOT_BASE + KN02_CHKSYN);
+
+	spin_lock_irqsave(&kn02_lock, flags);
+
+	/* Preset write-only bits of the Control Register cache. */
+	cached_kn02_csr = *csr | KN03_CSR_LEDS;
+
+	/* Set normal ECC detection and generation. */
+	cached_kn02_csr &= ~(KN02_CSR_DIAGCHK | KN02_CSR_DIAGGEN);
+	/* Enable ECC correction. */
+	cached_kn02_csr |= KN02_CSR_CORRECT;
+	*csr = cached_kn02_csr;
+	iob();
+
+	spin_unlock_irqrestore(&kn02_lock, flags);
+}
+
+static inline void dec_kn03_be_init(void)
+{
+	volatile u32 *mcr = (void *)(KN03_SLOT_BASE + IOASIC_MCR);
+	volatile u32 *mbcs = (void *)(KN03_SLOT_BASE + KN05_MB_CSR);
+
+	kn0x_erraddr = (void *)(KN03_SLOT_BASE + IOASIC_ERRADDR);
+	kn0x_chksyn = (void *)(KN03_SLOT_BASE + IOASIC_CHKSYN);
+			
+	/*
+	 * Set normal ECC detection and generation, enable ECC correction.
+	 * For KN05 we also need to make sure EE (?) is enabled in the MB.
+	 * Otherwise DBE/IBE exceptions would be masked but bus error
+	 * interrupts would still arrive, resulting in an inevitable crash
+	 * if get_dbe() triggers one.
+	 */
+	*mcr = (*mcr & ~(KN03_MCR_DIAGCHK | KN03_MCR_DIAGGEN)) |
+	       KN03_MCR_CORRECT;
+	if (current_cpu_data.cputype == CPU_R4400SC)
+		*mbcs |= KN05_MB_CSR_EE;
+	fast_iob();
+}
+
+void __init dec_ecc_be_init(void)
+{
+	if (mips_machtype == MACH_DS5000_200)
+		dec_kn02_be_init();
+	else
+		dec_kn03_be_init();
+
+	/* Clear any leftover errors from the firmware. */
+	dec_ecc_be_ack();
+}
diff --git a/arch/mips/dec/int-handler.S b/arch/mips/dec/int-handler.S
new file mode 100644
index 0000000..3b37909
--- /dev/null
+++ b/arch/mips/dec/int-handler.S
@@ -0,0 +1,297 @@
+/*
+ * arch/mips/dec/int-handler.S
+ *
+ * Copyright (C) 1995, 1996, 1997 Paul M. Antoine and Harald Koerfgen
+ * Copyright (C) 2000, 2001, 2002, 2003  Maciej W. Rozycki
+ *
+ * Written by Ralf Baechle and Andreas Busse, modified for DECStation
+ * support by Paul Antoine and Harald Koerfgen.
+ *
+ * completly rewritten:
+ * Copyright (C) 1998 Harald Koerfgen
+ *
+ * Rewritten extensively for controller-driven IRQ support
+ * by Maciej W. Rozycki.
+ */
+#include <linux/config.h>
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+#include <asm/addrspace.h>
+
+#include <asm/dec/interrupts.h>
+#include <asm/dec/ioasic_addrs.h>
+#include <asm/dec/ioasic_ints.h>
+#include <asm/dec/kn01.h>
+#include <asm/dec/kn02.h>
+#include <asm/dec/kn02xa.h>
+#include <asm/dec/kn03.h>
+
+
+		.text
+		.set	noreorder
+/*
+ * decstation_handle_int: Interrupt handler for DECStations
+ *
+ * We follow the model in the Indy interrupt code by David Miller, where he
+ * says: a lot of complication here is taken away because:
+ *
+ * 1) We handle one interrupt and return, sitting in a loop
+ *    and moving across all the pending IRQ bits in the cause
+ *    register is _NOT_ the answer, the common case is one
+ *    pending IRQ so optimize in that direction.
+ *
+ * 2) We need not check against bits in the status register
+ *    IRQ mask, that would make this routine slow as hell.
+ *
+ * 3) Linux only thinks in terms of all IRQs on or all IRQs
+ *    off, nothing in between like BSD spl() brain-damage.
+ *
+ * Furthermore, the IRQs on the DECStations look basically (barring
+ * software IRQs which we don't use at all) like...
+ *
+ * DS2100/3100's, aka kn01, aka Pmax:
+ *
+ *	MIPS IRQ	Source
+ *      --------        ------
+ *             0	Software (ignored)
+ *             1        Software (ignored)
+ *             2        SCSI
+ *             3        Lance Ethernet
+ *             4        DZ11 serial
+ *             5        RTC
+ *             6        Memory Controller
+ *             7        FPU
+ *
+ * DS5000/200, aka kn02, aka 3max:
+ *
+ *	MIPS IRQ	Source
+ *      --------        ------
+ *             0	Software (ignored)
+ *             1        Software (ignored)
+ *             2        TurboChannel
+ *             3        RTC
+ *             4        Reserved
+ *             5        Memory Controller
+ *             6        Reserved
+ *             7        FPU
+ *
+ * DS5000/1xx's, aka kn02ba, aka 3min:
+ *
+ *	MIPS IRQ	Source
+ *      --------        ------
+ *             0	Software (ignored)
+ *             1        Software (ignored)
+ *             2        TurboChannel Slot 0
+ *             3        TurboChannel Slot 1
+ *             4        TurboChannel Slot 2
+ *             5        TurboChannel Slot 3 (ASIC)
+ *             6        Halt button
+ *             7        FPU/R4k timer
+ *
+ * DS5000/2x's, aka kn02ca, aka maxine:
+ *
+ *	MIPS IRQ	Source
+ *      --------        ------
+ *             0	Software (ignored)
+ *             1        Software (ignored)
+ *             2        Periodic Interrupt (100usec)
+ *             3        RTC
+ *             4        I/O write timeout
+ *             5        TurboChannel (ASIC)
+ *             6        Halt Keycode from Access.Bus keyboard (CTRL-ALT-ENTER)
+ *             7        FPU/R4k timer
+ *
+ * DS5000/2xx's, aka kn03, aka 3maxplus:
+ *
+ *	MIPS IRQ	Source
+ *      --------        ------
+ *             0	Software (ignored)
+ *             1        Software (ignored)
+ *             2        System Board (ASIC)
+ *             3        RTC
+ *             4        Reserved
+ *             5        Memory
+ *             6        Halt Button
+ *             7        FPU/R4k timer
+ *
+ * We handle the IRQ according to _our_ priority (see setup.c),
+ * then we just return.  If multiple IRQs are pending then we will
+ * just take another exception, big deal.
+ */
+		.align	5
+		NESTED(decstation_handle_int, PT_SIZE, ra)
+		.set	noat
+		SAVE_ALL
+		CLI				# TEST: interrupts should be off
+		.set	at
+		.set	noreorder
+
+		/*
+		 * Get pending Interrupts
+		 */
+		mfc0	t0,CP0_CAUSE		# get pending interrupts
+		mfc0	t1,CP0_STATUS
+#ifdef CONFIG_MIPS32
+		lw	t2,cpu_fpu_mask
+#endif
+		andi	t0,ST0_IM		# CAUSE.CE may be non-zero!
+		and	t0,t1			# isolate allowed ones
+
+		beqz	t0,spurious
+
+#ifdef CONFIG_MIPS32
+		 and	t2,t0
+		bnez	t2,fpu			# handle FPU immediately
+#endif
+
+		/*
+		 * Find irq with highest priority
+		 */
+		 PTR_LA	t1,cpu_mask_nr_tbl
+1:		lw	t2,(t1)
+		nop
+		and	t2,t0
+		beqz	t2,1b
+		 addu	t1,2*PTRSIZE		# delay slot
+
+		/*
+		 * Do the low-level stuff
+		 */
+		lw	a0,(-PTRSIZE)(t1)
+		nop
+		bgez	a0,handle_it		# irq_nr >= 0?
+						# irq_nr < 0: it is an address
+		 nop
+		jr	a0
+						# a trick to save a branch:
+		 lui	t2,(KN03_IOASIC_BASE>>16)&0xffff
+						# upper part of IOASIC Address
+
+/*
+ * Handle "IRQ Controller" Interrupts
+ * Masked Interrupts are still visible and have to be masked "by hand".
+ */
+		FEXPORT(kn02_io_int)		# 3max
+		lui	t0,(KN02_CSR_BASE>>16)&0xffff
+						# get interrupt status and mask
+		lw	t0,(t0)
+		nop
+		andi	t1,t0,KN02_IRQ_ALL
+		b	1f
+		 srl	t0,16			# shift interrupt mask
+
+		FEXPORT(kn02xa_io_int)		# 3min/maxine
+		lui	t2,(KN02XA_IOASIC_BASE>>16)&0xffff
+						# upper part of IOASIC Address
+
+		FEXPORT(kn03_io_int)		# 3max+ (t2 loaded earlier)
+		lw	t0,IO_REG_SIR(t2)	# get status: IOASIC sir
+		lw	t1,IO_REG_SIMR(t2)	# get mask:   IOASIC simr
+		nop
+
+1:		and	t0,t1			# mask out allowed ones
+
+		beqz	t0,spurious
+
+		/*
+		 * Find irq with highest priority
+		 */
+		 PTR_LA	t1,asic_mask_nr_tbl
+2:		lw	t2,(t1)
+		nop
+		and	t2,t0
+		beq	zero,t2,2b
+		 addu	t1,2*PTRSIZE		# delay slot
+
+		/*
+		 * Do the low-level stuff
+		 */
+		lw	a0,%lo(-PTRSIZE)(t1)
+		nop
+		bgez	a0,handle_it		# irq_nr >= 0?
+						# irq_nr < 0: it is an address
+		 nop
+		jr	a0
+		 nop				# delay slot
+
+/*
+ * Dispatch low-priority interrupts.  We reconsider all status
+ * bits again, which looks like a lose, but it makes the code
+ * simple and O(log n), so it gets compensated.
+ */
+		FEXPORT(cpu_all_int)		# HALT, timers, software junk
+		li	a0,DEC_CPU_IRQ_BASE
+		srl	t0,CAUSEB_IP
+		li	t1,CAUSEF_IP>>CAUSEB_IP	# mask
+		b	1f
+		 li	t2,4			# nr of bits / 2
+
+		FEXPORT(kn02_all_int)		# impossible ?
+		li	a0,KN02_IRQ_BASE
+		li	t1,KN02_IRQ_ALL		# mask
+		b	1f
+		 li	t2,4			# nr of bits / 2
+
+		FEXPORT(asic_all_int)		# various I/O ASIC junk
+		li	a0,IO_IRQ_BASE
+		li	t1,IO_IRQ_ALL		# mask
+		b	1f
+		 li	t2,8			# nr of bits / 2
+
+/*
+ * Dispatch DMA interrupts -- O(log n).
+ */
+		FEXPORT(asic_dma_int)		# I/O ASIC DMA events
+		li	a0,IO_IRQ_BASE+IO_INR_DMA
+		srl	t0,IO_INR_DMA
+		li	t1,IO_IRQ_DMA>>IO_INR_DMA # mask
+		li	t2,8			# nr of bits / 2
+
+		/*
+		 * Find irq with highest priority.
+		 * Highest irq number takes precedence.
+		 */
+1:		srlv	t3,t1,t2
+2:		xor	t1,t3
+		and	t3,t0,t1
+		beqz	t3,3f
+		 nop
+		move	t0,t3
+		addu	a0,t2
+3:		srl	t2,1
+		bnez	t2,2b
+		 srlv	t3,t1,t2
+
+handle_it:
+		jal	do_IRQ
+		 move	a1,sp
+
+		j	ret_from_irq
+		 nop
+
+#ifdef CONFIG_MIPS32
+fpu:
+		j	handle_fpe_int
+		 nop
+#endif
+
+spurious:
+		j	spurious_interrupt
+		 nop
+		END(decstation_handle_int)
+
+/*
+ * Generic unimplemented interrupt routines -- cpu_mask_nr_tbl
+ * and asic_mask_nr_tbl are initialized to point all interrupts here.
+ * The tables are then filled in by machine-specific initialisation
+ * in dec_setup().
+ */
+		FEXPORT(dec_intr_unimplemented)
+		move	a1,t0			# cheats way of printing an arg!
+		PANIC("Unimplemented cpu interrupt! CP0_CAUSE: 0x%08x");
+
+		FEXPORT(asic_intr_unimplemented)
+		move	a1,t0			# cheats way of printing an arg!
+		PANIC("Unimplemented asic interrupt! ASIC ISR: 0x%08x");
diff --git a/arch/mips/dec/ioasic-irq.c b/arch/mips/dec/ioasic-irq.c
new file mode 100644
index 0000000..d5bca5d
--- /dev/null
+++ b/arch/mips/dec/ioasic-irq.c
@@ -0,0 +1,157 @@
+/*
+ *	linux/arch/mips/dec/ioasic-irq.c
+ *
+ *	DEC I/O ASIC interrupts.
+ *
+ *	Copyright (c) 2002, 2003  Maciej W. Rozycki
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <asm/dec/ioasic.h>
+#include <asm/dec/ioasic_addrs.h>
+#include <asm/dec/ioasic_ints.h>
+
+
+static DEFINE_SPINLOCK(ioasic_lock);
+
+static int ioasic_irq_base;
+
+
+static inline void unmask_ioasic_irq(unsigned int irq)
+{
+	u32 simr;
+
+	simr = ioasic_read(IO_REG_SIMR);
+	simr |= (1 << (irq - ioasic_irq_base));
+	ioasic_write(IO_REG_SIMR, simr);
+}
+
+static inline void mask_ioasic_irq(unsigned int irq)
+{
+	u32 simr;
+
+	simr = ioasic_read(IO_REG_SIMR);
+	simr &= ~(1 << (irq - ioasic_irq_base));
+	ioasic_write(IO_REG_SIMR, simr);
+}
+
+static inline void clear_ioasic_irq(unsigned int irq)
+{
+	u32 sir;
+
+	sir = ~(1 << (irq - ioasic_irq_base));
+	ioasic_write(IO_REG_SIR, sir);
+}
+
+static inline void enable_ioasic_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ioasic_lock, flags);
+	unmask_ioasic_irq(irq);
+	spin_unlock_irqrestore(&ioasic_lock, flags);
+}
+
+static inline void disable_ioasic_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ioasic_lock, flags);
+	mask_ioasic_irq(irq);
+	spin_unlock_irqrestore(&ioasic_lock, flags);
+}
+
+
+static inline unsigned int startup_ioasic_irq(unsigned int irq)
+{
+	enable_ioasic_irq(irq);
+	return 0;
+}
+
+#define shutdown_ioasic_irq disable_ioasic_irq
+
+static inline void ack_ioasic_irq(unsigned int irq)
+{
+	spin_lock(&ioasic_lock);
+	mask_ioasic_irq(irq);
+	spin_unlock(&ioasic_lock);
+	fast_iob();
+}
+
+static inline void end_ioasic_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		enable_ioasic_irq(irq);
+}
+
+static struct hw_interrupt_type ioasic_irq_type = {
+	.typename = "IO-ASIC",
+	.startup = startup_ioasic_irq,
+	.shutdown = shutdown_ioasic_irq,
+	.enable = enable_ioasic_irq,
+	.disable = disable_ioasic_irq,
+	.ack = ack_ioasic_irq,
+	.end = end_ioasic_irq,
+};
+
+
+#define startup_ioasic_dma_irq startup_ioasic_irq
+
+#define shutdown_ioasic_dma_irq shutdown_ioasic_irq
+
+#define enable_ioasic_dma_irq enable_ioasic_irq
+
+#define disable_ioasic_dma_irq disable_ioasic_irq
+
+#define ack_ioasic_dma_irq ack_ioasic_irq
+
+static inline void end_ioasic_dma_irq(unsigned int irq)
+{
+	clear_ioasic_irq(irq);
+	fast_iob();
+	end_ioasic_irq(irq);
+}
+
+static struct hw_interrupt_type ioasic_dma_irq_type = {
+	.typename = "IO-ASIC-DMA",
+	.startup = startup_ioasic_dma_irq,
+	.shutdown = shutdown_ioasic_dma_irq,
+	.enable = enable_ioasic_dma_irq,
+	.disable = disable_ioasic_dma_irq,
+	.ack = ack_ioasic_dma_irq,
+	.end = end_ioasic_dma_irq,
+};
+
+
+void __init init_ioasic_irqs(int base)
+{
+	int i;
+
+	/* Mask interrupts. */
+	ioasic_write(IO_REG_SIMR, 0);
+	fast_iob();
+
+	for (i = base; i < base + IO_INR_DMA; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = 0;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &ioasic_irq_type;
+	}
+	for (; i < base + IO_IRQ_LINES; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = 0;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &ioasic_dma_irq_type;
+	}
+
+	ioasic_irq_base = base;
+}
diff --git a/arch/mips/dec/kn02-irq.c b/arch/mips/dec/kn02-irq.c
new file mode 100644
index 0000000..e0bfcd1
--- /dev/null
+++ b/arch/mips/dec/kn02-irq.c
@@ -0,0 +1,127 @@
+/*
+ *	linux/arch/mips/dec/kn02-irq.c
+ *
+ *	DECstation 5000/200 (KN02) Control and Status Register
+ *	interrupts.
+ *
+ *	Copyright (c) 2002, 2003  Maciej W. Rozycki
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <asm/dec/kn02.h>
+
+
+/*
+ * Bits 7:0 of the Control Register are write-only -- the
+ * corresponding bits of the Status Register have a different
+ * meaning.  Hence we use a cache.  It speeds up things a bit
+ * as well.
+ *
+ * There is no default value -- it has to be initialized.
+ */
+u32 cached_kn02_csr;
+DEFINE_SPINLOCK(kn02_lock);
+
+
+static int kn02_irq_base;
+
+
+static inline void unmask_kn02_irq(unsigned int irq)
+{
+	volatile u32 *csr = (volatile u32 *)KN02_CSR_BASE;
+
+	cached_kn02_csr |= (1 << (irq - kn02_irq_base + 16));
+	*csr = cached_kn02_csr;
+}
+
+static inline void mask_kn02_irq(unsigned int irq)
+{
+	volatile u32 *csr = (volatile u32 *)KN02_CSR_BASE;
+
+	cached_kn02_csr &= ~(1 << (irq - kn02_irq_base + 16));
+	*csr = cached_kn02_csr;
+}
+
+static inline void enable_kn02_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&kn02_lock, flags);
+	unmask_kn02_irq(irq);
+	spin_unlock_irqrestore(&kn02_lock, flags);
+}
+
+static inline void disable_kn02_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&kn02_lock, flags);
+	mask_kn02_irq(irq);
+	spin_unlock_irqrestore(&kn02_lock, flags);
+}
+
+
+static unsigned int startup_kn02_irq(unsigned int irq)
+{
+	enable_kn02_irq(irq);
+	return 0;
+}
+
+#define shutdown_kn02_irq disable_kn02_irq
+
+static void ack_kn02_irq(unsigned int irq)
+{
+	spin_lock(&kn02_lock);
+	mask_kn02_irq(irq);
+	spin_unlock(&kn02_lock);
+	iob();
+}
+
+static void end_kn02_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		enable_kn02_irq(irq);
+}
+
+static struct hw_interrupt_type kn02_irq_type = {
+	.typename = "KN02-CSR",
+	.startup = startup_kn02_irq,
+	.shutdown = shutdown_kn02_irq,
+	.enable = enable_kn02_irq,
+	.disable = disable_kn02_irq,
+	.ack = ack_kn02_irq,
+	.end = end_kn02_irq,
+};
+
+
+void __init init_kn02_irqs(int base)
+{
+	volatile u32 *csr = (volatile u32 *)KN02_CSR_BASE;
+	unsigned long flags;
+	int i;
+
+	/* Mask interrupts. */
+	spin_lock_irqsave(&kn02_lock, flags);
+	cached_kn02_csr &= ~KN03_CSR_IOINTEN;
+	*csr = cached_kn02_csr;
+	iob();
+	spin_unlock_irqrestore(&kn02_lock, flags);
+
+	for (i = base; i < base + KN02_IRQ_LINES; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = 0;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &kn02_irq_type;
+	}
+
+	kn02_irq_base = base;
+}
diff --git a/arch/mips/dec/prom/Makefile b/arch/mips/dec/prom/Makefile
new file mode 100644
index 0000000..373822e
--- /dev/null
+++ b/arch/mips/dec/prom/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for the DECstation prom monitor library routines
+# under Linux.
+#
+
+lib-y			+= init.o memory.o cmdline.o identify.o console.o
+
+lib-$(CONFIG_MIPS32)	+= locore.o
+lib-$(CONFIG_MIPS64)	+= call_o32.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/dec/prom/call_o32.S b/arch/mips/dec/prom/call_o32.S
new file mode 100644
index 0000000..0dd56db
--- /dev/null
+++ b/arch/mips/dec/prom/call_o32.S
@@ -0,0 +1,91 @@
+/*
+ *	arch/mips/dec/call_o32.S
+ *
+ *	O32 interface for the 64 (or N32) ABI.
+ *
+ *	Copyright (C) 2002  Maciej W. Rozycki
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+
+/* Maximum number of arguments supported.  Must be even!  */
+#define O32_ARGC	32
+/* Number of static registers we save.  */
+#define O32_STATC	11
+/* Frame size for both of the above.  */
+#define O32_FRAMESZ	(4 * O32_ARGC + SZREG * O32_STATC)
+
+		.text
+
+/*
+ * O32 function call dispatcher, for interfacing 32-bit ROM routines.
+ *
+ * The standard 64 (N32) calling sequence is supported, with a0
+ * holding a function pointer, a1-a7 -- its first seven arguments
+ * and the stack -- remaining ones (up to O32_ARGC, including a1-a7).
+ * Static registers, gp and fp are preserved, v0 holds a result.
+ * This code relies on the called o32 function for sp and ra
+ * restoration and thus both this dispatcher and the current stack
+ * have to be placed in a KSEGx (or KUSEG) address space.  Any
+ * pointers passed have to point to addresses within one of these
+ * spaces as well.
+ */
+NESTED(call_o32, O32_FRAMESZ, ra)
+		REG_SUBU	sp,O32_FRAMESZ
+
+		REG_S		ra,O32_FRAMESZ-1*SZREG(sp)
+		REG_S		fp,O32_FRAMESZ-2*SZREG(sp)
+		REG_S		gp,O32_FRAMESZ-3*SZREG(sp)
+		REG_S		s7,O32_FRAMESZ-4*SZREG(sp)
+		REG_S		s6,O32_FRAMESZ-5*SZREG(sp)
+		REG_S		s5,O32_FRAMESZ-6*SZREG(sp)
+		REG_S		s4,O32_FRAMESZ-7*SZREG(sp)
+		REG_S		s3,O32_FRAMESZ-8*SZREG(sp)
+		REG_S		s2,O32_FRAMESZ-9*SZREG(sp)
+		REG_S		s1,O32_FRAMESZ-10*SZREG(sp)
+		REG_S		s0,O32_FRAMESZ-11*SZREG(sp)
+
+		move		jp,a0
+
+		sll		a0,a1,zero
+		sll		a1,a2,zero
+		sll		a2,a3,zero
+		sll		a3,a4,zero
+		sw		a5,0x10(sp)
+		sw		a6,0x14(sp)
+		sw		a7,0x18(sp)
+
+		PTR_LA		t0,O32_FRAMESZ(sp)
+		PTR_LA		t1,0x1c(sp)
+		li		t2,O32_ARGC-7
+1:
+		lw		t3,(t0)
+		REG_ADDU	t0,SZREG
+		sw		t3,(t1)
+		REG_SUBU	t2,1
+		REG_ADDU	t1,4
+		bnez		t2,1b
+
+		jalr		jp
+
+		REG_L		s0,O32_FRAMESZ-11*SZREG(sp)
+		REG_L		s1,O32_FRAMESZ-10*SZREG(sp)
+		REG_L		s2,O32_FRAMESZ-9*SZREG(sp)
+		REG_L		s3,O32_FRAMESZ-8*SZREG(sp)
+		REG_L		s4,O32_FRAMESZ-7*SZREG(sp)
+		REG_L		s5,O32_FRAMESZ-6*SZREG(sp)
+		REG_L		s6,O32_FRAMESZ-5*SZREG(sp)
+		REG_L		s7,O32_FRAMESZ-4*SZREG(sp)
+		REG_L		gp,O32_FRAMESZ-3*SZREG(sp)
+		REG_L		fp,O32_FRAMESZ-2*SZREG(sp)
+		REG_L		ra,O32_FRAMESZ-1*SZREG(sp)
+
+		REG_ADDU	sp,O32_FRAMESZ
+		jr		ra
+END(call_o32)
diff --git a/arch/mips/dec/prom/cmdline.c b/arch/mips/dec/prom/cmdline.c
new file mode 100644
index 0000000..c3490be
--- /dev/null
+++ b/arch/mips/dec/prom/cmdline.c
@@ -0,0 +1,39 @@
+/*
+ * cmdline.c: read the command line passed to us by the PROM.
+ *
+ * Copyright (C) 1998 Harald Koerfgen
+ * Copyright (C) 2002, 2004  Maciej W. Rozycki
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include <asm/bootinfo.h>
+#include <asm/dec/prom.h>
+
+#undef PROM_DEBUG
+
+void __init prom_init_cmdline(s32 argc, s32 *argv, u32 magic)
+{
+	char *arg;
+	int start_arg, i;
+
+	/*
+	 * collect args and prepare cmd_line
+	 */
+	if (!prom_is_rex(magic))
+		start_arg = 1;
+	else
+		start_arg = 2;
+	for (i = start_arg; i < argc; i++) {
+		arg = (void *)(long)(argv[i]);
+		strcat(arcs_cmdline, arg);
+		if (i < (argc - 1))
+			strcat(arcs_cmdline, " ");
+	}
+
+#ifdef PROM_DEBUG
+	printk("arcs_cmdline: %s\n", &(arcs_cmdline[0]));
+#endif
+}
diff --git a/arch/mips/dec/prom/console.c b/arch/mips/dec/prom/console.c
new file mode 100644
index 0000000..cade16e
--- /dev/null
+++ b/arch/mips/dec/prom/console.c
@@ -0,0 +1,55 @@
+/*
+ *	arch/mips/dec/prom/console.c
+ *
+ *	DECstation PROM-based early console support.
+ *
+ *	Copyright (C) 2004  Maciej W. Rozycki
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ */
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+#include <asm/dec/prom.h>
+
+static void __init prom_console_write(struct console *con, const char *s,
+				      unsigned int c)
+{
+	static char sfmt[] __initdata = "%%%us";
+	char fmt[13];
+
+	snprintf(fmt, sizeof(fmt), sfmt, c);
+	prom_printf(fmt, s);
+}
+
+static struct console promcons __initdata = {
+	.name	= "prom",
+	.write	= prom_console_write,
+	.flags	= CON_PRINTBUFFER,
+	.index	= -1,
+};
+
+static int promcons_output __initdata = 0;
+
+void __init register_prom_console(void)
+{
+	if (!promcons_output) {
+		promcons_output = 1;
+		register_console(&promcons);
+	}
+}
+
+void __init unregister_prom_console(void)
+{
+	if (promcons_output) {
+		unregister_console(&promcons);
+		promcons_output = 0;
+	}
+}
+
+void disable_early_printk(void)
+	__attribute__((alias("unregister_prom_console")));
diff --git a/arch/mips/dec/prom/dectypes.h b/arch/mips/dec/prom/dectypes.h
new file mode 100644
index 0000000..707b6f1
--- /dev/null
+++ b/arch/mips/dec/prom/dectypes.h
@@ -0,0 +1,14 @@
+#ifndef DECTYPES
+#define	DECTYPES
+
+#define DS2100_3100	1	/* DS2100/3100	Pmax		*/
+#define DS5000_200	2	/* DS5000/200	3max		*/
+#define DS5000_1XX	3	/* DS5000/1xx	kmin		*/
+#define DS5000_2X0	4	/* DS5000/2x0	3max+		*/
+#define DS5800		5	/* DS5800	Isis		*/
+#define DS5400		6	/* DS5400	MIPSfair	*/
+#define DS5000_XX	7	/* DS5000/xx	maxine		*/
+#define DS5500		11	/* DS5500	MIPSfair-2	*/
+#define DS5100		12	/* DS5100	MIPSmate	*/
+
+#endif
diff --git a/arch/mips/dec/prom/identify.c b/arch/mips/dec/prom/identify.c
new file mode 100644
index 0000000..9380588
--- /dev/null
+++ b/arch/mips/dec/prom/identify.c
@@ -0,0 +1,177 @@
+/*
+ * identify.c: machine identification code.
+ *
+ * Copyright (C) 1998 Harald Koerfgen and Paul M. Antoine
+ * Copyright (C) 2002, 2003, 2004  Maciej W. Rozycki
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mc146818rtc.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include <asm/bootinfo.h>
+#include <asm/dec/ioasic.h>
+#include <asm/dec/ioasic_addrs.h>
+#include <asm/dec/kn01.h>
+#include <asm/dec/kn02.h>
+#include <asm/dec/kn02ba.h>
+#include <asm/dec/kn02ca.h>
+#include <asm/dec/kn03.h>
+#include <asm/dec/kn230.h>
+#include <asm/dec/prom.h>
+
+#include "dectypes.h"
+
+extern unsigned long mips_machgroup;
+extern unsigned long mips_machtype;
+
+static const char *dec_system_strings[] = {
+	[MACH_DSUNKNOWN]	"unknown DECstation",
+	[MACH_DS23100]		"DECstation 2100/3100",
+	[MACH_DS5100]		"DECsystem 5100",
+	[MACH_DS5000_200]	"DECstation 5000/200",
+	[MACH_DS5000_1XX]	"DECstation 5000/1xx",
+	[MACH_DS5000_XX]	"Personal DECstation 5000/xx",
+	[MACH_DS5000_2X0]	"DECstation 5000/2x0",
+	[MACH_DS5400]		"DECsystem 5400",
+	[MACH_DS5500]		"DECsystem 5500",
+	[MACH_DS5800]		"DECsystem 5800",
+	[MACH_DS5900]		"DECsystem 5900",
+};
+
+const char *get_system_type(void)
+{
+#define STR_BUF_LEN	64
+	static char system[STR_BUF_LEN];
+	static int called = 0;
+
+	if (called == 0) {
+		called = 1;
+		snprintf(system, STR_BUF_LEN, "Digital %s",
+			 dec_system_strings[mips_machtype]);
+	}
+
+	return system;
+}
+
+
+/*
+ * Setup essential system-specific memory addresses.  We need them
+ * early.  Semantically the functions belong to prom/init.c, but they
+ * are compact enough we want them inlined. --macro
+ */
+volatile u8 *dec_rtc_base;
+
+EXPORT_SYMBOL(dec_rtc_base);
+
+static inline void prom_init_kn01(void)
+{
+	dec_rtc_base = (void *)KN01_RTC_BASE;
+	dec_kn_slot_size = KN01_SLOT_SIZE;
+}
+
+static inline void prom_init_kn230(void)
+{
+	dec_rtc_base = (void *)KN01_RTC_BASE;
+	dec_kn_slot_size = KN01_SLOT_SIZE;
+}
+
+static inline void prom_init_kn02(void)
+{
+	dec_rtc_base = (void *)KN02_RTC_BASE;
+	dec_kn_slot_size = KN02_SLOT_SIZE;
+}
+
+static inline void prom_init_kn02xa(void)
+{
+	ioasic_base = (void *)KN02XA_IOASIC_BASE;
+	dec_rtc_base = (void *)KN02XA_RTC_BASE;
+	dec_kn_slot_size = IOASIC_SLOT_SIZE;
+}
+
+static inline void prom_init_kn03(void)
+{
+	ioasic_base = (void *)KN03_IOASIC_BASE;
+	dec_rtc_base = (void *)KN03_RTC_BASE;
+	dec_kn_slot_size = IOASIC_SLOT_SIZE;
+}
+
+
+void __init prom_identify_arch(u32 magic)
+{
+	unsigned char dec_cpunum, dec_firmrev, dec_etc, dec_systype;
+	u32 dec_sysid;
+
+	if (!prom_is_rex(magic)) {
+		dec_sysid = simple_strtoul(prom_getenv("systype"),
+					   (char **)0, 0);
+	} else {
+		dec_sysid = rex_getsysid();
+		if (dec_sysid == 0) {
+			printk("Zero sysid returned from PROM! "
+			       "Assuming a PMAX-like machine.\n");
+			dec_sysid = 1;
+		}
+	}
+
+	dec_cpunum = (dec_sysid & 0xff000000) >> 24;
+	dec_systype = (dec_sysid & 0xff0000) >> 16;
+	dec_firmrev = (dec_sysid & 0xff00) >> 8;
+	dec_etc = dec_sysid & 0xff;
+
+	/* We're obviously one of the DEC machines */
+	mips_machgroup = MACH_GROUP_DEC;
+
+	/*
+	 * FIXME: This may not be an exhaustive list of DECStations/Servers!
+	 * Put all model-specific initialisation calls here.
+	 */
+	switch (dec_systype) {
+	case DS2100_3100:
+		mips_machtype = MACH_DS23100;
+		prom_init_kn01();
+		break;
+	case DS5100:		/* DS5100 MIPSMATE */
+		mips_machtype = MACH_DS5100;
+		prom_init_kn230();
+		break;
+	case DS5000_200:	/* DS5000 3max */
+		mips_machtype = MACH_DS5000_200;
+		prom_init_kn02();
+		break;
+	case DS5000_1XX:	/* DS5000/100 3min */
+		mips_machtype = MACH_DS5000_1XX;
+		prom_init_kn02xa();
+		break;
+	case DS5000_2X0:	/* DS5000/240 3max+ or DS5900 bigmax */
+		mips_machtype = MACH_DS5000_2X0;
+		prom_init_kn03();
+		if (!(ioasic_read(IO_REG_SIR) & KN03_IO_INR_3MAXP))
+			mips_machtype = MACH_DS5900;
+		break;
+	case DS5000_XX:		/* Personal DS5000/xx maxine */
+		mips_machtype = MACH_DS5000_XX;
+		prom_init_kn02xa();
+		break;
+	case DS5800:		/* DS5800 Isis */
+		mips_machtype = MACH_DS5800;
+		break;
+	case DS5400:		/* DS5400 MIPSfair */
+		mips_machtype = MACH_DS5400;
+		break;
+	case DS5500:		/* DS5500 MIPSfair-2 */
+		mips_machtype = MACH_DS5500;
+		break;
+	default:
+		mips_machtype = MACH_DSUNKNOWN;
+		break;
+	}
+
+	if (mips_machtype == MACH_DSUNKNOWN)
+		printk("This is an %s, id is %x\n",
+		       dec_system_strings[mips_machtype], dec_systype);
+	else
+		printk("This is a %s\n", dec_system_strings[mips_machtype]);
+}
diff --git a/arch/mips/dec/prom/init.c b/arch/mips/dec/prom/init.c
new file mode 100644
index 0000000..60f7425
--- /dev/null
+++ b/arch/mips/dec/prom/init.c
@@ -0,0 +1,134 @@
+/*
+ * init.c: PROM library initialisation code.
+ *
+ * Copyright (C) 1998 Harald Koerfgen
+ * Copyright (C) 2002, 2004  Maciej W. Rozycki
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/processor.h>
+
+#include <asm/dec/prom.h>
+
+
+int (*__rex_bootinit)(void);
+int (*__rex_bootread)(void);
+int (*__rex_getbitmap)(memmap *);
+unsigned long *(*__rex_slot_address)(int);
+void *(*__rex_gettcinfo)(void);
+int (*__rex_getsysid)(void);
+void (*__rex_clear_cache)(void);
+
+int (*__prom_getchar)(void);
+char *(*__prom_getenv)(char *);
+int (*__prom_printf)(char *, ...);
+
+int (*__pmax_open)(char*, int);
+int (*__pmax_lseek)(int, long, int);
+int (*__pmax_read)(int, void *, int);
+int (*__pmax_close)(int);
+
+
+/*
+ * Detect which PROM the DECSTATION has, and set the callback vectors
+ * appropriately.
+ */
+void __init which_prom(s32 magic, s32 *prom_vec)
+{
+	/*
+	 * No sign of the REX PROM's magic number means we assume a non-REX
+	 * machine (i.e. we're on a DS2100/3100, DS5100 or DS5000/2xx)
+	 */
+	if (prom_is_rex(magic)) {
+		/*
+		 * Set up prom abstraction structure with REX entry points.
+		 */
+		__rex_bootinit =
+			(void *)(long)*(prom_vec + REX_PROM_BOOTINIT);
+		__rex_bootread =
+			(void *)(long)*(prom_vec + REX_PROM_BOOTREAD);
+		__rex_getbitmap =
+			(void *)(long)*(prom_vec + REX_PROM_GETBITMAP);
+		__prom_getchar =
+			(void *)(long)*(prom_vec + REX_PROM_GETCHAR);
+		__prom_getenv =
+			(void *)(long)*(prom_vec + REX_PROM_GETENV);
+		__rex_getsysid =
+			(void *)(long)*(prom_vec + REX_PROM_GETSYSID);
+		__rex_gettcinfo =
+			(void *)(long)*(prom_vec + REX_PROM_GETTCINFO);
+		__prom_printf =
+			(void *)(long)*(prom_vec + REX_PROM_PRINTF);
+		__rex_slot_address =
+			(void *)(long)*(prom_vec + REX_PROM_SLOTADDR);
+		__rex_clear_cache =
+			(void *)(long)*(prom_vec + REX_PROM_CLEARCACHE);
+	} else {
+		/*
+		 * Set up prom abstraction structure with non-REX entry points.
+		 */
+		__prom_getchar = (void *)PMAX_PROM_GETCHAR;
+		__prom_getenv = (void *)PMAX_PROM_GETENV;
+		__prom_printf = (void *)PMAX_PROM_PRINTF;
+		__pmax_open = (void *)PMAX_PROM_OPEN;
+		__pmax_lseek = (void *)PMAX_PROM_LSEEK;
+		__pmax_read = (void *)PMAX_PROM_READ;
+		__pmax_close = (void *)PMAX_PROM_CLOSE;
+	}
+}
+
+void __init prom_init(void)
+{
+	extern void dec_machine_halt(void);
+	static char cpu_msg[] __initdata =
+		"Sorry, this kernel is compiled for a wrong CPU type!\n";
+	static char r3k_msg[] __initdata =
+		"Please recompile with \"CONFIG_CPU_R3000 = y\".\n";
+	static char r4k_msg[] __initdata =
+		"Please recompile with \"CONFIG_CPU_R4x00 = y\".\n";
+	s32 argc = fw_arg0;
+	s32 argv = fw_arg1;
+	u32 magic = fw_arg2;
+	s32 prom_vec = fw_arg3;
+
+	/*
+	 * Determine which PROM we have
+	 * (and therefore which machine we're on!)
+	 */
+	which_prom(magic, prom_vec);
+
+	if (prom_is_rex(magic))
+		rex_clear_cache();
+
+	/* Register the early console.  */
+	register_prom_console();
+
+	/* Were we compiled with the right CPU option? */
+#if defined(CONFIG_CPU_R3000)
+	if ((current_cpu_data.cputype == CPU_R4000SC) ||
+	    (current_cpu_data.cputype == CPU_R4400SC)) {
+		printk(cpu_msg);
+		printk(r4k_msg);
+		dec_machine_halt();
+	}
+#endif
+
+#if defined(CONFIG_CPU_R4X00)
+	if ((current_cpu_data.cputype == CPU_R3000) ||
+	    (current_cpu_data.cputype == CPU_R3000A)) {
+		printk(cpu_msg);
+		printk(r3k_msg);
+		dec_machine_halt();
+	}
+#endif
+
+	prom_meminit(magic);
+	prom_identify_arch(magic);
+	prom_init_cmdline(argc, argv, magic);
+}
diff --git a/arch/mips/dec/prom/locore.S b/arch/mips/dec/prom/locore.S
new file mode 100644
index 0000000..d9acdce
--- /dev/null
+++ b/arch/mips/dec/prom/locore.S
@@ -0,0 +1,30 @@
+/*
+ * locore.S
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+
+	.text
+
+/*
+ * Simple general exception handling routine. This one is used for the
+ * Memory sizing routine for pmax machines. HK
+ */
+
+NESTED(genexcept_early, 0, sp)
+	.set	noat
+	.set	noreorder
+
+	mfc0	k0, CP0_STATUS
+	la	k1, mem_err
+
+	sw	k0, 0(k1)
+
+	mfc0	k0, CP0_EPC
+	nop
+	addiu	k0, 4		# skip the causing instruction
+	jr	k0
+	 rfe
+END(genexcept_early)
+
diff --git a/arch/mips/dec/prom/memory.c b/arch/mips/dec/prom/memory.c
new file mode 100644
index 0000000..e4f6f26
--- /dev/null
+++ b/arch/mips/dec/prom/memory.c
@@ -0,0 +1,130 @@
+/*
+ * memory.c: memory initialisation code.
+ *
+ * Copyright (C) 1998 Harald Koerfgen, Frieder Streffer and Paul M. Antoine
+ * Copyright (C) 2000, 2002  Maciej W. Rozycki
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/dec/machtype.h>
+#include <asm/dec/prom.h>
+#include <asm/page.h>
+#include <asm/sections.h>
+
+
+volatile unsigned long mem_err = 0;	/* So we know an error occurred */
+
+/*
+ * Probe memory in 4MB chunks, waiting for an error to tell us we've fallen
+ * off the end of real memory.  Only suitable for the 2100/3100's (PMAX).
+ */
+
+#define CHUNK_SIZE 0x400000
+
+static inline void pmax_setup_memory_region(void)
+{
+	volatile unsigned char *memory_page, dummy;
+	char old_handler[0x80];
+	extern char genexcept_early;
+
+	/* Install exception handler */
+	memcpy(&old_handler, (void *)(KSEG0 + 0x80), 0x80);
+	memcpy((void *)(KSEG0 + 0x80), &genexcept_early, 0x80);
+
+	/* read unmapped and uncached (KSEG1)
+	 * DECstations have at least 4MB RAM
+	 * Assume less than 480MB of RAM, as this is max for 5000/2xx
+	 * FIXME this should be replaced by the first free page!
+	 */
+	for (memory_page = (unsigned char *) KSEG1 + CHUNK_SIZE;
+	     (mem_err== 0) && (memory_page < ((unsigned char *) KSEG1+0x1E000000));
+  	     memory_page += CHUNK_SIZE) {
+		dummy = *memory_page;
+	}
+	memcpy((void *)(KSEG0 + 0x80), &old_handler, 0x80);
+
+	add_memory_region(0, (unsigned long)memory_page - KSEG1 - CHUNK_SIZE,
+			  BOOT_MEM_RAM);
+}
+
+/*
+ * Use the REX prom calls to get hold of the memory bitmap, and thence
+ * determine memory size.
+ */
+static inline void rex_setup_memory_region(void)
+{
+	int i, bitmap_size;
+	unsigned long mem_start = 0, mem_size = 0;
+	memmap *bm;
+
+	/* some free 64k */
+	bm = (memmap *)KSEG0ADDR(0x28000);
+
+	bitmap_size = rex_getbitmap(bm);
+
+	for (i = 0; i < bitmap_size; i++) {
+		/* FIXME: very simplistically only add full sets of pages */
+		if (bm->bitmap[i] == 0xff)
+			mem_size += (8 * bm->pagesize);
+		else if (!mem_size)
+			mem_start += (8 * bm->pagesize);
+		else {
+			add_memory_region(mem_start, mem_size, BOOT_MEM_RAM);
+			mem_start += mem_size + (8 * bm->pagesize);
+			mem_size = 0;
+		}
+	}
+	if (mem_size)
+		add_memory_region(mem_start, mem_size, BOOT_MEM_RAM);
+}
+
+void __init prom_meminit(u32 magic)
+{
+	if (!prom_is_rex(magic))
+		pmax_setup_memory_region();
+	else
+		rex_setup_memory_region();
+}
+
+unsigned long __init prom_free_prom_memory(void)
+{
+	unsigned long addr, end;
+
+	/*
+	 * Free everything below the kernel itself but leave
+	 * the first page reserved for the exception handlers.
+	 */
+
+#if defined(CONFIG_DECLANCE) || defined(CONFIG_DECLANCE_MODULE)
+	/*
+	 * Leave 128 KB reserved for Lance memory for
+	 * IOASIC DECstations.
+	 *
+	 * XXX: save this address for use in dec_lance.c?
+	 */
+	if (IOASIC)
+		end = __pa(&_text) - 0x00020000;
+	else
+#endif
+		end = __pa(&_text);
+
+	addr = PAGE_SIZE;
+	while (addr < end) {
+		ClearPageReserved(virt_to_page(__va(addr)));
+		set_page_count(virt_to_page(__va(addr)), 1);
+		free_page((unsigned long)__va(addr));
+		addr += PAGE_SIZE;
+	}
+
+	printk("Freeing unused PROM memory: %ldk freed\n",
+	       (end - PAGE_SIZE) >> 10);
+
+	return end - PAGE_SIZE;
+}
diff --git a/arch/mips/dec/promcon.c b/arch/mips/dec/promcon.c
new file mode 100644
index 0000000..9f0972f
--- /dev/null
+++ b/arch/mips/dec/promcon.c
@@ -0,0 +1,55 @@
+/*
+ * Wrap-around code for a console using the
+ * DECstation PROM io-routines.
+ *
+ * Copyright (c) 1998 Harald Koerfgen
+ */
+
+#include <linux/tty.h>
+#include <linux/ptrace.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/fs.h>
+
+#include <asm/dec/prom.h>
+
+static void prom_console_write(struct console *co, const char *s,
+			       unsigned count)
+{
+	unsigned i;
+
+	/*
+	 *    Now, do each character
+	 */
+	for (i = 0; i < count; i++) {
+		if (*s == 10)
+			prom_printf("%c", 13);
+		prom_printf("%c", *s++);
+	}
+}
+
+static int __init prom_console_setup(struct console *co, char *options)
+{
+	return 0;
+}
+
+static struct console sercons =
+{
+	.name	= "ttyS",
+	.write	= prom_console_write,
+	.setup	= prom_console_setup,
+	.flags	= CON_PRINTBUFFER,
+	.index	= -1,
+};
+
+/*
+ *    Register console.
+ */
+
+static int __init prom_console_init(void)
+{
+	register_console(&sercons);
+
+	return 0;
+}
+console_initcall(prom_console_init);
diff --git a/arch/mips/dec/reset.c b/arch/mips/dec/reset.c
new file mode 100644
index 0000000..7e4d34d
--- /dev/null
+++ b/arch/mips/dec/reset.c
@@ -0,0 +1,41 @@
+/*
+ * Reset a DECstation machine.
+ *
+ * Copyright (C) 199x  the Anonymous
+ * Copyright (C) 2001, 2002, 2003  Maciej W. Rozycki
+ */
+#include <linux/interrupt.h>
+#include <linux/linkage.h>
+
+#include <asm/addrspace.h>
+#include <asm/ptrace.h>
+
+typedef void ATTRIB_NORET (* noret_func_t)(void);
+
+static inline void ATTRIB_NORET back_to_prom(void)
+{
+	noret_func_t func = (void *) KSEG1ADDR(0x1fc00000);
+
+	func();
+}
+
+void ATTRIB_NORET dec_machine_restart(char *command)
+{
+	back_to_prom();
+}
+
+void ATTRIB_NORET dec_machine_halt(void)
+{
+	back_to_prom();
+}
+
+void ATTRIB_NORET dec_machine_power_off(void)
+{
+    /* DECstations don't have a software power switch */
+	back_to_prom();
+}
+
+irqreturn_t dec_intr_halt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	dec_machine_halt();
+}
diff --git a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c
new file mode 100644
index 0000000..6a69309
--- /dev/null
+++ b/arch/mips/dec/setup.c
@@ -0,0 +1,750 @@
+/*
+ * Setup the interrupt stuff.
+ *
+ * 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) 1998 Harald Koerfgen
+ * Copyright (C) 2000, 2001, 2002, 2003  Maciej W. Rozycki
+ */
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/param.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/cpu-features.h>
+#include <asm/irq.h>
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/time.h>
+#include <asm/traps.h>
+#include <asm/wbflush.h>
+
+#include <asm/dec/interrupts.h>
+#include <asm/dec/ioasic.h>
+#include <asm/dec/ioasic_addrs.h>
+#include <asm/dec/ioasic_ints.h>
+#include <asm/dec/kn01.h>
+#include <asm/dec/kn02.h>
+#include <asm/dec/kn02ba.h>
+#include <asm/dec/kn02ca.h>
+#include <asm/dec/kn03.h>
+#include <asm/dec/kn230.h>
+
+
+extern void dec_machine_restart(char *command);
+extern void dec_machine_halt(void);
+extern void dec_machine_power_off(void);
+extern irqreturn_t dec_intr_halt(int irq, void *dev_id, struct pt_regs *regs);
+
+extern asmlinkage void decstation_handle_int(void);
+
+spinlock_t ioasic_ssr_lock;
+
+volatile u32 *ioasic_base;
+unsigned long dec_kn_slot_size;
+
+/*
+ * IRQ routing and priority tables.  Priorites are set as follows:
+ *
+ * 		KN01	KN230	KN02	KN02-BA	KN02-CA	KN03
+ *
+ * MEMORY	CPU	CPU	CPU	ASIC	CPU	CPU
+ * RTC		CPU	CPU	CPU	ASIC	CPU	CPU
+ * DMA		-	-	-	ASIC	ASIC	ASIC
+ * SERIAL0	CPU	CPU	CSR	ASIC	ASIC	ASIC
+ * SERIAL1	-	-	-	ASIC	-	ASIC
+ * SCSI		CPU	CPU	CSR	ASIC	ASIC	ASIC
+ * ETHERNET	CPU	*	CSR	ASIC	ASIC	ASIC
+ * other	-	-	-	ASIC	-	-
+ * TC2		-	-	CSR	CPU	ASIC	ASIC
+ * TC1		-	-	CSR	CPU	ASIC	ASIC
+ * TC0		-	-	CSR	CPU	ASIC	ASIC
+ * other	-	CPU	-	CPU	ASIC	ASIC
+ * other	-	-	-	-	CPU	CPU
+ *
+ * * -- shared with SCSI
+ */
+
+int dec_interrupt[DEC_NR_INTS] = {
+	[0 ... DEC_NR_INTS - 1] = -1
+};
+int_ptr cpu_mask_nr_tbl[DEC_MAX_CPU_INTS][2] = {
+	{ { .i = ~0 }, { .p = dec_intr_unimplemented } },
+};
+int_ptr asic_mask_nr_tbl[DEC_MAX_ASIC_INTS][2] = {
+	{ { .i = ~0 }, { .p = asic_intr_unimplemented } },
+};
+int cpu_fpu_mask = DEC_CPU_IRQ_MASK(DEC_CPU_INR_FPU);
+
+static struct irqaction ioirq = {
+	.handler = no_action,
+	.name = "cascade",
+};
+static struct irqaction fpuirq = {
+	.handler = no_action,
+	.name = "fpu",
+};
+
+static struct irqaction busirq = {
+	.flags = SA_INTERRUPT,
+	.name = "bus error",
+};
+
+static struct irqaction haltirq = {
+	.handler = dec_intr_halt,
+	.name = "halt",
+};
+
+
+/*
+ * Bus error (DBE/IBE exceptions and bus interrupts) handling setup.
+ */
+void __init dec_be_init(void)
+{
+	switch (mips_machtype) {
+	case MACH_DS23100:	/* DS2100/DS3100 Pmin/Pmax */
+		busirq.flags |= SA_SHIRQ;
+		break;
+	case MACH_DS5000_200:	/* DS5000/200 3max */
+	case MACH_DS5000_2X0:	/* DS5000/240 3max+ */
+	case MACH_DS5900:	/* DS5900 bigmax */
+		board_be_handler = dec_ecc_be_handler;
+		busirq.handler = dec_ecc_be_interrupt;
+		dec_ecc_be_init();
+		break;
+	}
+}
+
+
+extern void dec_time_init(void);
+extern void dec_timer_setup(struct irqaction *);
+
+static void __init decstation_setup(void)
+{
+	board_be_init = dec_be_init;
+	board_time_init = dec_time_init;
+	board_timer_setup = dec_timer_setup;
+
+	wbflush_setup();
+
+	_machine_restart = dec_machine_restart;
+	_machine_halt = dec_machine_halt;
+	_machine_power_off = dec_machine_power_off;
+}
+
+early_initcall(decstation_setup);
+
+/*
+ * Machine-specific initialisation for KN01, aka DS2100 (aka Pmin)
+ * or DS3100 (aka Pmax).
+ */
+static int kn01_interrupt[DEC_NR_INTS] __initdata = {
+	[DEC_IRQ_CASCADE]	= -1,
+	[DEC_IRQ_AB_RECV]	= -1,
+	[DEC_IRQ_AB_XMIT]	= -1,
+	[DEC_IRQ_DZ11]		= DEC_CPU_IRQ_NR(KN01_CPU_INR_DZ11),
+	[DEC_IRQ_ASC]		= -1,
+	[DEC_IRQ_FLOPPY]	= -1,
+	[DEC_IRQ_FPU]		= DEC_CPU_IRQ_NR(DEC_CPU_INR_FPU),
+	[DEC_IRQ_HALT]		= -1,
+	[DEC_IRQ_ISDN]		= -1,
+	[DEC_IRQ_LANCE]		= DEC_CPU_IRQ_NR(KN01_CPU_INR_LANCE),
+	[DEC_IRQ_BUS]		= DEC_CPU_IRQ_NR(KN01_CPU_INR_BUS),
+	[DEC_IRQ_PSU]		= -1,
+	[DEC_IRQ_RTC]		= DEC_CPU_IRQ_NR(KN01_CPU_INR_RTC),
+	[DEC_IRQ_SCC0]		= -1,
+	[DEC_IRQ_SCC1]		= -1,
+	[DEC_IRQ_SII]		= DEC_CPU_IRQ_NR(KN01_CPU_INR_SII),
+	[DEC_IRQ_TC0]		= -1,
+	[DEC_IRQ_TC1]		= -1,
+	[DEC_IRQ_TC2]		= -1,
+	[DEC_IRQ_TIMER]		= -1,
+	[DEC_IRQ_VIDEO]		= DEC_CPU_IRQ_NR(KN01_CPU_INR_VIDEO),
+	[DEC_IRQ_ASC_MERR]	= -1,
+	[DEC_IRQ_ASC_ERR]	= -1,
+	[DEC_IRQ_ASC_DMA]	= -1,
+	[DEC_IRQ_FLOPPY_ERR]	= -1,
+	[DEC_IRQ_ISDN_ERR]	= -1,
+	[DEC_IRQ_ISDN_RXDMA]	= -1,
+	[DEC_IRQ_ISDN_TXDMA]	= -1,
+	[DEC_IRQ_LANCE_MERR]	= -1,
+	[DEC_IRQ_SCC0A_RXERR]	= -1,
+	[DEC_IRQ_SCC0A_RXDMA]	= -1,
+	[DEC_IRQ_SCC0A_TXERR]	= -1,
+	[DEC_IRQ_SCC0A_TXDMA]	= -1,
+	[DEC_IRQ_AB_RXERR]	= -1,
+	[DEC_IRQ_AB_RXDMA]	= -1,
+	[DEC_IRQ_AB_TXERR]	= -1,
+	[DEC_IRQ_AB_TXDMA]	= -1,
+	[DEC_IRQ_SCC1A_RXERR]	= -1,
+	[DEC_IRQ_SCC1A_RXDMA]	= -1,
+	[DEC_IRQ_SCC1A_TXERR]	= -1,
+	[DEC_IRQ_SCC1A_TXDMA]	= -1,
+};
+
+static int_ptr kn01_cpu_mask_nr_tbl[][2] __initdata = {
+	{ { .i = DEC_CPU_IRQ_MASK(KN01_CPU_INR_BUS) },
+		{ .i = DEC_CPU_IRQ_NR(KN01_CPU_INR_BUS) } },
+	{ { .i = DEC_CPU_IRQ_MASK(KN01_CPU_INR_RTC) },
+		{ .i = DEC_CPU_IRQ_NR(KN01_CPU_INR_RTC) } },
+	{ { .i = DEC_CPU_IRQ_MASK(KN01_CPU_INR_DZ11) },
+		{ .i = DEC_CPU_IRQ_NR(KN01_CPU_INR_DZ11) } },
+	{ { .i = DEC_CPU_IRQ_MASK(KN01_CPU_INR_SII) },
+		{ .i = DEC_CPU_IRQ_NR(KN01_CPU_INR_SII) } },
+	{ { .i = DEC_CPU_IRQ_MASK(KN01_CPU_INR_LANCE) },
+		{ .i = DEC_CPU_IRQ_NR(KN01_CPU_INR_LANCE) } },
+	{ { .i = DEC_CPU_IRQ_ALL },
+		{ .p = cpu_all_int } },
+};
+
+void __init dec_init_kn01(void)
+{
+	/* IRQ routing. */
+	memcpy(&dec_interrupt, &kn01_interrupt,
+		sizeof(kn01_interrupt));
+
+	/* CPU IRQ priorities. */
+	memcpy(&cpu_mask_nr_tbl, &kn01_cpu_mask_nr_tbl,
+		sizeof(kn01_cpu_mask_nr_tbl));
+
+	mips_cpu_irq_init(DEC_CPU_IRQ_BASE);
+
+}				/* dec_init_kn01 */
+
+
+/*
+ * Machine-specific initialisation for KN230, aka DS5100, aka MIPSmate.
+ */
+static int kn230_interrupt[DEC_NR_INTS] __initdata = {
+	[DEC_IRQ_CASCADE]	= -1,
+	[DEC_IRQ_AB_RECV]	= -1,
+	[DEC_IRQ_AB_XMIT]	= -1,
+	[DEC_IRQ_DZ11]		= DEC_CPU_IRQ_NR(KN230_CPU_INR_DZ11),
+	[DEC_IRQ_ASC]		= -1,
+	[DEC_IRQ_FLOPPY]	= -1,
+	[DEC_IRQ_FPU]		= DEC_CPU_IRQ_NR(DEC_CPU_INR_FPU),
+	[DEC_IRQ_HALT]		= DEC_CPU_IRQ_NR(KN230_CPU_INR_HALT),
+	[DEC_IRQ_ISDN]		= -1,
+	[DEC_IRQ_LANCE]		= DEC_CPU_IRQ_NR(KN230_CPU_INR_LANCE),
+	[DEC_IRQ_BUS]		= DEC_CPU_IRQ_NR(KN230_CPU_INR_BUS),
+	[DEC_IRQ_PSU]		= -1,
+	[DEC_IRQ_RTC]		= DEC_CPU_IRQ_NR(KN230_CPU_INR_RTC),
+	[DEC_IRQ_SCC0]		= -1,
+	[DEC_IRQ_SCC1]		= -1,
+	[DEC_IRQ_SII]		= DEC_CPU_IRQ_NR(KN230_CPU_INR_SII),
+	[DEC_IRQ_TC0]		= -1,
+	[DEC_IRQ_TC1]		= -1,
+	[DEC_IRQ_TC2]		= -1,
+	[DEC_IRQ_TIMER]		= -1,
+	[DEC_IRQ_VIDEO]		= -1,
+	[DEC_IRQ_ASC_MERR]	= -1,
+	[DEC_IRQ_ASC_ERR]	= -1,
+	[DEC_IRQ_ASC_DMA]	= -1,
+	[DEC_IRQ_FLOPPY_ERR]	= -1,
+	[DEC_IRQ_ISDN_ERR]	= -1,
+	[DEC_IRQ_ISDN_RXDMA]	= -1,
+	[DEC_IRQ_ISDN_TXDMA]	= -1,
+	[DEC_IRQ_LANCE_MERR]	= -1,
+	[DEC_IRQ_SCC0A_RXERR]	= -1,
+	[DEC_IRQ_SCC0A_RXDMA]	= -1,
+	[DEC_IRQ_SCC0A_TXERR]	= -1,
+	[DEC_IRQ_SCC0A_TXDMA]	= -1,
+	[DEC_IRQ_AB_RXERR]	= -1,
+	[DEC_IRQ_AB_RXDMA]	= -1,
+	[DEC_IRQ_AB_TXERR]	= -1,
+	[DEC_IRQ_AB_TXDMA]	= -1,
+	[DEC_IRQ_SCC1A_RXERR]	= -1,
+	[DEC_IRQ_SCC1A_RXDMA]	= -1,
+	[DEC_IRQ_SCC1A_TXERR]	= -1,
+	[DEC_IRQ_SCC1A_TXDMA]	= -1,
+};
+
+static int_ptr kn230_cpu_mask_nr_tbl[][2] __initdata = {
+	{ { .i = DEC_CPU_IRQ_MASK(KN230_CPU_INR_BUS) },
+		{ .i = DEC_CPU_IRQ_NR(KN230_CPU_INR_BUS) } },
+	{ { .i = DEC_CPU_IRQ_MASK(KN230_CPU_INR_RTC) },
+		{ .i = DEC_CPU_IRQ_NR(KN230_CPU_INR_RTC) } },
+	{ { .i = DEC_CPU_IRQ_MASK(KN230_CPU_INR_DZ11) },
+		{ .i = DEC_CPU_IRQ_NR(KN230_CPU_INR_DZ11) } },
+	{ { .i = DEC_CPU_IRQ_MASK(KN230_CPU_INR_SII) },
+		{ .i = DEC_CPU_IRQ_NR(KN230_CPU_INR_SII) } },
+	{ { .i = DEC_CPU_IRQ_ALL },
+		{ .p = cpu_all_int } },
+};
+
+void __init dec_init_kn230(void)
+{
+	/* IRQ routing. */
+	memcpy(&dec_interrupt, &kn230_interrupt,
+		sizeof(kn230_interrupt));
+
+	/* CPU IRQ priorities. */
+	memcpy(&cpu_mask_nr_tbl, &kn230_cpu_mask_nr_tbl,
+		sizeof(kn230_cpu_mask_nr_tbl));
+
+	mips_cpu_irq_init(DEC_CPU_IRQ_BASE);
+
+}				/* dec_init_kn230 */
+
+
+/*
+ * Machine-specific initialisation for KN02, aka DS5000/200, aka 3max.
+ */
+static int kn02_interrupt[DEC_NR_INTS] __initdata = {
+	[DEC_IRQ_CASCADE]	= DEC_CPU_IRQ_NR(KN02_CPU_INR_CASCADE),
+	[DEC_IRQ_AB_RECV]	= -1,
+	[DEC_IRQ_AB_XMIT]	= -1,
+	[DEC_IRQ_DZ11]		= KN02_IRQ_NR(KN02_CSR_INR_DZ11),
+	[DEC_IRQ_ASC]		= KN02_IRQ_NR(KN02_CSR_INR_ASC),
+	[DEC_IRQ_FLOPPY]	= -1,
+	[DEC_IRQ_FPU]		= DEC_CPU_IRQ_NR(DEC_CPU_INR_FPU),
+	[DEC_IRQ_HALT]		= -1,
+	[DEC_IRQ_ISDN]		= -1,
+	[DEC_IRQ_LANCE]		= KN02_IRQ_NR(KN02_CSR_INR_LANCE),
+	[DEC_IRQ_BUS]		= DEC_CPU_IRQ_NR(KN02_CPU_INR_BUS),
+	[DEC_IRQ_PSU]		= -1,
+	[DEC_IRQ_RTC]		= DEC_CPU_IRQ_NR(KN02_CPU_INR_RTC),
+	[DEC_IRQ_SCC0]		= -1,
+	[DEC_IRQ_SCC1]		= -1,
+	[DEC_IRQ_SII]		= -1,
+	[DEC_IRQ_TC0]		= KN02_IRQ_NR(KN02_CSR_INR_TC0),
+	[DEC_IRQ_TC1]		= KN02_IRQ_NR(KN02_CSR_INR_TC1),
+	[DEC_IRQ_TC2]		= KN02_IRQ_NR(KN02_CSR_INR_TC2),
+	[DEC_IRQ_TIMER]		= -1,
+	[DEC_IRQ_VIDEO]		= -1,
+	[DEC_IRQ_ASC_MERR]	= -1,
+	[DEC_IRQ_ASC_ERR]	= -1,
+	[DEC_IRQ_ASC_DMA]	= -1,
+	[DEC_IRQ_FLOPPY_ERR]	= -1,
+	[DEC_IRQ_ISDN_ERR]	= -1,
+	[DEC_IRQ_ISDN_RXDMA]	= -1,
+	[DEC_IRQ_ISDN_TXDMA]	= -1,
+	[DEC_IRQ_LANCE_MERR]	= -1,
+	[DEC_IRQ_SCC0A_RXERR]	= -1,
+	[DEC_IRQ_SCC0A_RXDMA]	= -1,
+	[DEC_IRQ_SCC0A_TXERR]	= -1,
+	[DEC_IRQ_SCC0A_TXDMA]	= -1,
+	[DEC_IRQ_AB_RXERR]	= -1,
+	[DEC_IRQ_AB_RXDMA]	= -1,
+	[DEC_IRQ_AB_TXERR]	= -1,
+	[DEC_IRQ_AB_TXDMA]	= -1,
+	[DEC_IRQ_SCC1A_RXERR]	= -1,
+	[DEC_IRQ_SCC1A_RXDMA]	= -1,
+	[DEC_IRQ_SCC1A_TXERR]	= -1,
+	[DEC_IRQ_SCC1A_TXDMA]	= -1,
+};
+
+static int_ptr kn02_cpu_mask_nr_tbl[][2] __initdata = {
+	{ { .i = DEC_CPU_IRQ_MASK(KN02_CPU_INR_BUS) },
+		{ .i = DEC_CPU_IRQ_NR(KN02_CPU_INR_BUS) } },
+	{ { .i = DEC_CPU_IRQ_MASK(KN02_CPU_INR_RTC) },
+		{ .i = DEC_CPU_IRQ_NR(KN02_CPU_INR_RTC) } },
+	{ { .i = DEC_CPU_IRQ_MASK(KN02_CPU_INR_CASCADE) },
+		{ .p = kn02_io_int } },
+	{ { .i = DEC_CPU_IRQ_ALL },
+		{ .p = cpu_all_int } },
+};
+
+static int_ptr kn02_asic_mask_nr_tbl[][2] __initdata = {
+	{ { .i = KN02_IRQ_MASK(KN02_CSR_INR_DZ11) },
+		{ .i = KN02_IRQ_NR(KN02_CSR_INR_DZ11) } },
+	{ { .i = KN02_IRQ_MASK(KN02_CSR_INR_ASC) },
+		{ .i = KN02_IRQ_NR(KN02_CSR_INR_ASC) } },
+	{ { .i = KN02_IRQ_MASK(KN02_CSR_INR_LANCE) },
+		{ .i = KN02_IRQ_NR(KN02_CSR_INR_LANCE) } },
+	{ { .i = KN02_IRQ_MASK(KN02_CSR_INR_TC2) },
+		{ .i = KN02_IRQ_NR(KN02_CSR_INR_TC2) } },
+	{ { .i = KN02_IRQ_MASK(KN02_CSR_INR_TC1) },
+		{ .i = KN02_IRQ_NR(KN02_CSR_INR_TC1) } },
+	{ { .i = KN02_IRQ_MASK(KN02_CSR_INR_TC0) },
+		{ .i = KN02_IRQ_NR(KN02_CSR_INR_TC0) } },
+	{ { .i = KN02_IRQ_ALL },
+		{ .p = kn02_all_int } },
+};
+
+void __init dec_init_kn02(void)
+{
+	/* IRQ routing. */
+	memcpy(&dec_interrupt, &kn02_interrupt,
+		sizeof(kn02_interrupt));
+
+	/* CPU IRQ priorities. */
+	memcpy(&cpu_mask_nr_tbl, &kn02_cpu_mask_nr_tbl,
+		sizeof(kn02_cpu_mask_nr_tbl));
+
+	/* KN02 CSR IRQ priorities. */
+	memcpy(&asic_mask_nr_tbl, &kn02_asic_mask_nr_tbl,
+		sizeof(kn02_asic_mask_nr_tbl));
+
+	mips_cpu_irq_init(DEC_CPU_IRQ_BASE);
+	init_kn02_irqs(KN02_IRQ_BASE);
+
+}				/* dec_init_kn02 */
+
+
+/*
+ * Machine-specific initialisation for KN02-BA, aka DS5000/1xx
+ * (xx = 20, 25, 33), aka 3min.  Also applies to KN04(-BA), aka
+ * DS5000/150, aka 4min.
+ */
+static int kn02ba_interrupt[DEC_NR_INTS] __initdata = {
+	[DEC_IRQ_CASCADE]	= DEC_CPU_IRQ_NR(KN02BA_CPU_INR_CASCADE),
+	[DEC_IRQ_AB_RECV]	= -1,
+	[DEC_IRQ_AB_XMIT]	= -1,
+	[DEC_IRQ_DZ11]		= -1,
+	[DEC_IRQ_ASC]		= IO_IRQ_NR(KN02BA_IO_INR_ASC),
+	[DEC_IRQ_FLOPPY]	= -1,
+	[DEC_IRQ_FPU]		= DEC_CPU_IRQ_NR(DEC_CPU_INR_FPU),
+	[DEC_IRQ_HALT]		= DEC_CPU_IRQ_NR(KN02BA_CPU_INR_HALT),
+	[DEC_IRQ_ISDN]		= -1,
+	[DEC_IRQ_LANCE]		= IO_IRQ_NR(KN02BA_IO_INR_LANCE),
+	[DEC_IRQ_BUS]		= IO_IRQ_NR(KN02BA_IO_INR_BUS),
+	[DEC_IRQ_PSU]		= IO_IRQ_NR(KN02BA_IO_INR_PSU),
+	[DEC_IRQ_RTC]		= IO_IRQ_NR(KN02BA_IO_INR_RTC),
+	[DEC_IRQ_SCC0]		= IO_IRQ_NR(KN02BA_IO_INR_SCC0),
+	[DEC_IRQ_SCC1]		= IO_IRQ_NR(KN02BA_IO_INR_SCC1),
+	[DEC_IRQ_SII]		= -1,
+	[DEC_IRQ_TC0]		= DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC0),
+	[DEC_IRQ_TC1]		= DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC1),
+	[DEC_IRQ_TC2]		= DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC2),
+	[DEC_IRQ_TIMER]		= -1,
+	[DEC_IRQ_VIDEO]		= -1,
+	[DEC_IRQ_ASC_MERR]	= IO_IRQ_NR(IO_INR_ASC_MERR),
+	[DEC_IRQ_ASC_ERR]	= IO_IRQ_NR(IO_INR_ASC_ERR),
+	[DEC_IRQ_ASC_DMA]	= IO_IRQ_NR(IO_INR_ASC_DMA),
+	[DEC_IRQ_FLOPPY_ERR]	= -1,
+	[DEC_IRQ_ISDN_ERR]	= -1,
+	[DEC_IRQ_ISDN_RXDMA]	= -1,
+	[DEC_IRQ_ISDN_TXDMA]	= -1,
+	[DEC_IRQ_LANCE_MERR]	= IO_IRQ_NR(IO_INR_LANCE_MERR),
+	[DEC_IRQ_SCC0A_RXERR]	= IO_IRQ_NR(IO_INR_SCC0A_RXERR),
+	[DEC_IRQ_SCC0A_RXDMA]	= IO_IRQ_NR(IO_INR_SCC0A_RXDMA),
+	[DEC_IRQ_SCC0A_TXERR]	= IO_IRQ_NR(IO_INR_SCC0A_TXERR),
+	[DEC_IRQ_SCC0A_TXDMA]	= IO_IRQ_NR(IO_INR_SCC0A_TXDMA),
+	[DEC_IRQ_AB_RXERR]	= -1,
+	[DEC_IRQ_AB_RXDMA]	= -1,
+	[DEC_IRQ_AB_TXERR]	= -1,
+	[DEC_IRQ_AB_TXDMA]	= -1,
+	[DEC_IRQ_SCC1A_RXERR]	= IO_IRQ_NR(IO_INR_SCC1A_RXERR),
+	[DEC_IRQ_SCC1A_RXDMA]	= IO_IRQ_NR(IO_INR_SCC1A_RXDMA),
+	[DEC_IRQ_SCC1A_TXERR]	= IO_IRQ_NR(IO_INR_SCC1A_TXERR),
+	[DEC_IRQ_SCC1A_TXDMA]	= IO_IRQ_NR(IO_INR_SCC1A_TXDMA),
+};
+
+static int_ptr kn02ba_cpu_mask_nr_tbl[][2] __initdata = {
+	{ { .i = DEC_CPU_IRQ_MASK(KN02BA_CPU_INR_CASCADE) },
+		{ .p = kn02xa_io_int } },
+	{ { .i = DEC_CPU_IRQ_MASK(KN02BA_CPU_INR_TC2) },
+		{ .i = DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC2) } },
+	{ { .i = DEC_CPU_IRQ_MASK(KN02BA_CPU_INR_TC1) },
+		{ .i = DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC1) } },
+	{ { .i = DEC_CPU_IRQ_MASK(KN02BA_CPU_INR_TC0) },
+		{ .i = DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC0) } },
+	{ { .i = DEC_CPU_IRQ_ALL },
+		{ .p = cpu_all_int } },
+};
+
+static int_ptr kn02ba_asic_mask_nr_tbl[][2] __initdata = {
+	{ { .i = IO_IRQ_MASK(KN02BA_IO_INR_BUS) },
+		{ .i = IO_IRQ_NR(KN02BA_IO_INR_BUS) } },
+	{ { .i = IO_IRQ_MASK(KN02BA_IO_INR_RTC) },
+		{ .i = IO_IRQ_NR(KN02BA_IO_INR_RTC) } },
+	{ { .i = IO_IRQ_DMA },
+		{ .p = asic_dma_int } },
+	{ { .i = IO_IRQ_MASK(KN02BA_IO_INR_SCC0) },
+		{ .i = IO_IRQ_NR(KN02BA_IO_INR_SCC0) } },
+	{ { .i = IO_IRQ_MASK(KN02BA_IO_INR_SCC1) },
+		{ .i = IO_IRQ_NR(KN02BA_IO_INR_SCC1) } },
+	{ { .i = IO_IRQ_MASK(KN02BA_IO_INR_ASC) },
+		{ .i = IO_IRQ_NR(KN02BA_IO_INR_ASC) } },
+	{ { .i = IO_IRQ_MASK(KN02BA_IO_INR_LANCE) },
+		{ .i = IO_IRQ_NR(KN02BA_IO_INR_LANCE) } },
+	{ { .i = IO_IRQ_ALL },
+		{ .p = asic_all_int } },
+};
+
+void __init dec_init_kn02ba(void)
+{
+	/* IRQ routing. */
+	memcpy(&dec_interrupt, &kn02ba_interrupt,
+		sizeof(kn02ba_interrupt));
+
+	/* CPU IRQ priorities. */
+	memcpy(&cpu_mask_nr_tbl, &kn02ba_cpu_mask_nr_tbl,
+		sizeof(kn02ba_cpu_mask_nr_tbl));
+
+	/* I/O ASIC IRQ priorities. */
+	memcpy(&asic_mask_nr_tbl, &kn02ba_asic_mask_nr_tbl,
+		sizeof(kn02ba_asic_mask_nr_tbl));
+
+	mips_cpu_irq_init(DEC_CPU_IRQ_BASE);
+	init_ioasic_irqs(IO_IRQ_BASE);
+
+}				/* dec_init_kn02ba */
+
+
+/*
+ * Machine-specific initialisation for KN02-CA, aka DS5000/xx,
+ * (xx = 20, 25, 33), aka MAXine.  Also applies to KN04(-CA), aka
+ * DS5000/50, aka 4MAXine.
+ */
+static int kn02ca_interrupt[DEC_NR_INTS] __initdata = {
+	[DEC_IRQ_CASCADE]	= DEC_CPU_IRQ_NR(KN02CA_CPU_INR_CASCADE),
+	[DEC_IRQ_AB_RECV]	= IO_IRQ_NR(KN02CA_IO_INR_AB_RECV),
+	[DEC_IRQ_AB_XMIT]	= IO_IRQ_NR(KN02CA_IO_INR_AB_XMIT),
+	[DEC_IRQ_DZ11]		= -1,
+	[DEC_IRQ_ASC]		= IO_IRQ_NR(KN02CA_IO_INR_ASC),
+	[DEC_IRQ_FLOPPY]	= IO_IRQ_NR(KN02CA_IO_INR_FLOPPY),
+	[DEC_IRQ_FPU]		= DEC_CPU_IRQ_NR(DEC_CPU_INR_FPU),
+	[DEC_IRQ_HALT]		= DEC_CPU_IRQ_NR(KN02CA_CPU_INR_HALT),
+	[DEC_IRQ_ISDN]		= IO_IRQ_NR(KN02CA_IO_INR_ISDN),
+	[DEC_IRQ_LANCE]		= IO_IRQ_NR(KN02CA_IO_INR_LANCE),
+	[DEC_IRQ_BUS]		= DEC_CPU_IRQ_NR(KN02CA_CPU_INR_BUS),
+	[DEC_IRQ_PSU]		= -1,
+	[DEC_IRQ_RTC]		= DEC_CPU_IRQ_NR(KN02CA_CPU_INR_RTC),
+	[DEC_IRQ_SCC0]		= IO_IRQ_NR(KN02CA_IO_INR_SCC0),
+	[DEC_IRQ_SCC1]		= -1,
+	[DEC_IRQ_SII]		= -1,
+	[DEC_IRQ_TC0]		= IO_IRQ_NR(KN02CA_IO_INR_TC0),
+	[DEC_IRQ_TC1]		= IO_IRQ_NR(KN02CA_IO_INR_TC1),
+	[DEC_IRQ_TC2]		= -1,
+	[DEC_IRQ_TIMER]		= DEC_CPU_IRQ_NR(KN02CA_CPU_INR_TIMER),
+	[DEC_IRQ_VIDEO]		= IO_IRQ_NR(KN02CA_IO_INR_VIDEO),
+	[DEC_IRQ_ASC_MERR]	= IO_IRQ_NR(IO_INR_ASC_MERR),
+	[DEC_IRQ_ASC_ERR]	= IO_IRQ_NR(IO_INR_ASC_ERR),
+	[DEC_IRQ_ASC_DMA]	= IO_IRQ_NR(IO_INR_ASC_DMA),
+	[DEC_IRQ_FLOPPY_ERR]	= IO_IRQ_NR(IO_INR_FLOPPY_ERR),
+	[DEC_IRQ_ISDN_ERR]	= IO_IRQ_NR(IO_INR_ISDN_ERR),
+	[DEC_IRQ_ISDN_RXDMA]	= IO_IRQ_NR(IO_INR_ISDN_RXDMA),
+	[DEC_IRQ_ISDN_TXDMA]	= IO_IRQ_NR(IO_INR_ISDN_TXDMA),
+	[DEC_IRQ_LANCE_MERR]	= IO_IRQ_NR(IO_INR_LANCE_MERR),
+	[DEC_IRQ_SCC0A_RXERR]	= IO_IRQ_NR(IO_INR_SCC0A_RXERR),
+	[DEC_IRQ_SCC0A_RXDMA]	= IO_IRQ_NR(IO_INR_SCC0A_RXDMA),
+	[DEC_IRQ_SCC0A_TXERR]	= IO_IRQ_NR(IO_INR_SCC0A_TXERR),
+	[DEC_IRQ_SCC0A_TXDMA]	= IO_IRQ_NR(IO_INR_SCC0A_TXDMA),
+	[DEC_IRQ_AB_RXERR]	= IO_IRQ_NR(IO_INR_AB_RXERR),
+	[DEC_IRQ_AB_RXDMA]	= IO_IRQ_NR(IO_INR_AB_RXDMA),
+	[DEC_IRQ_AB_TXERR]	= IO_IRQ_NR(IO_INR_AB_TXERR),
+	[DEC_IRQ_AB_TXDMA]	= IO_IRQ_NR(IO_INR_AB_TXDMA),
+	[DEC_IRQ_SCC1A_RXERR]	= -1,
+	[DEC_IRQ_SCC1A_RXDMA]	= -1,
+	[DEC_IRQ_SCC1A_TXERR]	= -1,
+	[DEC_IRQ_SCC1A_TXDMA]	= -1,
+};
+
+static int_ptr kn02ca_cpu_mask_nr_tbl[][2] __initdata = {
+	{ { .i = DEC_CPU_IRQ_MASK(KN02CA_CPU_INR_BUS) },
+		{ .i = DEC_CPU_IRQ_NR(KN02CA_CPU_INR_BUS) } },
+	{ { .i = DEC_CPU_IRQ_MASK(KN02CA_CPU_INR_RTC) },
+		{ .i = DEC_CPU_IRQ_NR(KN02CA_CPU_INR_RTC) } },
+	{ { .i = DEC_CPU_IRQ_MASK(KN02CA_CPU_INR_CASCADE) },
+		{ .p = kn02xa_io_int } },
+	{ { .i = DEC_CPU_IRQ_ALL },
+		{ .p = cpu_all_int } },
+};
+
+static int_ptr kn02ca_asic_mask_nr_tbl[][2] __initdata = {
+	{ { .i = IO_IRQ_DMA },
+		{ .p = asic_dma_int } },
+	{ { .i = IO_IRQ_MASK(KN02CA_IO_INR_SCC0) },
+		{ .i = IO_IRQ_NR(KN02CA_IO_INR_SCC0) } },
+	{ { .i = IO_IRQ_MASK(KN02CA_IO_INR_ASC) },
+		{ .i = IO_IRQ_NR(KN02CA_IO_INR_ASC) } },
+	{ { .i = IO_IRQ_MASK(KN02CA_IO_INR_LANCE) },
+		{ .i = IO_IRQ_NR(KN02CA_IO_INR_LANCE) } },
+	{ { .i = IO_IRQ_MASK(KN02CA_IO_INR_TC1) },
+		{ .i = IO_IRQ_NR(KN02CA_IO_INR_TC1) } },
+	{ { .i = IO_IRQ_MASK(KN02CA_IO_INR_TC0) },
+		{ .i = IO_IRQ_NR(KN02CA_IO_INR_TC0) } },
+	{ { .i = IO_IRQ_ALL },
+		{ .p = asic_all_int } },
+};
+
+void __init dec_init_kn02ca(void)
+{
+	/* IRQ routing. */
+	memcpy(&dec_interrupt, &kn02ca_interrupt,
+		sizeof(kn02ca_interrupt));
+
+	/* CPU IRQ priorities. */
+	memcpy(&cpu_mask_nr_tbl, &kn02ca_cpu_mask_nr_tbl,
+		sizeof(kn02ca_cpu_mask_nr_tbl));
+
+	/* I/O ASIC IRQ priorities. */
+	memcpy(&asic_mask_nr_tbl, &kn02ca_asic_mask_nr_tbl,
+		sizeof(kn02ca_asic_mask_nr_tbl));
+
+	mips_cpu_irq_init(DEC_CPU_IRQ_BASE);
+	init_ioasic_irqs(IO_IRQ_BASE);
+
+}				/* dec_init_kn02ca */
+
+
+/*
+ * Machine-specific initialisation for KN03, aka DS5000/240,
+ * aka 3max+ and DS5900, aka BIGmax.  Also applies to KN05, aka
+ * DS5000/260, aka 4max+ and DS5900/260.
+ */
+static int kn03_interrupt[DEC_NR_INTS] __initdata = {
+	[DEC_IRQ_CASCADE]	= DEC_CPU_IRQ_NR(KN03_CPU_INR_CASCADE),
+	[DEC_IRQ_AB_RECV]	= -1,
+	[DEC_IRQ_AB_XMIT]	= -1,
+	[DEC_IRQ_DZ11]		= -1,
+	[DEC_IRQ_ASC]		= IO_IRQ_NR(KN03_IO_INR_ASC),
+	[DEC_IRQ_FLOPPY]	= -1,
+	[DEC_IRQ_FPU]		= DEC_CPU_IRQ_NR(DEC_CPU_INR_FPU),
+	[DEC_IRQ_HALT]		= DEC_CPU_IRQ_NR(KN03_CPU_INR_HALT),
+	[DEC_IRQ_ISDN]		= -1,
+	[DEC_IRQ_LANCE]		= IO_IRQ_NR(KN03_IO_INR_LANCE),
+	[DEC_IRQ_BUS]		= DEC_CPU_IRQ_NR(KN03_CPU_INR_BUS),
+	[DEC_IRQ_PSU]		= IO_IRQ_NR(KN03_IO_INR_PSU),
+	[DEC_IRQ_RTC]		= DEC_CPU_IRQ_NR(KN03_CPU_INR_RTC),
+	[DEC_IRQ_SCC0]		= IO_IRQ_NR(KN03_IO_INR_SCC0),
+	[DEC_IRQ_SCC1]		= IO_IRQ_NR(KN03_IO_INR_SCC1),
+	[DEC_IRQ_SII]		= -1,
+	[DEC_IRQ_TC0]		= IO_IRQ_NR(KN03_IO_INR_TC0),
+	[DEC_IRQ_TC1]		= IO_IRQ_NR(KN03_IO_INR_TC1),
+	[DEC_IRQ_TC2]		= IO_IRQ_NR(KN03_IO_INR_TC2),
+	[DEC_IRQ_TIMER]		= -1,
+	[DEC_IRQ_VIDEO]		= -1,
+	[DEC_IRQ_ASC_MERR]	= IO_IRQ_NR(IO_INR_ASC_MERR),
+	[DEC_IRQ_ASC_ERR]	= IO_IRQ_NR(IO_INR_ASC_ERR),
+	[DEC_IRQ_ASC_DMA]	= IO_IRQ_NR(IO_INR_ASC_DMA),
+	[DEC_IRQ_FLOPPY_ERR]	= -1,
+	[DEC_IRQ_ISDN_ERR]	= -1,
+	[DEC_IRQ_ISDN_RXDMA]	= -1,
+	[DEC_IRQ_ISDN_TXDMA]	= -1,
+	[DEC_IRQ_LANCE_MERR]	= IO_IRQ_NR(IO_INR_LANCE_MERR),
+	[DEC_IRQ_SCC0A_RXERR]	= IO_IRQ_NR(IO_INR_SCC0A_RXERR),
+	[DEC_IRQ_SCC0A_RXDMA]	= IO_IRQ_NR(IO_INR_SCC0A_RXDMA),
+	[DEC_IRQ_SCC0A_TXERR]	= IO_IRQ_NR(IO_INR_SCC0A_TXERR),
+	[DEC_IRQ_SCC0A_TXDMA]	= IO_IRQ_NR(IO_INR_SCC0A_TXDMA),
+	[DEC_IRQ_AB_RXERR]	= -1,
+	[DEC_IRQ_AB_RXDMA]	= -1,
+	[DEC_IRQ_AB_TXERR]	= -1,
+	[DEC_IRQ_AB_TXDMA]	= -1,
+	[DEC_IRQ_SCC1A_RXERR]	= IO_IRQ_NR(IO_INR_SCC1A_RXERR),
+	[DEC_IRQ_SCC1A_RXDMA]	= IO_IRQ_NR(IO_INR_SCC1A_RXDMA),
+	[DEC_IRQ_SCC1A_TXERR]	= IO_IRQ_NR(IO_INR_SCC1A_TXERR),
+	[DEC_IRQ_SCC1A_TXDMA]	= IO_IRQ_NR(IO_INR_SCC1A_TXDMA),
+};
+
+static int_ptr kn03_cpu_mask_nr_tbl[][2] __initdata = {
+	{ { .i = DEC_CPU_IRQ_MASK(KN03_CPU_INR_BUS) },
+		{ .i = DEC_CPU_IRQ_NR(KN03_CPU_INR_BUS) } },
+	{ { .i = DEC_CPU_IRQ_MASK(KN03_CPU_INR_RTC) },
+		{ .i = DEC_CPU_IRQ_NR(KN03_CPU_INR_RTC) } },
+	{ { .i = DEC_CPU_IRQ_MASK(KN03_CPU_INR_CASCADE) },
+		{ .p = kn03_io_int } },
+	{ { .i = DEC_CPU_IRQ_ALL },
+		{ .p = cpu_all_int } },
+};
+
+static int_ptr kn03_asic_mask_nr_tbl[][2] __initdata = {
+	{ { .i = IO_IRQ_DMA },
+		{ .p = asic_dma_int } },
+	{ { .i = IO_IRQ_MASK(KN03_IO_INR_SCC0) },
+		{ .i = IO_IRQ_NR(KN03_IO_INR_SCC0) } },
+	{ { .i = IO_IRQ_MASK(KN03_IO_INR_SCC1) },
+		{ .i = IO_IRQ_NR(KN03_IO_INR_SCC1) } },
+	{ { .i = IO_IRQ_MASK(KN03_IO_INR_ASC) },
+		{ .i = IO_IRQ_NR(KN03_IO_INR_ASC) } },
+	{ { .i = IO_IRQ_MASK(KN03_IO_INR_LANCE) },
+		{ .i = IO_IRQ_NR(KN03_IO_INR_LANCE) } },
+	{ { .i = IO_IRQ_MASK(KN03_IO_INR_TC2) },
+		{ .i = IO_IRQ_NR(KN03_IO_INR_TC2) } },
+	{ { .i = IO_IRQ_MASK(KN03_IO_INR_TC1) },
+		{ .i = IO_IRQ_NR(KN03_IO_INR_TC1) } },
+	{ { .i = IO_IRQ_MASK(KN03_IO_INR_TC0) },
+		{ .i = IO_IRQ_NR(KN03_IO_INR_TC0) } },
+	{ { .i = IO_IRQ_ALL },
+		{ .p = asic_all_int } },
+};
+
+void __init dec_init_kn03(void)
+{
+	/* IRQ routing. */
+	memcpy(&dec_interrupt, &kn03_interrupt,
+		sizeof(kn03_interrupt));
+
+	/* CPU IRQ priorities. */
+	memcpy(&cpu_mask_nr_tbl, &kn03_cpu_mask_nr_tbl,
+		sizeof(kn03_cpu_mask_nr_tbl));
+
+	/* I/O ASIC IRQ priorities. */
+	memcpy(&asic_mask_nr_tbl, &kn03_asic_mask_nr_tbl,
+		sizeof(kn03_asic_mask_nr_tbl));
+
+	mips_cpu_irq_init(DEC_CPU_IRQ_BASE);
+	init_ioasic_irqs(IO_IRQ_BASE);
+
+}				/* dec_init_kn03 */
+
+
+void __init arch_init_irq(void)
+{
+	switch (mips_machtype) {
+	case MACH_DS23100:	/* DS2100/DS3100 Pmin/Pmax */
+		dec_init_kn01();
+		break;
+	case MACH_DS5100:	/* DS5100 MIPSmate */
+		dec_init_kn230();
+		break;
+	case MACH_DS5000_200:	/* DS5000/200 3max */
+		dec_init_kn02();
+		break;
+	case MACH_DS5000_1XX:	/* DS5000/1xx 3min */
+		dec_init_kn02ba();
+		break;
+	case MACH_DS5000_2X0:	/* DS5000/240 3max+ */
+	case MACH_DS5900:	/* DS5900 bigmax */
+		dec_init_kn03();
+		break;
+	case MACH_DS5000_XX:	/* Personal DS5000/xx */
+		dec_init_kn02ca();
+		break;
+	case MACH_DS5800:	/* DS5800 Isis */
+		panic("Don't know how to set this up!");
+		break;
+	case MACH_DS5400:	/* DS5400 MIPSfair */
+		panic("Don't know how to set this up!");
+		break;
+	case MACH_DS5500:	/* DS5500 MIPSfair-2 */
+		panic("Don't know how to set this up!");
+		break;
+	}
+	set_except_vector(0, decstation_handle_int);
+
+	/* Free the FPU interrupt if the exception is present. */
+	if (!cpu_has_nofpuex) {
+		cpu_fpu_mask = 0;
+		dec_interrupt[DEC_IRQ_FPU] = -1;
+	}
+
+	/* Register board interrupts: FPU and cascade. */
+	if (dec_interrupt[DEC_IRQ_FPU] >= 0)
+		setup_irq(dec_interrupt[DEC_IRQ_FPU], &fpuirq);
+	if (dec_interrupt[DEC_IRQ_CASCADE] >= 0)
+		setup_irq(dec_interrupt[DEC_IRQ_CASCADE], &ioirq);
+
+	/* Register the bus error interrupt. */
+	if (dec_interrupt[DEC_IRQ_BUS] >= 0 && busirq.handler)
+		setup_irq(dec_interrupt[DEC_IRQ_BUS], &busirq);
+
+	/* Register the HALT interrupt. */
+	if (dec_interrupt[DEC_IRQ_HALT] >= 0)
+		setup_irq(dec_interrupt[DEC_IRQ_HALT], &haltirq);
+}
+
+EXPORT_SYMBOL(ioasic_base);
+EXPORT_SYMBOL(dec_kn_slot_size);
+EXPORT_SYMBOL(dec_interrupt);
diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c
new file mode 100644
index 0000000..dc7091c
--- /dev/null
+++ b/arch/mips/dec/time.c
@@ -0,0 +1,200 @@
+/*
+ *  linux/arch/mips/dec/time.c
+ *
+ *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
+ *  Copyright (C) 2000, 2003  Maciej W. Rozycki
+ *
+ * This file contains the time handling details for PC-style clocks as
+ * found in some MIPS systems.
+ *
+ */
+#include <linux/bcd.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mc146818rtc.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/param.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/time.h>
+#include <linux/types.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/div64.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/sections.h>
+#include <asm/time.h>
+
+#include <asm/dec/interrupts.h>
+#include <asm/dec/ioasic.h>
+#include <asm/dec/ioasic_addrs.h>
+#include <asm/dec/machtype.h>
+
+
+static unsigned long dec_rtc_get_time(void)
+{
+	unsigned int year, mon, day, hour, min, sec, real_year;
+	int i;
+
+	/* The Linux interpretation of the DS1287 clock register contents:
+	 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
+	 * RTC registers show the second which has precisely just started.
+	 * Let's hope other operating systems interpret the RTC the same way.
+	 */
+	/* read RTC exactly on falling edge of update flag */
+	for (i = 0; i < 1000000; i++)	/* may take up to 1 second... */
+		if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
+			break;
+	for (i = 0; i < 1000000; i++)	/* must try at least 2.228 ms */
+		if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
+			break;
+	/* Isn't this overkill?  UIP above should guarantee consistency */
+	do {
+		sec = CMOS_READ(RTC_SECONDS);
+		min = CMOS_READ(RTC_MINUTES);
+		hour = CMOS_READ(RTC_HOURS);
+		day = CMOS_READ(RTC_DAY_OF_MONTH);
+		mon = CMOS_READ(RTC_MONTH);
+		year = CMOS_READ(RTC_YEAR);
+	} while (sec != CMOS_READ(RTC_SECONDS));
+	if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+		sec = BCD2BIN(sec);
+		min = BCD2BIN(min);
+		hour = BCD2BIN(hour);
+		day = BCD2BIN(day);
+		mon = BCD2BIN(mon);
+		year = BCD2BIN(year);
+	}
+	/*
+	 * The PROM will reset the year to either '72 or '73.
+	 * Therefore we store the real year separately, in one
+	 * of unused BBU RAM locations.
+	 */
+	real_year = CMOS_READ(RTC_DEC_YEAR);
+	year += real_year - 72 + 2000;
+
+	return mktime(year, mon, day, hour, min, sec);
+}
+
+/*
+ * In order to set the CMOS clock precisely, dec_rtc_set_mmss has to
+ * be called 500 ms after the second nowtime has started, because when
+ * nowtime is written into the registers of the CMOS clock, it will
+ * jump to the next second precisely 500 ms later.  Check the Dallas
+ * DS1287 data sheet for details.
+ */
+static int dec_rtc_set_mmss(unsigned long nowtime)
+{
+	int retval = 0;
+	int real_seconds, real_minutes, cmos_minutes;
+	unsigned char save_control, save_freq_select;
+
+	/* tell the clock it's being set */
+	save_control = CMOS_READ(RTC_CONTROL);
+	CMOS_WRITE((save_control | RTC_SET), RTC_CONTROL);
+
+	/* stop and reset prescaler */
+	save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
+	CMOS_WRITE((save_freq_select | RTC_DIV_RESET2), RTC_FREQ_SELECT);
+
+	cmos_minutes = CMOS_READ(RTC_MINUTES);
+	if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
+		cmos_minutes = BCD2BIN(cmos_minutes);
+
+	/*
+	 * since we're only adjusting minutes and seconds,
+	 * don't interfere with hour overflow. This avoids
+	 * messing with unknown time zones but requires your
+	 * RTC not to be off by more than 15 minutes
+	 */
+	real_seconds = nowtime % 60;
+	real_minutes = nowtime / 60;
+	if (((abs(real_minutes - cmos_minutes) + 15) / 30) & 1)
+		real_minutes += 30;	/* correct for half hour time zone */
+	real_minutes %= 60;
+
+	if (abs(real_minutes - cmos_minutes) < 30) {
+		if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+			real_seconds = BIN2BCD(real_seconds);
+			real_minutes = BIN2BCD(real_minutes);
+		}
+		CMOS_WRITE(real_seconds, RTC_SECONDS);
+		CMOS_WRITE(real_minutes, RTC_MINUTES);
+	} else {
+		printk(KERN_WARNING
+		       "set_rtc_mmss: can't update from %d to %d\n",
+		       cmos_minutes, real_minutes);
+		retval = -1;
+	}
+
+	/* The following flags have to be released exactly in this order,
+	 * otherwise the DS1287 will not reset the oscillator and will not
+	 * update precisely 500 ms later.  You won't find this mentioned
+	 * in the Dallas Semiconductor data sheets, but who believes data
+	 * sheets anyway ...                           -- Markus Kuhn
+	 */
+	CMOS_WRITE(save_control, RTC_CONTROL);
+	CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
+
+	return retval;
+}
+
+
+static int dec_timer_state(void)
+{
+	return (CMOS_READ(RTC_REG_C) & RTC_PF) != 0;
+}
+
+static void dec_timer_ack(void)
+{
+	CMOS_READ(RTC_REG_C);			/* Ack the RTC interrupt.  */
+}
+
+static unsigned int dec_ioasic_hpt_read(void)
+{
+	/*
+	 * The free-running counter is 32-bit which is good for about
+	 * 2 minutes, 50 seconds at possible count rates of up to 25MHz.
+	 */
+	return ioasic_read(IO_REG_FCTR);
+}
+
+static void dec_ioasic_hpt_init(unsigned int count)
+{
+	ioasic_write(IO_REG_FCTR, ioasic_read(IO_REG_FCTR) - count);
+}
+
+
+void __init dec_time_init(void)
+{
+	rtc_get_time = dec_rtc_get_time;
+	rtc_set_mmss = dec_rtc_set_mmss;
+
+	mips_timer_state = dec_timer_state;
+	mips_timer_ack = dec_timer_ack;
+
+	if (!cpu_has_counter && IOASIC) {
+		/* For pre-R4k systems we use the I/O ASIC's counter.  */
+		mips_hpt_read = dec_ioasic_hpt_read;
+		mips_hpt_init = dec_ioasic_hpt_init;
+	}
+
+	/* Set up the rate of periodic DS1287 interrupts.  */
+	CMOS_WRITE(RTC_REF_CLCK_32KHZ | (16 - LOG_2_HZ), RTC_REG_A);
+}
+
+EXPORT_SYMBOL(do_settimeofday);
+
+void __init dec_timer_setup(struct irqaction *irq)
+{
+	setup_irq(dec_interrupt[DEC_IRQ_RTC], irq);
+
+	/* Enable periodic DS1287 interrupts.  */
+	CMOS_WRITE(CMOS_READ(RTC_REG_B) | RTC_PIE, RTC_REG_B);
+}
diff --git a/arch/mips/dec/wbflush.c b/arch/mips/dec/wbflush.c
new file mode 100644
index 0000000..925c052
--- /dev/null
+++ b/arch/mips/dec/wbflush.c
@@ -0,0 +1,94 @@
+/*
+ * Setup the right wbflush routine for the different DECstations.
+ *
+ * Created with information from:
+ *      DECstation 3100 Desktop Workstation Functional Specification
+ *      DECstation 5000/200 KN02 System Module Functional Specification
+ *      mipsel-linux-objdump --disassemble vmunix | grep "wbflush" :-)
+ *
+ * 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) 1998 Harald Koerfgen
+ * Copyright (C) 2002 Maciej W. Rozycki
+ */
+
+#include <linux/init.h>
+
+#include <asm/bootinfo.h>
+#include <asm/system.h>
+#include <asm/wbflush.h>
+
+static void wbflush_kn01(void);
+static void wbflush_kn210(void);
+static void wbflush_mips(void);
+
+void (*__wbflush) (void);
+
+void __init wbflush_setup(void)
+{
+	switch (mips_machtype) {
+	case MACH_DS23100:
+	case MACH_DS5000_200:	/* DS5000 3max */
+		__wbflush = wbflush_kn01;
+		break;
+	case MACH_DS5100:	/* DS5100 MIPSMATE */
+		__wbflush = wbflush_kn210;
+		break;
+	case MACH_DS5000_1XX:	/* DS5000/100 3min */
+	case MACH_DS5000_XX:	/* Personal DS5000/2x */
+	case MACH_DS5000_2X0:	/* DS5000/240 3max+ */
+	case MACH_DS5900:	/* DS5900 bigmax */
+	default:
+		__wbflush = wbflush_mips;
+		break;
+	}
+}
+
+/*
+ * For the DS3100 and DS5000/200 the R2020/R3220 writeback buffer functions
+ * as part of Coprocessor 0.
+ */
+static void wbflush_kn01(void)
+{
+    asm(".set\tpush\n\t"
+	".set\tnoreorder\n\t"
+	"1:\tbc0f\t1b\n\t"
+	"nop\n\t"
+	".set\tpop");
+}
+
+/*
+ * For the DS5100 the writeback buffer seems to be a part of Coprocessor 3.
+ * But CP3 has to enabled first.
+ */
+static void wbflush_kn210(void)
+{
+    asm(".set\tpush\n\t"
+	".set\tnoreorder\n\t"
+	"mfc0\t$2,$12\n\t"
+	"lui\t$3,0x8000\n\t"
+	"or\t$3,$2,$3\n\t"
+	"mtc0\t$3,$12\n\t"
+	"nop\n"
+	"1:\tbc3f\t1b\n\t"
+	"nop\n\t"
+	"mtc0\t$2,$12\n\t"
+	"nop\n\t"
+	".set\tpop"
+	: : : "$2", "$3");
+}
+
+/*
+ * I/O ASIC systems use a standard writeback buffer that gets flushed
+ * upon an uncached read.
+ */
+static void wbflush_mips(void)
+{
+	__fast_iob();
+}
+
+#include <linux/module.h>
+
+EXPORT_SYMBOL(__wbflush);
diff --git a/arch/mips/defconfig b/arch/mips/defconfig
new file mode 100644
index 0000000..d55fe66
--- /dev/null
+++ b/arch/mips/defconfig
@@ -0,0 +1,962 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Wed Jan 26 02:48:59 2005
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS64 is not set
+# CONFIG_64BIT is not set
+CONFIG_MIPS32=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+CONFIG_SGI_IP22=y
+# CONFIG_SOC_AU1X00 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_ARC=y
+CONFIG_DMA_NONCOHERENT=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_IRQ_CPU=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_ARC32=y
+CONFIG_BOOT_ELF32=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+CONFIG_ARC_CONSOLE=y
+CONFIG_ARC_PROMLIB=y
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+CONFIG_CPU_R5000=y
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_BOARD_SCACHE=y
+CONFIG_IP22_CPU_SCACHE=y
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+# CONFIG_EISA is not set
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=m
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_ISCSI_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_SGIWD93_SCSI=y
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=m
+CONFIG_IP_TCPDIAG_IPV6=y
+
+#
+# IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_CT_ACCT=y
+CONFIG_IP_NF_CONNTRACK_MARK=y
+# CONFIG_IP_NF_CT_PROTO_SCTP is not set
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_REALM=m
+CONFIG_IP_NF_MATCH_SCTP=m
+CONFIG_IP_NF_MATCH_COMMENT=m
+CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_CONNMARK=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_TARGET_NOTRACK=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_LIMIT=m
+CONFIG_IP6_NF_MATCH_MAC=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_MULTIPORT=m
+CONFIG_IP6_NF_MATCH_OWNER=m
+CONFIG_IP6_NF_MATCH_MARK=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_AHESP=m
+CONFIG_IP6_NF_MATCH_LENGTH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_TARGET_MARK=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+CONFIG_NET_DIVERT=y
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_QOS=y
+CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+# CONFIG_CLS_U32_PERF is not set
+# CONFIG_NET_CLS_IND is not set
+# CONFIG_CLS_U32_MARK is not set
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_CLS_POLICE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_ETHERTAP=m
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+CONFIG_SGISEEQ=y
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE 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=m
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input 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
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=m
+CONFIG_MOUSE_SERIAL=m
+# CONFIG_MOUSE_VSXXXAA 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_IP22_ZILOG=m
+CONFIG_SERIAL_CORE=m
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_INDYDOG=m
+# CONFIG_RTC is not set
+CONFIG_SGI_DS1286=m
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+CONFIG_RAW_DRIVER=m
+CONFIG_MAX_RAW_DEVS=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_SGI_NEWPORT_CONSOLE=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+CONFIG_LOGO_SGI_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=m
+# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+# CONFIG_XFS_RT is not set
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+# CONFIG_XFS_POSIX_ACL is not set
+CONFIG_MINIX_FS=m
+# CONFIG_ROMFS_FS is not set
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=m
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=m
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+CONFIG_EFS_FS=m
+# 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=m
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V4 is not set
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_SMB_NLS_REMOTE="cp437"
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_NCP_FS is not set
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC32=m
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/galileo-boards/ev96100/Makefile b/arch/mips/galileo-boards/ev96100/Makefile
new file mode 100644
index 0000000..58c02f9
--- /dev/null
+++ b/arch/mips/galileo-boards/ev96100/Makefile
@@ -0,0 +1,9 @@
+#
+#  Copyright 2000 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc.
+#     	ppopov@mvista.com or source@mvista.com
+#
+# Makefile for the Galileo EV96100 board.
+#
+
+obj-y		+= init.o irq.o puts.o reset.o time.o int-handler.o setup.o
diff --git a/arch/mips/galileo-boards/ev96100/init.c b/arch/mips/galileo-boards/ev96100/init.c
new file mode 100644
index 0000000..a01fe9b
--- /dev/null
+++ b/arch/mips/galileo-boards/ev96100/init.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * This file was derived from Carsten Langgaard's
+ * arch/mips/mips-boards/generic/generic.c
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/gt64120.h>
+
+
+/* Environment variable */
+
+typedef struct {
+	char *name;
+	char *val;
+} t_env_var;
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+
+int init_debug = 0;
+
+char * __init prom_getcmdline(void)
+{
+	return &(arcs_cmdline[0]);
+}
+
+unsigned long __init prom_free_prom_memory(void)
+{
+	return 0;
+}
+
+void  __init prom_init_cmdline(void)
+{
+	char *cp;
+	int actr;
+
+	actr = 1; /* Always ignore argv[0] */
+
+	cp = &(arcs_cmdline[0]);
+	while(actr < prom_argc) {
+	        strcpy(cp, prom_argv[actr]);
+		cp += strlen(prom_argv[actr]);
+		*cp++ = ' ';
+		actr++;
+	}
+	if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
+		--cp;
+	*cp = '\0';
+}
+
+char *prom_getenv(char *envname)
+{
+	/*
+	 * Return a pointer to the given environment variable.
+	 */
+
+	t_env_var *env = (t_env_var *) prom_envp;
+	int i;
+
+	i = strlen(envname);
+
+	while (env->name) {
+		if (strncmp(envname, env->name, i) == 0) {
+			return (env->val);
+		}
+		env++;
+	}
+	return (NULL);
+}
+
+static inline unsigned char str2hexnum(unsigned char c)
+{
+	if (c >= '0' && c <= '9')
+		return c - '0';
+	if (c >= 'a' && c <= 'f')
+		return c - 'a' + 10;
+	return 0;		/* foo */
+}
+
+static inline void str2eaddr(unsigned char *ea, unsigned char *str)
+{
+	int i;
+
+	for (i = 0; i < 6; i++) {
+		unsigned char num;
+
+		if ((*str == '.') || (*str == ':'))
+			str++;
+		num = str2hexnum(*str++) << 4;
+		num |= (str2hexnum(*str++));
+		ea[i] = num;
+	}
+}
+
+int get_ethernet_addr(char *ethernet_addr)
+{
+	char *ethaddr_str;
+
+	ethaddr_str = prom_getenv("ethaddr");
+	if (!ethaddr_str) {
+		printk("ethaddr not set in boot prom\n");
+		return -1;
+	}
+	str2eaddr(ethernet_addr, ethaddr_str);
+
+	if (init_debug > 1) {
+		int i;
+		printk("get_ethernet_addr: ");
+		for (i = 0; i < 5; i++)
+			printk("%02x:",
+			       (unsigned char) *(ethernet_addr + i));
+		printk("%02x\n", *(ethernet_addr + i));
+	}
+
+	return 0;
+}
+
+const char *get_system_type(void)
+{
+	return "Galileo EV96100";
+}
+
+void __init prom_init(void)
+{
+	volatile unsigned char *uart;
+	char ppbuf[8];
+
+	prom_argc = fw_arg0;
+	prom_argv = (char **) fw_arg1;
+	prom_envp = (char **) fw_arg2;
+
+	mips_machgroup = MACH_GROUP_GALILEO;
+	mips_machtype = MACH_EV96100;
+
+	prom_init_cmdline();
+
+	/* 32 MB upgradable */
+	add_memory_region(0, 32 << 20, BOOT_MEM_RAM);
+}
diff --git a/arch/mips/galileo-boards/ev96100/int-handler.S b/arch/mips/galileo-boards/ev96100/int-handler.S
new file mode 100644
index 0000000..ff4d10a
--- /dev/null
+++ b/arch/mips/galileo-boards/ev96100/int-handler.S
@@ -0,0 +1,33 @@
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+	.set	noat
+	.align	5
+
+NESTED(ev96100IRQ, PT_SIZE, sp)
+	SAVE_ALL
+	CLI				# Important: mark KERNEL mode !
+
+	mfc0	t0, CP0_CAUSE		# get pending interrupts
+	mfc0	t1, CP0_STATUS		# get enabled interrupts
+	and	t0, t1			# isolate allowed ones
+
+	# FIX ME add R7000 extensions
+	andi	t0,0xff00		# isolate pending bits
+	andi	a0, t0, CAUSEF_IP7
+	beq	a0, zero, 1f
+	move	a0, sp
+	jal	mips_timer_interrupt
+	j	ret_from_irq
+
+1:	beqz	t0, 3f			# spurious interrupt
+
+	move	a0, t0
+	move	a1, sp
+	jal	ev96100_cpu_irq
+	j	ret_from_irq
+
+3:	j	spurious_interrupt
+	END(ev96100IRQ)
diff --git a/arch/mips/galileo-boards/ev96100/irq.c b/arch/mips/galileo-boards/ev96100/irq.c
new file mode 100644
index 0000000..97bf094
--- /dev/null
+++ b/arch/mips/galileo-boards/ev96100/irq.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * This file was derived from Carsten Langgaard's
+ * arch/mips/mips-boards/atlas/atlas_int.c.
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <asm/irq_cpu.h>
+
+extern asmlinkage void ev96100IRQ(void);
+
+static inline unsigned int ffz8(unsigned int word)
+{
+	unsigned long k;
+
+	k = 7;
+	if (word & 0x0fUL) { k -= 4;  word <<= 4;  }
+	if (word & 0x30UL) { k -= 2;  word <<= 2;  }
+	if (word & 0x40UL) { k -= 1; }
+
+	return k;
+}
+
+asmlinkage void ev96100_cpu_irq(unsigned int pendin)
+{
+	do_IRQ(ffz8(pending >> 8), regs);
+}
+
+void __init arch_init_irq(void)
+{
+	set_except_vector(0, ev96100IRQ);
+	mips_cpu_irq_init(0);
+}
diff --git a/arch/mips/galileo-boards/ev96100/puts.c b/arch/mips/galileo-boards/ev96100/puts.c
new file mode 100644
index 0000000..49dc6d1
--- /dev/null
+++ b/arch/mips/galileo-boards/ev96100/puts.c
@@ -0,0 +1,138 @@
+
+/*
+ * Debug routines which directly access the uart.
+ */
+
+#include <linux/types.h>
+#include <asm/gt64120.h>
+
+
+//#define SERIAL_BASE    EV96100_UART0_REGS_BASE
+#define SERIAL_BASE    0xBD000020
+#define NS16550_BASE   SERIAL_BASE
+
+#define SERA_CMD       0x0D
+#define SERA_DATA      0x08
+//#define SERB_CMD       0x05
+#define SERB_CMD       20
+#define SERB_DATA      0x00
+#define TX_BUSY        0x20
+
+#define TIMEOUT    0xffff
+#undef SLOW_DOWN
+
+static const char digits[16] = "0123456789abcdef";
+static volatile unsigned char *const com1 = (unsigned char *) SERIAL_BASE;
+
+
+#ifdef SLOW_DOWN
+static inline void slow_down()
+{
+	int k;
+	for (k = 0; k < 10000; k++);
+}
+#else
+#define slow_down()
+#endif
+
+void putch(const unsigned char c)
+{
+	unsigned char ch;
+	int i = 0;
+
+	do {
+		ch = com1[SERB_CMD];
+		slow_down();
+		i++;
+		if (i > TIMEOUT) {
+			break;
+		}
+	} while (0 == (ch & TX_BUSY));
+	com1[SERB_DATA] = c;
+}
+
+void putchar(const unsigned char c)
+{
+	unsigned char ch;
+	int i = 0;
+
+	do {
+		ch = com1[SERB_CMD];
+		slow_down();
+		i++;
+		if (i > TIMEOUT) {
+			break;
+		}
+	} while (0 == (ch & TX_BUSY));
+	com1[SERB_DATA] = c;
+}
+
+void puts(unsigned char *cp)
+{
+	unsigned char ch;
+	int i = 0;
+
+	while (*cp) {
+		do {
+			ch = com1[SERB_CMD];
+			slow_down();
+			i++;
+			if (i > TIMEOUT) {
+				break;
+			}
+		} while (0 == (ch & TX_BUSY));
+		com1[SERB_DATA] = *cp++;
+	}
+	putch('\r');
+	putch('\n');
+}
+
+void fputs(unsigned char *cp)
+{
+	unsigned char ch;
+	int i = 0;
+
+	while (*cp) {
+
+		do {
+			ch = com1[SERB_CMD];
+			slow_down();
+			i++;
+			if (i > TIMEOUT) {
+				break;
+			}
+		} while (0 == (ch & TX_BUSY));
+		com1[SERB_DATA] = *cp++;
+	}
+}
+
+
+void put64(uint64_t ul)
+{
+	int cnt;
+	unsigned ch;
+
+	cnt = 16;		/* 16 nibbles in a 64 bit long */
+	putch('0');
+	putch('x');
+	do {
+		cnt--;
+		ch = (unsigned char) (ul >> cnt * 4) & 0x0F;
+		putch(digits[ch]);
+	} while (cnt > 0);
+}
+
+void put32(unsigned u)
+{
+	int cnt;
+	unsigned ch;
+
+	cnt = 8;		/* 8 nibbles in a 32 bit long */
+	putch('0');
+	putch('x');
+	do {
+		cnt--;
+		ch = (unsigned char) (u >> cnt * 4) & 0x0F;
+		putch(digits[ch]);
+	} while (cnt > 0);
+}
diff --git a/arch/mips/galileo-boards/ev96100/reset.c b/arch/mips/galileo-boards/ev96100/reset.c
new file mode 100644
index 0000000..5ef9b7f
--- /dev/null
+++ b/arch/mips/galileo-boards/ev96100/reset.c
@@ -0,0 +1,70 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Galileo EV96100 reset routines.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * This file was derived from Carsten Langgaard's
+ * arch/mips/mips-boards/generic/reset.c
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <asm/gt64120.h>
+
+static void mips_machine_restart(char *command);
+static void mips_machine_halt(void);
+
+static void mips_machine_restart(char *command)
+{
+	set_c0_status(ST0_BEV | ST0_ERL);
+	change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+	flush_cache_all();
+	write_c0_wired(0);
+	__asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
+	while (1);
+}
+
+static void mips_machine_halt(void)
+{
+	printk(KERN_NOTICE "You can safely turn off the power\n");
+	while (1)
+		__asm__(".set\tmips3\n\t"
+	                "wait\n\t"
+			".set\tmips0");
+}
+
+void mips_reboot_setup(void)
+{
+	_machine_restart = mips_machine_restart;
+	_machine_halt = mips_machine_halt;
+}
diff --git a/arch/mips/galileo-boards/ev96100/setup.c b/arch/mips/galileo-boards/ev96100/setup.c
new file mode 100644
index 0000000..28bd908
--- /dev/null
+++ b/arch/mips/galileo-boards/ev96100/setup.c
@@ -0,0 +1,162 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Galileo EV96100 setup.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * This file was derived from Carsten Langgaard's
+ * arch/mips/mips-boards/atlas/atlas_setup.c.
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/pci.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
+#include <asm/irq.h>
+#include <asm/delay.h>
+#include <asm/gt64120.h>
+#include <asm/galileo-boards/ev96100int.h>
+
+
+extern char *__init prom_getcmdline(void);
+
+extern void mips_reboot_setup(void);
+
+unsigned char mac_0_1[12];
+
+static void __init ev96100_setup(void)
+{
+	unsigned int config = read_c0_config();
+	unsigned int status = read_c0_status();
+	unsigned int info = read_c0_info();
+	u32 tmp;
+
+	char *argptr;
+
+	clear_c0_status(ST0_FR);
+
+	if (config & 0x8)
+		printk("Secondary cache is enabled\n");
+	else
+		printk("Secondary cache is disabled\n");
+
+	if (status & (1 << 27))
+		printk("User-mode cache ops enabled\n");
+	else
+		printk("User-mode cache ops disabled\n");
+
+	printk("CP0 info reg: %x\n", (unsigned) info);
+	if (info & (1 << 28))
+		printk("burst mode Scache RAMS\n");
+	else
+		printk("pipelined Scache RAMS\n");
+
+	if (info & 0x1)
+		printk("Atomic Enable is set\n");
+
+	argptr = prom_getcmdline();
+#ifdef CONFIG_SERIAL_CONSOLE
+	if (strstr(argptr, "console=") == NULL) {
+		argptr = prom_getcmdline();
+		strcat(argptr, " console=ttyS0,115200");
+	}
+#endif
+
+	mips_reboot_setup();
+
+	set_io_port_base(KSEG1);
+	ioport_resource.start = GT_PCI_IO_BASE;
+	ioport_resource.end = GT_PCI_IO_BASE + 0x01ffffff;
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+#endif
+
+
+	/*
+	 * Setup GT controller master bit so we can do config cycles
+	 */
+
+	/* Clear cause register bits */
+	GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
+				     GT_INTRCAUSE_TARABORT0_BIT));
+	/* Setup address */
+	GT_WRITE(GT_PCI0_CFGADDR_OFS,
+		 (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) |
+		 (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
+		 ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) |
+		 GT_PCI0_CFGADDR_CONFIGEN_BIT);
+
+	udelay(2);
+	tmp = GT_READ(GT_PCI0_CFGDATA_OFS);
+
+	tmp |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+		PCI_COMMAND_MASTER | PCI_COMMAND_SERR);
+	GT_WRITE(GT_PCI0_CFGADDR_OFS,
+		 (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) |
+		 (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
+		 ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) |
+		 GT_PCI0_CFGADDR_CONFIGEN_BIT);
+	udelay(2);
+	GT_WRITE(GT_PCI0_CFGDATA_OFS, tmp);
+
+	/* Setup address */
+	GT_WRITE(GT_PCI0_CFGADDR_OFS,
+		 (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) |
+		 (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
+		 ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) |
+		 GT_PCI0_CFGADDR_CONFIGEN_BIT);
+
+	udelay(2);
+	tmp = GT_READ(GT_PCI0_CFGDATA_OFS);
+}
+
+early_initcall(ev96100_setup);
+
+unsigned short get_gt_devid(void)
+{
+	u32 gt_devid;
+
+	/* Figure out if this is a gt96100 or gt96100A */
+	GT_WRITE(GT_PCI0_CFGADDR_OFS,
+		 (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) |
+		 (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
+		 ((PCI_VENDOR_ID / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) |
+		 GT_PCI0_CFGADDR_CONFIGEN_BIT);
+
+	udelay(4);
+	gt_devid = GT_READ(GT_PCI0_CFGDATA_OFS);
+
+	return gt_devid >> 16;
+}
diff --git a/arch/mips/galileo-boards/ev96100/time.c b/arch/mips/galileo-boards/ev96100/time.c
new file mode 100644
index 0000000..bff5b1c
--- /dev/null
+++ b/arch/mips/galileo-boards/ev96100/time.c
@@ -0,0 +1,89 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Galileo EV96100 rtc routines.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * This file was derived from Carsten Langgaard's
+ * arch/mips/mips-boards/atlas/atlas_rtc.c.
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/timex.h>
+
+#include <asm/mipsregs.h>
+#include <asm/ptrace.h>
+#include <asm/time.h>
+
+
+#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
+
+extern volatile unsigned long wall_jiffies;
+unsigned long missed_heart_beats = 0;
+
+static unsigned long r4k_offset; /* Amount to increment compare reg each time */
+static unsigned long r4k_cur;    /* What counter should be at next timer irq */
+
+static inline void ack_r4ktimer(unsigned long newval)
+{
+	write_c0_compare(newval);
+}
+
+/*
+ * There are a lot of conceptually broken versions of the MIPS timer interrupt
+ * handler floating around.  This one is rather different, but the algorithm
+ * is probably more robust.
+ */
+void mips_timer_interrupt(struct pt_regs *regs)
+{
+        int irq = 7; /* FIX ME */
+
+	if (r4k_offset == 0) {
+            goto null;
+        }
+
+	do {
+		kstat_this_cpu.irqs[irq]++;
+		do_timer(regs);
+#ifndef CONFIG_SMP
+		update_process_times(user_mode(regs));
+#endif
+		r4k_cur += r4k_offset;
+		ack_r4ktimer(r4k_cur);
+
+	} while (((unsigned long)read_c0_count()
+                    - r4k_cur) < 0x7fffffff);
+	return;
+
+null:
+	ack_r4ktimer(0);
+}
diff --git a/arch/mips/gt64120/common/Makefile b/arch/mips/gt64120/common/Makefile
new file mode 100644
index 0000000..eba5051
--- /dev/null
+++ b/arch/mips/gt64120/common/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for common code of gt64120-based boards.
+#
+
+obj-y	 		+= time.o
+obj-$(CONFIG_PCI)	+= pci.o
diff --git a/arch/mips/gt64120/common/pci.c b/arch/mips/gt64120/common/pci.c
new file mode 100644
index 0000000..e9e5419
--- /dev/null
+++ b/arch/mips/gt64120/common/pci.c
@@ -0,0 +1,147 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ * Galileo Evaluation Boards PCI support.
+ *
+ * The general-purpose functions to read/write and configure the GT64120A's
+ * PCI registers (function names start with pci0 or pci1) are either direct
+ * copies of functions written by Galileo Technology, or are modifications
+ * of their functions to work with Linux 2.4 vs Linux 2.2.  These functions
+ * are Copyright - Galileo Technology.
+ *
+ * Other functions are derived from other MIPS PCI implementations, or were
+ * written by RidgeRun, Inc,  Copyright (C) 2000 RidgeRun, Inc.
+ *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <asm/gt64120.h>
+
+#define SELF 0
+
+/*
+ * pciXReadConfigReg  - Read from a PCI configuration register
+ *                    - Make sure the GT is configured as a master before
+ *                      reading from another device on the PCI.
+ *                   - The function takes care of Big/Little endian conversion.
+ * INPUTS:   regOffset: The register offset as it apears in the GT spec (or PCI
+ *                        spec)
+ *           pciDevNum: The device number needs to be addressed.
+ * RETURNS: data , if the data == 0xffffffff check the master abort bit in the
+ *                 cause register to make sure the data is valid
+ *
+ *  Configuration Address 0xCF8:
+ *
+ *       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
+ *  |congif|Reserved|  Bus |Device|Function|Register|00|
+ *  |Enable|        |Number|Number| Number | Number |  |    <=field Name
+ *
+ */
+static unsigned int pci0ReadConfigReg(int offset, struct pci_dev *device)
+{
+	unsigned int DataForRegCf8;
+	unsigned int data;
+
+	DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |
+			 (PCI_FUNC(device->devfn) << 8) |
+			 (offset & ~0x3)) | 0x80000000;
+	GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);
+
+	/*
+	 * The casual observer might wonder why the READ is duplicated here,
+	 * rather than immediately following the WRITE, and just have the swap
+	 * in the "if".  That's because there is a latency problem with trying
+	 * to read immediately after setting up the address register.  The "if"
+	 * check gives enough time for the address to stabilize, so the READ
+	 * can work.
+	 */
+	if (PCI_SLOT(device->devfn) == SELF)	/* This board */
+		return GT_READ(GT_PCI0_CFGDATA_OFS);
+	else		/* PCI is little endian so swap the Data. */
+		return __GT_READ(GT_PCI0_CFGDATA_OFS);
+}
+
+/*
+ * pciXWriteConfigReg - Write to a PCI configuration register
+ *                    - Make sure the GT is configured as a master before
+ *                      writingto another device on the PCI.
+ *                    - The function takes care of Big/Little endian conversion.
+ * Inputs:   unsigned int regOffset: The register offset as it apears in the
+ *           GT spec
+ *                   (or any other PCI device spec)
+ *           pciDevNum: The device number needs to be addressed.
+ *
+ *  Configuration Address 0xCF8:
+ *
+ *       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
+ *  |congif|Reserved|  Bus |Device|Function|Register|00|
+ *  |Enable|        |Number|Number| Number | Number |  |    <=field Name
+ *
+ */
+static void pci0WriteConfigReg(unsigned int offset,
+			       struct pci_dev *device, unsigned int data)
+{
+	unsigned int DataForRegCf8;
+
+	DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |
+			 (PCI_FUNC(device->devfn) << 8) |
+			 (offset & ~0x3)) | 0x80000000;
+	GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);
+
+	if (PCI_SLOT(device->devfn) == SELF) 	/* This board */
+		GT_WRITE(GT_PCI0_CFGDATA_OFS, data);
+	else 			/* configuration Transaction over the pci. */
+		__GT_WRITE(GT_PCI0_CFGDATA_OFS, data);
+}
+
+extern struct pci_ops gt64120_pci_ops;
+
+void __init pcibios_init(void)
+{
+	u32 tmp;
+	struct pci_dev controller;
+
+	controller.devfn = SELF;
+
+	tmp = GT_READ(GT_PCI0_CMD_OFS);		/* Huh??? -- Ralf  */
+	tmp = GT_READ(GT_PCI0_BARE_OFS);
+
+	/*
+	 * You have to enable bus mastering to configure any other
+	 * card on the bus.
+	 */
+	tmp = pci0ReadConfigReg(PCI_COMMAND, &controller);
+	tmp |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
+	pci0WriteConfigReg(PCI_COMMAND, &controller, tmp);
+
+	/*
+	 *  Reset PCI I/O and PCI MEM values to ones supported by EVM.
+	 */
+	ioport_resource.start	= GT_PCI_IO_BASE;
+	ioport_resource.end	= GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1;
+	iomem_resource.start	= GT_PCI_MEM_BASE;
+	iomem_resource.end	= GT_PCI_MEM_BASE + GT_PCI_MEM_SIZE - 1;
+
+	pci_scan_bus(0, &gt64120_pci_ops, NULL);
+}
diff --git a/arch/mips/gt64120/common/time.c b/arch/mips/gt64120/common/time.c
new file mode 100644
index 0000000..2287b59
--- /dev/null
+++ b/arch/mips/gt64120/common/time.c
@@ -0,0 +1,100 @@
+/*
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Galileo Technology chip interrupt handler
+ */
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <asm/ptrace.h>
+#include <asm/gt64120.h>
+
+/*
+ * These are interrupt handlers for the GT on-chip interrupts.  They all come
+ * in to the MIPS on a single interrupt line, and have to be handled and ack'ed
+ * differently than other MIPS interrupts.
+ */
+
+static void gt64120_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned int irq_src, int_high_src, irq_src_mask, int_high_src_mask;
+	int handled = 0;
+
+	irq_src = GT_READ(GT_INTRCAUSE_OFS);
+	irq_src_mask = GT_READ(GT_INTRMASK_OFS);
+	int_high_src = GT_READ(GT_HINTRCAUSE_OFS);
+	int_high_src_mask = GT_READ(GT_HINTRMASK_OFS);
+	irq_src = irq_src & irq_src_mask;
+	int_high_src = int_high_src & int_high_src_mask;
+
+	if (irq_src & 0x00000800) {	/* Check for timer interrupt */
+		handled = 1;
+		irq_src &= ~0x00000800;
+		do_timer(regs);
+#ifndef CONFIG_SMP
+		update_process_times(user_mode(regs));
+#endif
+	}
+
+	GT_WRITE(GT_INTRCAUSE_OFS, 0);
+	GT_WRITE(GT_HINTRCAUSE_OFS, 0);
+}
+
+/*
+ * Initializes timer using galileo's built in timer.
+ */
+#ifdef CONFIG_SYSCLK_100
+#define Sys_clock (100 * 1000000)	// 100 MHz
+#endif
+#ifdef CONFIG_SYSCLK_83
+#define Sys_clock (83.333 * 1000000)	// 83.333 MHz
+#endif
+#ifdef CONFIG_SYSCLK_75
+#define Sys_clock (75 * 1000000)	// 75 MHz
+#endif
+
+/*
+ * This will ignore the standard MIPS timer interrupt handler that is passed in
+ * as *irq (=irq0 in ../kernel/time.c).  We will do our own timer interrupt
+ * handling.
+ */
+void gt64120_time_init(void)
+{
+	static struct irqaction timer;
+
+	/* Disable timer first */
+	GT_WRITE(GT_TC_CONTROL_OFS, 0);
+	/* Load timer value for 100 Hz */
+	GT_WRITE(GT_TC3_OFS, Sys_clock / 100);
+
+	/*
+	 * Create the IRQ structure entry for the timer.  Since we're too early
+	 * in the boot process to use the "request_irq()" call, we'll hard-code
+	 * the values to the correct interrupt line.
+	 */
+	timer.handler = gt64120_irq;
+	timer.flags = SA_SHIRQ | SA_INTERRUPT;
+	timer.name = "timer";
+	timer.dev_id = NULL;
+	timer.next = NULL;
+	timer.mask = CPU_MASK_NONE;
+	irq_desc[GT_TIMER].action = &timer;
+
+	enable_irq(GT_TIMER);
+
+	/* Enable timer ints */
+	GT_WRITE(GT_TC_CONTROL_OFS, 0xc0);
+	/* clear Cause register first */
+	GT_WRITE(GT_INTRCAUSE_OFS, 0x0);
+	/* Unmask timer int */
+	GT_WRITE(GT_INTRMASK_OFS, 0x800);
+	/* Clear High int register */
+	GT_WRITE(GT_HINTRCAUSE_OFS, 0x0);
+	/* Mask All interrupts at High cause interrupt */
+	GT_WRITE(GT_HINTRMASK_OFS, 0x0);
+}
diff --git a/arch/mips/gt64120/ev64120/Makefile b/arch/mips/gt64120/ev64120/Makefile
new file mode 100644
index 0000000..ebe91c5
--- /dev/null
+++ b/arch/mips/gt64120/ev64120/Makefile
@@ -0,0 +1,11 @@
+#
+#  Copyright 2000 RidgeRun, Inc.
+#  Author: RidgeRun, Inc.
+#     	glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+#
+# Makefile for the Galileo EV64120 board.
+#
+
+obj-y	+= int-handler.o irq.o promcon.o reset.o serialGT.o setup.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/gt64120/ev64120/int-handler.S b/arch/mips/gt64120/ev64120/int-handler.S
new file mode 100644
index 0000000..752435f
--- /dev/null
+++ b/arch/mips/gt64120/ev64120/int-handler.S
@@ -0,0 +1,113 @@
+/*
+ * int-handler.S
+ *
+ * Based on the cobalt handler.
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/*
+ * galileo_handle_int -
+ *      We check for the timer first, then check PCI ints A and D.
+ *      Then check for serial IRQ and fall through.
+ */
+		.align	5
+		.set	reorder
+		.set	noat
+		NESTED(galileo_handle_int, PT_SIZE, sp)
+		SAVE_ALL
+		CLI
+		.set	at
+		mfc0	t0,CP0_CAUSE
+		mfc0	t2,CP0_STATUS
+
+		and	t0,t2
+
+		andi	t1,t0,STATUSF_IP4 /* int2 hardware line (timer) */
+		bnez	t1,ll_gt64120_irq
+		andi	t1,t0,STATUSF_IP2 /* int0 hardware line */
+		bnez	t1,ll_pci_intA
+		andi	t1,t0,STATUSF_IP5 /* int3 hardware line */
+		bnez	t1,ll_pci_intD
+		andi	t1,t0,STATUSF_IP6 /* int4 hardware line */
+		bnez	t1,ll_serial_irq
+		andi	t1,t0,STATUSF_IP7 /* compare int */
+		bnez	t1,ll_compare_irq
+		nop
+
+    /* wrong alarm or masked ... */
+		j	spurious_interrupt
+		nop
+		END(galileo_handle_int)
+
+
+		.align	5
+		.set	reorder
+ll_gt64120_irq:
+		li	a0,4
+		move	a1,sp
+		jal	do_IRQ
+		nop
+		j	ret_from_irq
+		nop
+
+		.align	5
+		.set	reorder
+ll_compare_irq:
+		li 	a0,7
+		move	a1,sp
+		jal	do_IRQ
+		nop
+		j	ret_from_irq
+		nop
+
+		.align	5
+		.set	reorder
+ll_pci_intA:
+		move	a0,sp
+		jal	pci_intA
+		nop
+		j	ret_from_irq
+		nop
+
+#if 0
+		.align	5
+		.set	reorder
+ll_pci_intB:
+		move 	a0,sp
+		jal	pci_intB
+		nop
+		j	ret_from_irq
+		nop
+
+		.align	5
+		.set	reorder
+ll_pci_intC:
+		move 	a0,sp
+		jal	pci_intC
+		nop
+		j	ret_from_irq
+		nop
+#endif
+
+		.align	5
+		.set	reorder
+ll_pci_intD:
+		move 	a0,sp
+		jal	pci_intD
+		nop
+		j	ret_from_irq
+		nop
+
+		.align	5
+		.set	reorder
+ll_serial_irq:
+		li	a0,6
+		move	a1,sp
+		jal	do_IRQ
+		nop
+		j	ret_from_irq
+		nop
diff --git a/arch/mips/gt64120/ev64120/irq.c b/arch/mips/gt64120/ev64120/irq.c
new file mode 100644
index 0000000..3b18615
--- /dev/null
+++ b/arch/mips/gt64120/ev64120/irq.c
@@ -0,0 +1,145 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ * Code to handle irqs on GT64120A boards
+ *  Derived from mips/orion and Cort <cort@fsmlabs.com>
+ *
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: RidgeRun, Inc.
+ *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/gt64120.h>
+
+asmlinkage inline void pci_intA(struct pt_regs *regs)
+{
+	do_IRQ(GT_INTA, regs);
+}
+
+asmlinkage inline void pci_intD(struct pt_regs *regs)
+{
+	do_IRQ(GT_INTD, regs);
+}
+
+static void disable_ev64120_irq(unsigned int irq_nr)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	if (irq_nr >= 8) {	// All PCI interrupts are on line 5 or 2
+		clear_c0_status(9 << 10);
+	} else {
+		clear_c0_status(1 << (irq_nr + 8));
+	}
+	local_irq_restore(flags);
+}
+
+static void enable_ev64120_irq(unsigned int irq_nr)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	if (irq_nr >= 8)	// All PCI interrupts are on line 5 or 2
+		set_c0_status(9 << 10);
+	else
+		set_c0_status(1 << (irq_nr + 8));
+	local_irq_restore(flags);
+}
+
+static unsigned int startup_ev64120_irq(unsigned int irq)
+{
+	enable_ev64120_irq(irq);
+	return 0;		/* Never anything pending  */
+}
+
+#define shutdown_ev64120_irq     disable_ev64120_irq
+#define mask_and_ack_ev64120_irq disable_ev64120_irq
+
+static void end_ev64120_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_ev64120_irq(irq);
+}
+
+static struct hw_interrupt_type ev64120_irq_type = {
+	.typename	= "EV64120",
+	.startup	= startup_ev64120_irq,
+	.shutdown	= shutdown_ev64120_irq,
+	.enable		= enable_ev64120_irq,
+	.disable	= disable_ev64120_irq,
+	.ack		= mask_and_ack_ev64120_irq,
+	.end		= end_ev64120_irq,
+	.set_affinity	= NULL
+};
+
+void gt64120_irq_setup(void)
+{
+	extern asmlinkage void galileo_handle_int(void);
+
+	/*
+	 * Clear all of the interrupts while we change the able around a bit.
+	 */
+	clear_c0_status(ST0_IM);
+
+	/* Sets the exception_handler array. */
+	set_except_vector(0, galileo_handle_int);
+
+	local_irq_disable();
+
+	/*
+	 * Enable timer.  Other interrupts will be enabled as they are
+	 * registered.
+	 */
+	set_c0_status(IE_IRQ2);
+}
+
+void __init arch_init_irq(void)
+{
+	int i;
+
+	/*  Let's initialize our IRQ descriptors  */
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc[i].status = 0;
+		irq_desc[i].handler = &no_irq_type;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 0;
+		spin_lock_init(&irq_desc[i].lock);
+	}
+
+	gt64120_irq_setup();
+}
diff --git a/arch/mips/gt64120/ev64120/promcon.c b/arch/mips/gt64120/ev64120/promcon.c
new file mode 100644
index 0000000..b5937c4
--- /dev/null
+++ b/arch/mips/gt64120/ev64120/promcon.c
@@ -0,0 +1,53 @@
+/*
+ * Wrap-around code for a console using the
+ * SGI PROM io-routines.
+ *
+ * Copyright (c) 1999 Ulf Carlsson
+ *
+ * Derived from DECstation promcon.c
+ * Copyright (c) 1998 Harald Koerfgen
+ */
+#include <linux/tty.h>
+#include <linux/init.h>
+#include <linux/console.h>
+
+static void prom_console_write(struct console *co, const char *s,
+			       unsigned count)
+{
+	extern int CONSOLE_CHANNEL;	// The default serial port
+	unsigned i;
+
+	for (i = 0; i < count; i++) {
+		if (*s == 10)
+			serial_putc(CONSOLE_CHANNEL, 13);
+		serial_putc(CONSOLE_CHANNEL, *s++);
+	}
+}
+
+int prom_getchar(void)
+{
+	return 0;
+}
+
+static struct console sercons = {
+    .name	= "ttyS",
+    .write	= prom_console_write,
+    .flags	= CON_PRINTBUFFER,
+    .index	= -1,
+};
+
+/*
+ *    Register console.
+ */
+
+static int gal_serial_console_init(void)
+{
+	//  serial_init();
+	//serial_set(115200);
+
+	register_console(&sercons);
+
+	return 0;
+}
+
+console_initcall(gal_serial_console_init);
diff --git a/arch/mips/gt64120/ev64120/reset.c b/arch/mips/gt64120/ev64120/reset.c
new file mode 100644
index 0000000..7b9f5e5
--- /dev/null
+++ b/arch/mips/gt64120/ev64120/reset.c
@@ -0,0 +1,45 @@
+/*
+ * 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) 1997 Ralf Baechle
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+
+void galileo_machine_restart(char *command)
+{
+	*(volatile char *) 0xbc000000 = 0x0f;
+	/*
+	 * Ouch, we're still alive ... This time we take the silver bullet ...
+	 * ... and find that we leave the hardware in a state in which the
+	 * kernel in the flush locks up somewhen during of after the PCI
+	 * detection stuff.
+	 */
+	set_c0_status(ST0_BEV | ST0_ERL);
+	change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+	flush_cache_all();
+	write_c0_wired(0);
+	__asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
+}
+
+void galileo_machine_halt(void)
+{
+	printk(KERN_NOTICE "You can safely turn off the power\n");
+	while (1)
+		__asm__(".set\tmips3\n\t"
+	                "wait\n\t"
+			".set\tmips0");
+
+}
+
+void galileo_machine_power_off(void)
+{
+	galileo_machine_halt();
+}
diff --git a/arch/mips/gt64120/ev64120/serialGT.c b/arch/mips/gt64120/ev64120/serialGT.c
new file mode 100644
index 0000000..16e34a5
--- /dev/null
+++ b/arch/mips/gt64120/ev64120/serialGT.c
@@ -0,0 +1,212 @@
+/*
+ * serialGT.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *  Low Level Serial Port control for use
+ *  with the Galileo EVB64120A MIPS eval board and
+ *  its on board two channel 16552 Uart.
+ *
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: RidgeRun, Inc.
+ *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+// Note:
+//   Serial CHANNELS - 0 is the bottom connector of evb64120A.
+//                       (The one that maps to the "B" channel of the
+//                       board's uart)
+//                     1 is the top connector of evb64120A.
+//                       (The one that maps to the "A" channel of the
+//                       board's uart)
+int DEBUG_CHANNEL = 0;		// See Note Above
+int CONSOLE_CHANNEL = 1;	// See Note Above
+
+#define DUART 0xBD000000	/* Base address of Uart. */
+#define CHANNELOFFSET 0x20	/* DUART+CHANNELOFFSET gets you to the ChanA
+				   register set of the 16552 Uart device.
+				   DUART+0 gets you to the ChanB register set.
+				 */
+#define DUART_DELTA 0x4
+#define FIFO_ENABLE 0x07
+#define INT_ENABLE  0x04	/* default interrupt mask */
+
+#define RBR 0x00
+#define THR 0x00
+#define DLL 0x00
+#define IER 0x01
+#define DLM 0x01
+#define IIR 0x02
+#define FCR 0x02
+#define LCR 0x03
+#define MCR 0x04
+#define LSR 0x05
+#define MSR 0x06
+#define SCR 0x07
+
+#define LCR_DLAB 0x80
+#define XTAL 1843200
+#define LSR_THRE 0x20
+#define LSR_BI   0x10
+#define LSR_DR   0x01
+#define MCR_LOOP 0x10
+#define ACCESS_DELAY 0x10000
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+int inreg(int channel, int reg)
+{
+	int val;
+	val =
+	    *((volatile unsigned char *) DUART +
+	      (channel * CHANNELOFFSET) + (reg * DUART_DELTA));
+	return val;
+}
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+void outreg(int channel, int reg, unsigned char val)
+{
+	*((volatile unsigned char *) DUART + (channel * CHANNELOFFSET)
+	  + (reg * DUART_DELTA)) = val;
+}
+
+/******************************
+ Routine:
+ Description:
+   Initialize the device driver.
+ ******************************/
+void serial_init(int channel)
+{
+	/*
+	 * Configure active port, (CHANNELOFFSET already set.)
+	 *
+	 * Set 8 bits, 1 stop bit, no parity.
+	 *
+	 * LCR<7>       0       divisor latch access bit
+	 * LCR<6>       0       break control (1=send break)
+	 * LCR<5>       0       stick parity (0=space, 1=mark)
+	 * LCR<4>       0       parity even (0=odd, 1=even)
+	 * LCR<3>       0       parity enable (1=enabled)
+	 * LCR<2>       0       # stop bits (0=1, 1=1.5)
+	 * LCR<1:0>     11      bits per character(00=5, 01=6, 10=7, 11=8)
+	 */
+	outreg(channel, LCR, 0x3);
+
+	outreg(channel, FCR, FIFO_ENABLE);	/* Enable the FIFO */
+
+	outreg(channel, IER, INT_ENABLE);	/* Enable appropriate interrupts */
+}
+
+/******************************
+ Routine:
+ Description:
+   Set the baud rate.
+ ******************************/
+void serial_set(int channel, unsigned long baud)
+{
+	unsigned char sav_lcr;
+
+	/*
+	 * Enable access to the divisor latches by setting DLAB in LCR.
+	 *
+	 */
+	sav_lcr = inreg(channel, LCR);
+
+#if 0
+	/*
+	 * Set baud rate
+	 */
+	outreg(channel, LCR, LCR_DLAB | sav_lcr);
+	//  outreg(DLL,(XTAL/(16*2*(baud))-2));
+	outreg(channel, DLL, XTAL / (16 * baud));
+	//  outreg(DLM,(XTAL/(16*2*(baud))-2)>>8);
+	outreg(channel, DLM, (XTAL / (16 * baud)) >> 8);
+#else
+	/*
+	 * Note: Set baud rate, hardcoded here for rate of 115200
+	 * since became unsure of above "buad rate" algorithm (??).
+	 */
+	outreg(channel, LCR, 0x83);
+	outreg(channel, DLM, 0x00);	// See note above
+	outreg(channel, DLL, 0x02);	// See note above.
+	outreg(channel, LCR, 0x03);
+#endif
+
+	/*
+	 * Restore line control register
+	 */
+	outreg(channel, LCR, sav_lcr);
+}
+
+
+/******************************
+ Routine:
+ Description:
+   Transmit a character.
+ ******************************/
+void serial_putc(int channel, int c)
+{
+	while ((inreg(channel, LSR) & LSR_THRE) == 0);
+	outreg(channel, THR, c);
+}
+
+/******************************
+ Routine:
+ Description:
+    Read a received character if one is
+    available.  Return -1 otherwise.
+ ******************************/
+int serial_getc(int channel)
+{
+	if (inreg(channel, LSR) & LSR_DR) {
+		return inreg(channel, RBR);
+	}
+	return -1;
+}
+
+/******************************
+ Routine:
+ Description:
+   Used by embedded gdb client. (example; gdb-stub.c)
+ ******************************/
+char getDebugChar()
+{
+	int val;
+	while ((val = serial_getc(DEBUG_CHANNEL)) == -1);	// loop until we get a character in.
+	return (char) val;
+}
+
+/******************************
+ Routine:
+ Description:
+   Used by embedded gdb target. (example; gdb-stub.c)
+ ******************************/
+void putDebugChar(char c)
+{
+	serial_putc(DEBUG_CHANNEL, (int) c);
+}
diff --git a/arch/mips/gt64120/ev64120/setup.c b/arch/mips/gt64120/ev64120/setup.c
new file mode 100644
index 0000000..dba0961
--- /dev/null
+++ b/arch/mips/gt64120/ev64120/setup.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: RidgeRun, Inc.
+ *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/timex.h>
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pci.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/time.h>
+#include <asm/reboot.h>
+#include <asm/traps.h>
+#include <linux/bootmem.h>
+
+unsigned long gt64120_base = KSEG1ADDR(0x14000000);
+
+/* These functions are used for rebooting or halting the machine*/
+extern void galileo_machine_restart(char *command);
+extern void galileo_machine_halt(void);
+extern void galileo_machine_power_off(void);
+/*
+ *This structure holds pointers to the pci configuration space accesses
+ *and interrupts allocating routine for device over the PCI
+ */
+extern struct pci_ops galileo_pci_ops;
+
+unsigned long __init prom_free_prom_memory(void)
+{
+	return 0;
+}
+
+/*
+ * Initializes basic routines and structures pointers, memory size (as
+ * given by the bios and saves the command line.
+ */
+extern void gt64120_time_init(void);
+
+static void __init ev64120_setup(void)
+{
+	_machine_restart = galileo_machine_restart;
+	_machine_halt = galileo_machine_halt;
+	_machine_power_off = galileo_machine_power_off;
+
+	board_time_init = gt64120_time_init;
+	set_io_port_base(KSEG1);
+}
+
+early_initcall(ev64120_setup);
+
+const char *get_system_type(void)
+{
+	return "Galileo EV64120A";
+}
+
+/*
+ * Kernel arguments passed by the firmware
+ *
+ * $a0 - nothing
+ * $a1 - holds a pointer to the eprom parameters
+ * $a2 - nothing
+ */
+
+void __init prom_init(void)
+{
+	mips_machgroup = MACH_GROUP_GALILEO;
+	mips_machtype = MACH_EV64120A;
+
+	add_memory_region(0, 32 << 20, BOOT_MEM_RAM);
+}
diff --git a/arch/mips/gt64120/momenco_ocelot/Makefile b/arch/mips/gt64120/momenco_ocelot/Makefile
new file mode 100644
index 0000000..7b59c65
--- /dev/null
+++ b/arch/mips/gt64120/momenco_ocelot/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for Momentum's Ocelot board.
+#
+
+obj-y	 		+= int-handler.o irq.o prom.o reset.o setup.o
+
+obj-$(CONFIG_KGDB)	+= dbg_io.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/gt64120/momenco_ocelot/dbg_io.c b/arch/mips/gt64120/momenco_ocelot/dbg_io.c
new file mode 100644
index 0000000..8720bcc
--- /dev/null
+++ b/arch/mips/gt64120/momenco_ocelot/dbg_io.c
@@ -0,0 +1,126 @@
+#include <linux/config.h>
+
+#ifdef CONFIG_KGDB
+
+#include <asm/serial.h> /* For the serial port location and base baud */
+
+/* --- CONFIG --- */
+
+typedef unsigned char uint8;
+typedef unsigned int uint32;
+
+/* --- END OF CONFIG --- */
+
+#define         UART16550_BAUD_2400             2400
+#define         UART16550_BAUD_4800             4800
+#define         UART16550_BAUD_9600             9600
+#define         UART16550_BAUD_19200            19200
+#define         UART16550_BAUD_38400            38400
+#define         UART16550_BAUD_57600            57600
+#define         UART16550_BAUD_115200           115200
+
+#define         UART16550_PARITY_NONE           0
+#define         UART16550_PARITY_ODD            0x08
+#define         UART16550_PARITY_EVEN           0x18
+#define         UART16550_PARITY_MARK           0x28
+#define         UART16550_PARITY_SPACE          0x38
+
+#define         UART16550_DATA_5BIT             0x0
+#define         UART16550_DATA_6BIT             0x1
+#define         UART16550_DATA_7BIT             0x2
+#define         UART16550_DATA_8BIT             0x3
+
+#define         UART16550_STOP_1BIT             0x0
+#define         UART16550_STOP_2BIT             0x4
+
+/* ----------------------------------------------------- */
+
+/* === CONFIG === */
+
+/* [jsun] we use the second serial port for kdb */
+#define         BASE                    OCELOT_SERIAL1_BASE
+#define         MAX_BAUD                OCELOT_BASE_BAUD
+
+/* === END OF CONFIG === */
+
+#define         REG_OFFSET              4
+
+/* register offset */
+#define         OFS_RCV_BUFFER          0
+#define         OFS_TRANS_HOLD          0
+#define         OFS_SEND_BUFFER         0
+#define         OFS_INTR_ENABLE         (1*REG_OFFSET)
+#define         OFS_INTR_ID             (2*REG_OFFSET)
+#define         OFS_DATA_FORMAT         (3*REG_OFFSET)
+#define         OFS_LINE_CONTROL        (3*REG_OFFSET)
+#define         OFS_MODEM_CONTROL       (4*REG_OFFSET)
+#define         OFS_RS232_OUTPUT        (4*REG_OFFSET)
+#define         OFS_LINE_STATUS         (5*REG_OFFSET)
+#define         OFS_MODEM_STATUS        (6*REG_OFFSET)
+#define         OFS_RS232_INPUT         (6*REG_OFFSET)
+#define         OFS_SCRATCH_PAD         (7*REG_OFFSET)
+
+#define         OFS_DIVISOR_LSB         (0*REG_OFFSET)
+#define         OFS_DIVISOR_MSB         (1*REG_OFFSET)
+
+
+/* memory-mapped read/write of the port */
+#define         UART16550_READ(y)    (*((volatile uint8*)(BASE + y)))
+#define         UART16550_WRITE(y, z)  ((*((volatile uint8*)(BASE + y))) = z)
+
+void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
+{
+	/* disable interrupts */
+	UART16550_WRITE(OFS_INTR_ENABLE, 0);
+
+	/* set up buad rate */
+	{
+		uint32 divisor;
+
+		/* set DIAB bit */
+		UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
+
+		/* set divisor */
+		divisor = MAX_BAUD / baud;
+		UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
+		UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
+
+		/* clear DIAB bit */
+		UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
+	}
+
+	/* set data format */
+	UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
+}
+
+static int remoteDebugInitialized = 0;
+
+uint8 getDebugChar(void)
+{
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(UART16550_BAUD_38400,
+			  UART16550_DATA_8BIT,
+			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+	}
+
+	while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
+	return UART16550_READ(OFS_RCV_BUFFER);
+}
+
+
+int putDebugChar(uint8 byte)
+{
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(UART16550_BAUD_38400,
+			  UART16550_DATA_8BIT,
+			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+	}
+
+	while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
+	UART16550_WRITE(OFS_SEND_BUFFER, byte);
+	return 1;
+}
+
+#endif
diff --git a/arch/mips/gt64120/momenco_ocelot/int-handler.S b/arch/mips/gt64120/momenco_ocelot/int-handler.S
new file mode 100644
index 0000000..808acef
--- /dev/null
+++ b/arch/mips/gt64120/momenco_ocelot/int-handler.S
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * First-level interrupt dispatcher for ocelot board.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/*
+ * first level interrupt dispatcher for ocelot board -
+ * We check for the timer first, then check PCI ints A and D.
+ * Then check for serial IRQ and fall through.
+ */
+		.align	5
+		NESTED(ocelot_handle_int, PT_SIZE, sp)
+		SAVE_ALL
+		CLI
+		.set	at
+		mfc0	t0, CP0_CAUSE
+		mfc0	t2, CP0_STATUS
+
+		and	t0, t2
+
+		 andi	t1, t0, STATUSF_IP2	/* int0 hardware line */
+		bnez	t1, ll_pri_enet_irq
+		 andi	t1, t0, STATUSF_IP3	/* int1 hardware line */
+		bnez	t1, ll_sec_enet_irq
+		 andi	t1, t0, STATUSF_IP4	/* int2 hardware line */
+		bnez	t1, ll_uart1_irq
+		 andi	t1, t0, STATUSF_IP5	/* int3 hardware line */
+		bnez	t1, ll_cpci_irq
+		 andi	t1, t0, STATUSF_IP6	/* int4 hardware line */
+		bnez	t1, ll_galileo_irq
+		 andi	t1, t0, STATUSF_IP7	/* cpu timer */
+		bnez	t1, ll_cputimer_irq
+
+                /* now look at the extended interrupts */
+		mfc0	t0, CP0_CAUSE
+		cfc0	t1, CP0_S1_INTCONTROL
+
+		/* shift the mask 8 bits left to line up the bits */
+		 sll	t2, t1, 8
+
+		 and	t0, t2
+		 srl	t0, t0, 16
+
+		 andi	t1, t0, STATUSF_IP8	/* int6 hardware line */
+		bnez	t1, ll_pmc1_irq
+		 andi	t1, t0, STATUSF_IP9	/* int7 hardware line */
+		bnez	t1, ll_pmc2_irq
+		 andi	t1, t0, STATUSF_IP10	/* int8 hardware line */
+		bnez	t1, ll_cpci_abcd_irq
+		 andi	t1, t0, STATUSF_IP11	/* int9 hardware line */
+		bnez	t1, ll_uart2_irq
+
+		.set	reorder
+
+		/* wrong alarm or masked ... */
+		j	spurious_interrupt
+		nop
+		END(ocelot_handle_int)
+
+		.align	5
+ll_pri_enet_irq:
+		li	a0, 2
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_sec_enet_irq:
+		li	a0, 3
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_uart1_irq:
+		li	a0, 4
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_cpci_irq:
+		li	a0, 5
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_galileo_irq:
+		li	a0, 6
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_cputimer_irq:
+		li	a0, 7
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_pmc1_irq:
+		li	a0, 8
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_pmc2_irq:
+		li	a0, 9
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_cpci_abcd_irq:
+		li	a0, 10
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_uart2_irq:
+		li	a0, 11
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
diff --git a/arch/mips/gt64120/momenco_ocelot/irq.c b/arch/mips/gt64120/momenco_ocelot/irq.c
new file mode 100644
index 0000000..4f108da
--- /dev/null
+++ b/arch/mips/gt64120/momenco_ocelot/irq.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: RidgeRun, Inc.
+ *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ * Copyright (C) 2000, 2001, 2003 Ralf Baechle (ralf@gnu.org)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+extern asmlinkage void ocelot_handle_int(void);
+
+void __init arch_init_irq(void)
+{
+	/*
+	 * Clear all of the interrupts while we change the able around a bit.
+	 * int-handler is not on bootstrap
+	 */
+	clear_c0_status(ST0_IM);
+	local_irq_disable();
+
+	/* Sets the first-level interrupt dispatcher. */
+	set_except_vector(0, ocelot_handle_int);
+
+	mips_cpu_irq_init(0);
+	rm7k_cpu_irq_init(8);
+}
diff --git a/arch/mips/gt64120/momenco_ocelot/ocelot_pld.h b/arch/mips/gt64120/momenco_ocelot/ocelot_pld.h
new file mode 100644
index 0000000..11f02c4
--- /dev/null
+++ b/arch/mips/gt64120/momenco_ocelot/ocelot_pld.h
@@ -0,0 +1,30 @@
+/*
+ * Ocelot Board Register Definitions
+ *
+ * (C) 2001 Red Hat, Inc.
+ *
+ * GPL'd
+ */
+#ifndef __MOMENCO_OCELOT_PLD_H__
+#define __MOMENCO_OCELOT_PLD_H__
+
+#define OCELOT_CS0_ADDR (0xe0020000)
+
+#define OCELOT_REG_BOARDREV (0)
+#define OCELOT_REG_PLD1_ID (1)
+#define OCELOT_REG_PLD2_ID (2)
+#define OCELOT_REG_RESET_STATUS (3)
+#define OCELOT_REG_BOARD_STATUS (4)
+#define OCELOT_REG_CPCI_ID (5)
+#define OCELOT_REG_I2C_CTRL (8)
+#define OCELOT_REG_EEPROM_MODE (9)
+#define OCELOT_REG_INTMASK (10)
+#define OCELOT_REG_INTSTATUS (11)
+#define OCELOT_REG_INTSET (12)
+#define OCELOT_REG_INTCLR (13)
+
+#define OCELOT_PLD_WRITE(x, y) writeb(x, OCELOT_CS0_ADDR + OCELOT_REG_##y)
+#define OCELOT_PLD_READ(x) readb(OCELOT_CS0_ADDR + OCELOT_REG_##x)
+
+
+#endif /* __MOMENCO_OCELOT_PLD_H__ */
diff --git a/arch/mips/gt64120/momenco_ocelot/prom.c b/arch/mips/gt64120/momenco_ocelot/prom.c
new file mode 100644
index 0000000..8677b6d
--- /dev/null
+++ b/arch/mips/gt64120/momenco_ocelot/prom.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/pmon.h>
+
+struct callvectors* debug_vectors;
+
+extern unsigned long gt64120_base;
+
+const char *get_system_type(void)
+{
+	return "Momentum Ocelot";
+}
+
+/* [jsun@junsun.net] PMON passes arguments in C main() style */
+void __init prom_init(void)
+{
+	int argc = fw_arg0;
+	char **arg = (char **) fw_arg1;
+	char **env = (char **) fw_arg2;
+	struct callvectors *cv = (struct callvectors *) fw_arg3;
+	uint32_t tmp;
+	int i;
+
+	/* save the PROM vectors for debugging use */
+	debug_vectors = cv;
+
+	/* arg[0] is "g", the rest is boot parameters */
+	arcs_cmdline[0] = '\0';
+	for (i = 1; i < argc; i++) {
+		if (strlen(arcs_cmdline) + strlen(arg[i] + 1)
+		    >= sizeof(arcs_cmdline))
+			break;
+		strcat(arcs_cmdline, arg[i]);
+		strcat(arcs_cmdline, " ");
+	}
+
+	mips_machgroup = MACH_GROUP_MOMENCO;
+	mips_machtype = MACH_MOMENCO_OCELOT;
+
+	while (*env) {
+		if (strncmp("gtbase", *env, 6) == 0) {
+			gt64120_base = simple_strtol(*env + strlen("gtbase="),
+							NULL, 16);
+			break;
+		}
+		*env++;
+	}
+
+	debug_vectors->printf("Booting Linux kernel...\n");
+
+	/* All the boards have at least 64MiB. If there's more, we
+	   detect and register it later */
+	add_memory_region(0, 64 << 20, BOOT_MEM_RAM);
+}
+
+unsigned long __init prom_free_prom_memory(void)
+{
+	return 0;
+}
diff --git a/arch/mips/gt64120/momenco_ocelot/reset.c b/arch/mips/gt64120/momenco_ocelot/reset.c
new file mode 100644
index 0000000..3fd499a
--- /dev/null
+++ b/arch/mips/gt64120/momenco_ocelot/reset.c
@@ -0,0 +1,47 @@
+/*
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Copyright (C) 1997, 2001 Ralf Baechle
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <linux/delay.h>
+
+void momenco_ocelot_restart(char *command)
+{
+	void *nvram = ioremap_nocache(0x2c807000, 0x1000);
+
+	if (!nvram) {
+		printk(KERN_NOTICE "ioremap of reset register failed\n");
+		return;
+	}
+	writeb(0x84, nvram + 0xff7); /* Ask the NVRAM/RTC/watchdog chip to
+					assert reset in 1/16 second */
+	mdelay(10+(1000/16));
+	iounmap(nvram);
+	printk(KERN_NOTICE "Watchdog reset failed\n");
+}
+
+void momenco_ocelot_halt(void)
+{
+	printk(KERN_NOTICE "\n** You can safely turn off the power\n");
+	while (1)
+		__asm__(".set\tmips3\n\t"
+	                "wait\n\t"
+			".set\tmips0");
+}
+
+void momenco_ocelot_power_off(void)
+{
+	momenco_ocelot_halt();
+}
diff --git a/arch/mips/gt64120/momenco_ocelot/setup.c b/arch/mips/gt64120/momenco_ocelot/setup.c
new file mode 100644
index 0000000..d610f8c
--- /dev/null
+++ b/arch/mips/gt64120/momenco_ocelot/setup.c
@@ -0,0 +1,369 @@
+/*
+ * setup.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Momentum Computer Ocelot (CP7000) - board dependent boot routines
+ *
+ * Copyright (C) 1996, 1997, 2001  Ralf Baechle
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Copyright (C) 2001 Red Hat, Inc.
+ * Copyright (C) 2002 Momentum Computer
+ *
+ * Author: RidgeRun, Inc.
+ *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/timex.h>
+#include <linux/vmalloc.h>
+#include <asm/time.h>
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pci.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/reboot.h>
+#include <asm/traps.h>
+#include <linux/bootmem.h>
+#include <linux/initrd.h>
+#include <asm/gt64120.h>
+#include "ocelot_pld.h"
+
+unsigned long gt64120_base = KSEG1ADDR(GT_DEF_BASE);
+
+/* These functions are used for rebooting or halting the machine*/
+extern void momenco_ocelot_restart(char *command);
+extern void momenco_ocelot_halt(void);
+extern void momenco_ocelot_power_off(void);
+
+extern void gt64120_time_init(void);
+extern void momenco_ocelot_irq_setup(void);
+
+static char reset_reason;
+
+#define ENTRYLO(x) ((pte_val(pfn_pte((x) >> PAGE_SHIFT, PAGE_KERNEL_UNCACHED)) >> 6)|1)
+
+static void __init setup_l3cache(unsigned long size);
+
+/* setup code for a handoff from a version 1 PMON 2000 PROM */
+void PMON_v1_setup()
+{
+	/* A wired TLB entry for the GT64120A and the serial port. The
+	   GT64120A is going to be hit on every IRQ anyway - there's
+	   absolutely no point in letting it be a random TLB entry, as
+	   it'll just cause needless churning of the TLB. And we use
+	   the other half for the serial port, which is just a PITA
+	   otherwise :)
+
+		Device			Physical	Virtual
+		GT64120 Internal Regs	0x24000000	0xe0000000
+		UARTs (CS2)		0x2d000000	0xe0001000
+	*/
+	add_wired_entry(ENTRYLO(0x24000000), ENTRYLO(0x2D000000), 0xe0000000, PM_4K);
+
+	/* Also a temporary entry to let us talk to the Ocelot PLD and NVRAM
+	   in the CS[012] region. We can't use ioremap() yet. The NVRAM
+	   is a ST M48T37Y, which includes NVRAM, RTC, and Watchdog functions.
+
+		Ocelot PLD (CS0)	0x2c000000	0xe0020000
+		NVRAM			0x2c800000	0xe0030000
+	*/
+
+	add_temporary_entry(ENTRYLO(0x2C000000), ENTRYLO(0x2d000000), 0xe0020000, PM_64K);
+
+	/* Relocate the CS3/BootCS region */
+  	GT_WRITE(GT_CS3BOOTLD_OFS, 0x2f000000 >> 21);
+
+	/* Relocate CS[012] */
+ 	GT_WRITE(GT_CS20LD_OFS, 0x2c000000 >> 21);
+
+	/* Relocate the GT64120A itself... */
+	GT_WRITE(GT_ISD_OFS, 0x24000000 >> 21);
+	mb();
+	gt64120_base = 0xe0000000;
+
+	/* ...and the PCI0 view of it. */
+	GT_WRITE(GT_PCI0_CFGADDR_OFS, 0x80000020);
+	GT_WRITE(GT_PCI0_CFGDATA_OFS, 0x24000000);
+	GT_WRITE(GT_PCI0_CFGADDR_OFS, 0x80000024);
+	GT_WRITE(GT_PCI0_CFGDATA_OFS, 0x24000001);
+}
+
+/* setup code for a handoff from a version 2 PMON 2000 PROM */
+void PMON_v2_setup()
+{
+	/* A wired TLB entry for the GT64120A and the serial port. The
+	   GT64120A is going to be hit on every IRQ anyway - there's
+	   absolutely no point in letting it be a random TLB entry, as
+	   it'll just cause needless churning of the TLB. And we use
+	   the other half for the serial port, which is just a PITA
+	   otherwise :)
+
+		Device			Physical	Virtual
+		GT64120 Internal Regs	0xf4000000	0xe0000000
+		UARTs (CS2)		0xfd000000	0xe0001000
+	*/
+	add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xfD000000), 0xe0000000, PM_4K);
+
+	/* Also a temporary entry to let us talk to the Ocelot PLD and NVRAM
+	   in the CS[012] region. We can't use ioremap() yet. The NVRAM
+	   is a ST M48T37Y, which includes NVRAM, RTC, and Watchdog functions.
+
+		Ocelot PLD (CS0)	0xfc000000	0xe0020000
+		NVRAM			0xfc800000	0xe0030000
+	*/
+	add_temporary_entry(ENTRYLO(0xfC000000), ENTRYLO(0xfd000000), 0xe0020000, PM_64K);
+
+	gt64120_base = 0xe0000000;
+}
+
+static void __init momenco_ocelot_setup(void)
+{
+	void (*l3func)(unsigned long)=KSEG1ADDR(&setup_l3cache);
+	unsigned int tmpword;
+
+	board_time_init = gt64120_time_init;
+
+	_machine_restart = momenco_ocelot_restart;
+	_machine_halt = momenco_ocelot_halt;
+	_machine_power_off = momenco_ocelot_power_off;
+
+	/*
+	 * initrd_start = (ulong)ocelot_initrd_start;
+	 * initrd_end = (ulong)ocelot_initrd_start + (ulong)ocelot_initrd_size;
+	 * initrd_below_start_ok = 1;
+	 */
+
+	/* do handoff reconfiguration */
+	if (gt64120_base == KSEG1ADDR(GT_DEF_BASE))
+		PMON_v1_setup();
+	else
+		PMON_v2_setup();
+
+	/* Turn off the Bit-Error LED */
+	OCELOT_PLD_WRITE(0x80, INTCLR);
+
+	/* Relocate all the PCI1 stuff, not that we use it */
+	GT_WRITE(GT_PCI1IOLD_OFS, 0x30000000 >> 21);
+	GT_WRITE(GT_PCI1M0LD_OFS, 0x32000000 >> 21);
+	GT_WRITE(GT_PCI1M1LD_OFS, 0x34000000 >> 21);
+
+	/* Relocate PCI0 I/O and Mem0 */
+	GT_WRITE(GT_PCI0IOLD_OFS, 0x20000000 >> 21);
+	GT_WRITE(GT_PCI0M0LD_OFS, 0x22000000 >> 21);
+
+	/* Relocate PCI0 Mem1 */
+	GT_WRITE(GT_PCI0M1LD_OFS, 0x36000000 >> 21);
+
+	/* For the initial programming, we assume 512MB configuration */
+	/* Relocate the CPU's view of the RAM... */
+	GT_WRITE(GT_SCS10LD_OFS, 0);
+	GT_WRITE(GT_SCS10HD_OFS, 0x0fe00000 >> 21);
+	GT_WRITE(GT_SCS32LD_OFS, 0x10000000 >> 21);
+	GT_WRITE(GT_SCS32HD_OFS, 0x0fe00000 >> 21);
+
+	GT_WRITE(GT_SCS1LD_OFS, 0xff);
+	GT_WRITE(GT_SCS1HD_OFS, 0x00);
+	GT_WRITE(GT_SCS0LD_OFS, 0);
+	GT_WRITE(GT_SCS0HD_OFS, 0xff);
+	GT_WRITE(GT_SCS3LD_OFS, 0xff);
+	GT_WRITE(GT_SCS3HD_OFS, 0x00);
+	GT_WRITE(GT_SCS2LD_OFS, 0);
+	GT_WRITE(GT_SCS2HD_OFS, 0xff);
+
+	/* ...and the PCI0 view of it. */
+	GT_WRITE(GT_PCI0_CFGADDR_OFS, 0x80000010);
+	GT_WRITE(GT_PCI0_CFGDATA_OFS, 0x00000000);
+	GT_WRITE(GT_PCI0_CFGADDR_OFS, 0x80000014);
+	GT_WRITE(GT_PCI0_CFGDATA_OFS, 0x10000000);
+	GT_WRITE(GT_PCI0_BS_SCS10_OFS, 0x0ffff000);
+	GT_WRITE(GT_PCI0_BS_SCS32_OFS, 0x0ffff000);
+
+	tmpword = OCELOT_PLD_READ(BOARDREV);
+	if (tmpword < 26)
+		printk("Momenco Ocelot: Board Assembly Rev. %c\n", 'A'+tmpword);
+	else
+		printk("Momenco Ocelot: Board Assembly Revision #0x%x\n", tmpword);
+
+	tmpword = OCELOT_PLD_READ(PLD1_ID);
+	printk("PLD 1 ID: %d.%d\n", tmpword>>4, tmpword&15);
+	tmpword = OCELOT_PLD_READ(PLD2_ID);
+	printk("PLD 2 ID: %d.%d\n", tmpword>>4, tmpword&15);
+	tmpword = OCELOT_PLD_READ(RESET_STATUS);
+	printk("Reset reason: 0x%x\n", tmpword);
+	reset_reason = tmpword;
+	OCELOT_PLD_WRITE(0xff, RESET_STATUS);
+
+	tmpword = OCELOT_PLD_READ(BOARD_STATUS);
+	printk("Board Status register: 0x%02x\n", tmpword);
+	printk("  - User jumper: %s\n", (tmpword & 0x80)?"installed":"absent");
+	printk("  - Boot flash write jumper: %s\n", (tmpword&0x40)?"installed":"absent");
+	printk("  - Tulip PHY %s connected\n", (tmpword&0x10)?"is":"not");
+	printk("  - L3 Cache size: %d MiB\n", (1<<((tmpword&12) >> 2))&~1);
+	printk("  - SDRAM size: %d MiB\n", 1<<(6+(tmpword&3)));
+
+	if (tmpword&12)
+		l3func((1<<(((tmpword&12) >> 2)+20)));
+
+	switch(tmpword &3) {
+	case 3:
+		/* 512MiB */
+		/* Decoders are allready set -- just add the
+		 * appropriate region */
+		add_memory_region( 0x40<<20,  0xC0<<20, BOOT_MEM_RAM);
+		add_memory_region(0x100<<20, 0x100<<20, BOOT_MEM_RAM);
+		break;
+	case 2:
+		/* 256MiB -- two banks of 128MiB */
+		GT_WRITE(GT_SCS10HD_OFS, 0x07e00000 >> 21);
+		GT_WRITE(GT_SCS32LD_OFS, 0x08000000 >> 21);
+		GT_WRITE(GT_SCS32HD_OFS, 0x0fe00000 >> 21);
+
+		GT_WRITE(GT_SCS0HD_OFS, 0x7f);
+		GT_WRITE(GT_SCS2LD_OFS, 0x80);
+		GT_WRITE(GT_SCS2HD_OFS, 0xff);
+
+		/* reconfigure the PCI0 interface view of memory */
+		GT_WRITE(GT_PCI0_CFGADDR_OFS, 0x80000014);
+		GT_WRITE(GT_PCI0_CFGDATA_OFS, 0x08000000);
+		GT_WRITE(GT_PCI0_BS_SCS10_OFS, 0x0ffff000);
+		GT_WRITE(GT_PCI0_BS_SCS32_OFS, 0x0ffff000);
+
+		add_memory_region(0x40<<20, 0x40<<20, BOOT_MEM_RAM);
+		add_memory_region(0x80<<20, 0x80<<20, BOOT_MEM_RAM);
+		break;
+	case 1:
+		/* 128MiB -- 64MiB per bank */
+		GT_WRITE(GT_SCS10HD_OFS, 0x03e00000 >> 21);
+		GT_WRITE(GT_SCS32LD_OFS, 0x04000000 >> 21);
+		GT_WRITE(GT_SCS32HD_OFS, 0x07e00000 >> 21);
+
+		GT_WRITE(GT_SCS0HD_OFS, 0x3f);
+		GT_WRITE(GT_SCS2LD_OFS, 0x40);
+		GT_WRITE(GT_SCS2HD_OFS, 0x7f);
+
+		/* reconfigure the PCI0 interface view of memory */
+		GT_WRITE(GT_PCI0_CFGADDR_OFS, 0x80000014);
+		GT_WRITE(GT_PCI0_CFGDATA_OFS, 0x04000000);
+		GT_WRITE(GT_PCI0_BS_SCS10_OFS, 0x03fff000);
+		GT_WRITE(GT_PCI0_BS_SCS32_OFS, 0x03fff000);
+
+		/* add the appropriate region */
+		add_memory_region(0x40<<20, 0x40<<20, BOOT_MEM_RAM);
+		break;
+	case 0:
+		/* 64MiB */
+		GT_WRITE(GT_SCS10HD_OFS, 0x01e00000 >> 21);
+		GT_WRITE(GT_SCS32LD_OFS, 0x02000000 >> 21);
+		GT_WRITE(GT_SCS32HD_OFS, 0x03e00000 >> 21);
+
+		GT_WRITE(GT_SCS0HD_OFS, 0x1f);
+		GT_WRITE(GT_SCS2LD_OFS, 0x20);
+		GT_WRITE(GT_SCS2HD_OFS, 0x3f);
+
+		/* reconfigure the PCI0 interface view of memory */
+		GT_WRITE(GT_PCI0_CFGADDR_OFS, 0x80000014);
+		GT_WRITE(GT_PCI0_CFGDATA_OFS, 0x04000000);
+		GT_WRITE(GT_PCI0_BS_SCS10_OFS, 0x01fff000);
+		GT_WRITE(GT_PCI0_BS_SCS32_OFS, 0x01fff000);
+
+		break;
+	}
+
+	/* Fix up the DiskOnChip mapping */
+	GT_WRITE(GT_DEV_B3_OFS, 0xfef73);
+}
+
+early_initcall(momenco_ocelot_setup);
+
+extern int rm7k_tcache_enabled;
+/*
+ * This runs in KSEG1. See the verbiage in rm7k.c::probe_scache()
+ */
+#define Page_Invalidate_T 0x16
+static void __init setup_l3cache(unsigned long size)
+{
+	int register i;
+	unsigned long tmp;
+
+	printk("Enabling L3 cache...");
+
+	/* Enable the L3 cache in the GT64120A's CPU Configuration register */
+	tmp = GT_READ(GT_CPU_OFS);
+	GT_WRITE(GT_CPU_OFS, tmp | (1<<14));
+
+	/* Enable the L3 cache in the CPU */
+	set_c0_config(1<<12 /* CONF_TE */);
+
+	/* Clear the cache */
+	write_c0_taglo(0);
+	write_c0_taghi(0);
+
+	for (i=0; i < size; i+= 4096) {
+		__asm__ __volatile__ (
+			".set noreorder\n\t"
+			".set mips3\n\t"
+			"cache %1, (%0)\n\t"
+			".set mips0\n\t"
+			".set reorder"
+			:
+			: "r" (KSEG0ADDR(i)),
+			  "i" (Page_Invalidate_T));
+	}
+
+	/* Let the RM7000 MM code know that the tertiary cache is enabled */
+	rm7k_tcache_enabled = 1;
+
+	printk("Done\n");
+}
+
+
+/* This needs to be one of the first initcalls, because no I/O port access
+   can work before this */
+
+static int io_base_ioremap(void)
+{
+	void *io_remap_range = ioremap(GT_PCI_IO_BASE, GT_PCI_IO_SIZE);
+
+	if (!io_remap_range) {
+		panic("Could not ioremap I/O port range");
+	}
+	set_io_port_base(io_remap_range - GT_PCI_IO_BASE);
+
+	return 0;
+}
+
+module_init(io_base_ioremap);
diff --git a/arch/mips/ite-boards/generic/Makefile b/arch/mips/ite-boards/generic/Makefile
new file mode 100644
index 0000000..0e7853f
--- /dev/null
+++ b/arch/mips/ite-boards/generic/Makefile
@@ -0,0 +1,15 @@
+#
+#  Copyright 2000 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc.
+#     	ppopov@mvista.com or source@mvista.com
+#
+# Makefile for the ITE 8172 (qed-4n-s01b) board, generic files.
+#
+
+obj-y			+= it8172_setup.o irq.o int-handler.o pmon_prom.o \
+			   time.o lpc.o puts.o reset.o
+
+obj-$(CONFIG_IT8172_CIR)+= it8172_cir.o
+obj-$(CONFIG_KGDB)	+= dbg_io.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/ite-boards/generic/dbg_io.c b/arch/mips/ite-boards/generic/dbg_io.c
new file mode 100644
index 0000000..c4f8530
--- /dev/null
+++ b/arch/mips/ite-boards/generic/dbg_io.c
@@ -0,0 +1,125 @@
+
+#include <linux/config.h>
+
+#ifdef CONFIG_KGDB
+
+/* --- CONFIG --- */
+
+/* we need uint32 uint8 */
+/* #include "types.h" */
+typedef unsigned char uint8;
+typedef unsigned int uint32;
+
+/* --- END OF CONFIG --- */
+
+#define         UART16550_BAUD_2400             2400
+#define         UART16550_BAUD_4800             4800
+#define         UART16550_BAUD_9600             9600
+#define         UART16550_BAUD_19200            19200
+#define         UART16550_BAUD_38400            38400
+#define         UART16550_BAUD_57600            57600
+#define         UART16550_BAUD_115200           115200
+
+#define         UART16550_PARITY_NONE           0
+#define         UART16550_PARITY_ODD            0x08
+#define         UART16550_PARITY_EVEN           0x18
+#define         UART16550_PARITY_MARK           0x28
+#define         UART16550_PARITY_SPACE          0x38
+
+#define         UART16550_DATA_5BIT             0x0
+#define         UART16550_DATA_6BIT             0x1
+#define         UART16550_DATA_7BIT             0x2
+#define         UART16550_DATA_8BIT             0x3
+
+#define         UART16550_STOP_1BIT             0x0
+#define         UART16550_STOP_2BIT             0x4
+
+/* ----------------------------------------------------- */
+
+/* === CONFIG === */
+
+/* [stevel] we use the IT8712 serial port for kgdb */
+#define	DEBUG_BASE  0xB40003F8	/* 8712 serial port 1 base address */
+#define MAX_BAUD    115200
+
+/* === END OF CONFIG === */
+
+/* register offset */
+#define         OFS_RCV_BUFFER          0
+#define         OFS_TRANS_HOLD          0
+#define         OFS_SEND_BUFFER         0
+#define         OFS_INTR_ENABLE         1
+#define         OFS_INTR_ID             2
+#define         OFS_DATA_FORMAT         3
+#define         OFS_LINE_CONTROL        3
+#define         OFS_MODEM_CONTROL       4
+#define         OFS_RS232_OUTPUT        4
+#define         OFS_LINE_STATUS         5
+#define         OFS_MODEM_STATUS        6
+#define         OFS_RS232_INPUT         6
+#define         OFS_SCRATCH_PAD         7
+
+#define         OFS_DIVISOR_LSB         0
+#define         OFS_DIVISOR_MSB         1
+
+
+/* memory-mapped read/write of the port */
+#define UART16550_READ(y)    (*((volatile uint8*)(DEBUG_BASE + y)))
+#define UART16550_WRITE(y,z) ((*((volatile uint8*)(DEBUG_BASE + y))) = z)
+
+void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
+{
+	/* disable interrupts */
+	UART16550_WRITE(OFS_INTR_ENABLE, 0);
+
+	/* set up buad rate */
+	{
+		uint32 divisor;
+
+		/* set DIAB bit */
+		UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
+
+		/* set divisor */
+		divisor = MAX_BAUD / baud;
+		UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
+		UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
+
+		/* clear DIAB bit */
+		UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
+	}
+
+	/* set data format */
+	UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
+}
+
+static int remoteDebugInitialized = 0;
+
+uint8 getDebugChar(void)
+{
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(UART16550_BAUD_115200,
+			  UART16550_DATA_8BIT,
+			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+	}
+
+	while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
+	return UART16550_READ(OFS_RCV_BUFFER);
+}
+
+
+int putDebugChar(uint8 byte)
+{
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(UART16550_BAUD_115200,
+			  UART16550_DATA_8BIT,
+			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+	}
+
+	while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
+	UART16550_WRITE(OFS_SEND_BUFFER, byte);
+	return 1;
+}
+
+#endif
diff --git a/arch/mips/ite-boards/generic/int-handler.S b/arch/mips/ite-boards/generic/int-handler.S
new file mode 100644
index 0000000..d190d8a
--- /dev/null
+++ b/arch/mips/ite-boards/generic/int-handler.S
@@ -0,0 +1,63 @@
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+	.text
+	.set    macro
+	.set    noat
+	.align	5
+
+NESTED(it8172_IRQ, PT_SIZE, sp)
+	SAVE_ALL
+	CLI				# Important: mark KERNEL mode !
+
+        /* We're working with 'reorder' set at this point. */
+	/*
+	 * Get pending interrupts
+	 */
+
+	mfc0	t0,CP0_CAUSE		# get pending interrupts
+	mfc0	t1,CP0_STATUS		# get enabled interrupts
+	and	t0,t1			# isolate allowed ones
+
+	andi	t0,0xff00		# isolate pending bits
+        beqz    t0, 3f                  # spurious interrupt
+
+        andi    a0, t0, CAUSEF_IP7
+        beq     a0, zero, 1f
+
+        li	a0, 127			# MIPS_CPU_TIMER_IRQ = (NR_IRQS-1)
+        move    a1, sp
+        jal     ll_timer_interrupt
+	j	ret_from_irq
+        nop
+
+1:
+        andi    a0, t0, CAUSEF_IP2      # the only int we expect at this time
+        beq     a0, zero, 3f
+	move	a0,sp
+	jal	it8172_hw0_irqdispatch
+
+	mfc0	t0,CP0_STATUS		# disable interrupts
+	ori	t0,1
+	xori	t0,1
+	mtc0	t0,CP0_STATUS
+        nop
+        nop
+        nop
+
+	la      a1, ret_from_irq
+	jr	a1
+        nop
+
+3:
+	move a0, sp
+	jal	mips_spurious_interrupt
+        nop
+	la      a1, ret_from_irq
+	jr	a1
+        nop
+
+END(it8172_IRQ)
+
diff --git a/arch/mips/ite-boards/generic/irq.c b/arch/mips/ite-boards/generic/irq.c
new file mode 100644
index 0000000..cb71b90
--- /dev/null
+++ b/arch/mips/ite-boards/generic/irq.c
@@ -0,0 +1,304 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	ITE 8172G interrupt/setup routines.
+ *
+ * Copyright 2000,2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * Part of this file was derived from Carsten Langgaard's
+ * arch/mips/mips-boards/atlas/atlas_int.c.
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/serial_reg.h>
+#include <linux/bitops.h>
+
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/it8172/it8172.h>
+#include <asm/it8172/it8172_int.h>
+#include <asm/it8172/it8172_dbg.h>
+
+/* revisit */
+#define EXT_IRQ0_TO_IP 2 /* IP 2 */
+#define EXT_IRQ5_TO_IP 7 /* IP 7 */
+
+#define ALLINTS_NOTIMER (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4)
+
+void disable_it8172_irq(unsigned int irq_nr);
+void enable_it8172_irq(unsigned int irq_nr);
+
+extern void set_debug_traps(void);
+extern void mips_timer_interrupt(int irq, struct pt_regs *regs);
+extern asmlinkage void it8172_IRQ(void);
+
+struct it8172_intc_regs volatile *it8172_hw0_icregs =
+	(struct it8172_intc_regs volatile *)(KSEG1ADDR(IT8172_PCI_IO_BASE + IT_INTC_BASE));
+
+static void disable_it8172_irq(unsigned int irq_nr)
+{
+	if ( (irq_nr >= IT8172_LPC_IRQ_BASE) && (irq_nr <= IT8172_SERIRQ_15)) {
+		/* LPC interrupt */
+		it8172_hw0_icregs->lpc_mask |=
+			(1 << (irq_nr - IT8172_LPC_IRQ_BASE));
+	} else if ( (irq_nr >= IT8172_LB_IRQ_BASE) && (irq_nr <= IT8172_IOCHK_IRQ)) {
+		/* Local Bus interrupt */
+		it8172_hw0_icregs->lb_mask |=
+			(1 << (irq_nr - IT8172_LB_IRQ_BASE));
+	} else if ( (irq_nr >= IT8172_PCI_DEV_IRQ_BASE) && (irq_nr <= IT8172_DMA_IRQ)) {
+		/* PCI and other interrupts */
+		it8172_hw0_icregs->pci_mask |=
+			(1 << (irq_nr - IT8172_PCI_DEV_IRQ_BASE));
+	} else if ( (irq_nr >= IT8172_NMI_IRQ_BASE) && (irq_nr <= IT8172_POWER_NMI_IRQ)) {
+		/* NMI interrupts */
+		it8172_hw0_icregs->nmi_mask |=
+			(1 << (irq_nr - IT8172_NMI_IRQ_BASE));
+	} else {
+		panic("disable_it8172_irq: bad irq %d", irq_nr);
+	}
+}
+
+static void enable_it8172_irq(unsigned int irq_nr)
+{
+	if ( (irq_nr >= IT8172_LPC_IRQ_BASE) && (irq_nr <= IT8172_SERIRQ_15)) {
+		/* LPC interrupt */
+		it8172_hw0_icregs->lpc_mask &=
+			~(1 << (irq_nr - IT8172_LPC_IRQ_BASE));
+	}
+	else if ( (irq_nr >= IT8172_LB_IRQ_BASE) && (irq_nr <= IT8172_IOCHK_IRQ)) {
+		/* Local Bus interrupt */
+		it8172_hw0_icregs->lb_mask &=
+			~(1 << (irq_nr - IT8172_LB_IRQ_BASE));
+	}
+	else if ( (irq_nr >= IT8172_PCI_DEV_IRQ_BASE) && (irq_nr <= IT8172_DMA_IRQ)) {
+		/* PCI and other interrupts */
+		it8172_hw0_icregs->pci_mask &=
+			~(1 << (irq_nr - IT8172_PCI_DEV_IRQ_BASE));
+	}
+	else if ( (irq_nr >= IT8172_NMI_IRQ_BASE) && (irq_nr <= IT8172_POWER_NMI_IRQ)) {
+		/* NMI interrupts */
+		it8172_hw0_icregs->nmi_mask &=
+			~(1 << (irq_nr - IT8172_NMI_IRQ_BASE));
+	}
+	else {
+		panic("enable_it8172_irq: bad irq %d", irq_nr);
+	}
+}
+
+static unsigned int startup_ite_irq(unsigned int irq)
+{
+	enable_it8172_irq(irq);
+	return 0;
+}
+
+#define shutdown_ite_irq	disable_it8172_irq
+#define mask_and_ack_ite_irq    disable_it8172_irq
+
+static void end_ite_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_it8172_irq(irq);
+}
+
+static struct hw_interrupt_type it8172_irq_type = {
+	"ITE8172",
+	startup_ite_irq,
+	shutdown_ite_irq,
+	enable_it8172_irq,
+	disable_it8172_irq,
+	mask_and_ack_ite_irq,
+	end_ite_irq,
+	NULL
+};
+
+
+static void enable_none(unsigned int irq) { }
+static unsigned int startup_none(unsigned int irq) { return 0; }
+static void disable_none(unsigned int irq) { }
+static void ack_none(unsigned int irq) { }
+
+/* startup is the same as "enable", shutdown is same as "disable" */
+#define shutdown_none	disable_none
+#define end_none	enable_none
+
+static struct hw_interrupt_type cp0_irq_type = {
+	"CP0 Count",
+	startup_none,
+	shutdown_none,
+	enable_none,
+	disable_none,
+	ack_none,
+	end_none
+};
+
+void enable_cpu_timer(void)
+{
+        unsigned long flags;
+
+        local_irq_save(flags);
+	set_c0_status(0x100 << EXT_IRQ5_TO_IP);
+        local_irq_restore(flags);
+}
+
+void __init arch_init_irq(void)
+{
+	int i;
+        unsigned long flags;
+
+        memset(irq_desc, 0, sizeof(irq_desc));
+        set_except_vector(0, it8172_IRQ);
+
+	/* mask all interrupts */
+	it8172_hw0_icregs->lb_mask  = 0xffff;
+	it8172_hw0_icregs->lpc_mask = 0xffff;
+	it8172_hw0_icregs->pci_mask = 0xffff;
+	it8172_hw0_icregs->nmi_mask = 0xffff;
+
+	/* make all interrupts level triggered */
+	it8172_hw0_icregs->lb_trigger  = 0;
+	it8172_hw0_icregs->lpc_trigger = 0;
+	it8172_hw0_icregs->pci_trigger = 0;
+	it8172_hw0_icregs->nmi_trigger = 0;
+
+	/* active level setting */
+	/* uart, keyboard, and mouse are active high */
+	it8172_hw0_icregs->lpc_level = (0x10 | 0x2 | 0x1000);
+	it8172_hw0_icregs->lb_level |= 0x20;
+
+	/* keyboard and mouse are edge triggered */
+	it8172_hw0_icregs->lpc_trigger |= (0x2 | 0x1000);
+
+
+#if 0
+	// Enable this piece of code to make internal USB interrupt
+	// edge triggered.
+	it8172_hw0_icregs->pci_trigger |=
+		(1 << (IT8172_USB_IRQ - IT8172_PCI_DEV_IRQ_BASE));
+	it8172_hw0_icregs->pci_level &=
+		~(1 << (IT8172_USB_IRQ - IT8172_PCI_DEV_IRQ_BASE));
+#endif
+
+	for (i = 0; i <= IT8172_LAST_IRQ; i++) {
+		irq_desc[i].handler = &it8172_irq_type;
+		spin_lock_init(&irq_desc[i].lock);
+	}
+	irq_desc[MIPS_CPU_TIMER_IRQ].handler = &cp0_irq_type;
+	set_c0_status(ALLINTS_NOTIMER);
+}
+
+void mips_spurious_interrupt(struct pt_regs *regs)
+{
+#if 1
+	return;
+#else
+	unsigned long status, cause;
+
+	printk("got spurious interrupt\n");
+	status = read_c0_status();
+	cause = read_c0_cause();
+	printk("status %x cause %x\n", status, cause);
+	printk("epc %x badvaddr %x \n", regs->cp0_epc, regs->cp0_badvaddr);
+#endif
+}
+
+void it8172_hw0_irqdispatch(struct pt_regs *regs)
+{
+	int irq;
+	unsigned short intstatus = 0, status = 0;
+
+	intstatus = it8172_hw0_icregs->intstatus;
+	if (intstatus & 0x8) {
+		panic("Got NMI interrupt");
+	} else if (intstatus & 0x4) {
+		/* PCI interrupt */
+		irq = 0;
+		status |= it8172_hw0_icregs->pci_req;
+		while (!(status & 0x1)) {
+			irq++;
+			status >>= 1;
+		}
+		irq += IT8172_PCI_DEV_IRQ_BASE;
+	} else if (intstatus & 0x1) {
+		/* Local Bus interrupt */
+		irq = 0;
+		status |= it8172_hw0_icregs->lb_req;
+		while (!(status & 0x1)) {
+			irq++;
+			status >>= 1;
+		}
+		irq += IT8172_LB_IRQ_BASE;
+	} else if (intstatus & 0x2) {
+		/* LPC interrupt */
+		/* Since some lpc interrupts are edge triggered,
+		 * we could lose an interrupt this way because
+		 * we acknowledge all ints at onces. Revisit.
+		 */
+		status |= it8172_hw0_icregs->lpc_req;
+		it8172_hw0_icregs->lpc_req = 0; /* acknowledge ints */
+		irq = 0;
+		while (!(status & 0x1)) {
+			irq++;
+			status >>= 1;
+		}
+		irq += IT8172_LPC_IRQ_BASE;
+	} else
+		return;
+
+	do_IRQ(irq, regs);
+}
+
+void show_pending_irqs(void)
+{
+	fputs("intstatus:  ");
+	put32(it8172_hw0_icregs->intstatus);
+	puts("");
+
+	fputs("pci_req:  ");
+	put32(it8172_hw0_icregs->pci_req);
+	puts("");
+
+	fputs("lb_req:  ");
+	put32(it8172_hw0_icregs->lb_req);
+	puts("");
+
+	fputs("lpc_req:  ");
+	put32(it8172_hw0_icregs->lpc_req);
+	puts("");
+}
diff --git a/arch/mips/ite-boards/generic/it8172_cir.c b/arch/mips/ite-boards/generic/it8172_cir.c
new file mode 100644
index 0000000..19deb15
--- /dev/null
+++ b/arch/mips/ite-boards/generic/it8172_cir.c
@@ -0,0 +1,171 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	IT8172 Consumer IR port generic routines.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+
+#ifdef CONFIG_IT8172_CIR
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/it8172/it8172.h>
+#include <asm/it8172/it8172_cir.h>
+
+
+volatile struct it8172_cir_regs *cir_regs[NUM_CIR_PORTS] = {
+	(volatile struct it8172_cir_regs *)(KSEG1ADDR(IT8172_PCI_IO_BASE + IT_CIR0_BASE)),
+	(volatile struct it8172_cir_regs *)(KSEG1ADDR(IT8172_PCI_IO_BASE + IT_CIR1_BASE))};
+
+
+/*
+ * Initialize Consumer IR Port.
+ */
+int cir_port_init(struct cir_port *cir)
+{
+	int port = cir->port;
+	unsigned char data;
+
+	/* set baud rate */
+	cir_regs[port]->bdlr = cir->baud_rate & 0xff;
+	cir_regs[port]->bdhr = (cir->baud_rate >> 8) & 0xff;
+
+	/* set receiver control register */
+	cir_regs[port]->rcr = (CIR_SET_RDWOS(cir->rdwos) | CIR_SET_RXDCR(cir->rxdcr));
+
+	/* set carrier frequency register */
+	cir_regs[port]->cfr = (CIR_SET_CF(cir->cfq) | CIR_SET_HS(cir->hcfs));
+
+	/* set fifo threshold */
+	data = cir_regs[port]->mstcr & 0xf3;
+	data |= CIR_SET_FIFO_TL(cir->fifo_tl);
+	cir_regs[port]->mstcr = data;
+
+	clear_fifo(cir);
+	enable_receiver(cir);
+	disable_rx_demodulation(cir);
+
+	set_rx_active(cir);
+	int_enable(cir);
+	rx_int_enable(cir);
+
+	return 0;
+}
+
+
+void clear_fifo(struct cir_port *cir)
+{
+	cir_regs[cir->port]->mstcr |= CIR_FIFO_CLEAR;
+}
+
+void enable_receiver(struct cir_port *cir)
+{
+	cir_regs[cir->port]->rcr |= CIR_RXEN;
+}
+
+void disable_receiver(struct cir_port *cir)
+{
+	cir_regs[cir->port]->rcr &= ~CIR_RXEN;
+}
+
+void enable_rx_demodulation(struct cir_port *cir)
+{
+	cir_regs[cir->port]->rcr |= CIR_RXEND;
+}
+
+void disable_rx_demodulation(struct cir_port *cir)
+{
+	cir_regs[cir->port]->rcr &= ~CIR_RXEND;
+}
+
+void set_rx_active(struct cir_port *cir)
+{
+	cir_regs[cir->port]->rcr |= CIR_RXACT;
+}
+
+void int_enable(struct cir_port *cir)
+{
+	cir_regs[cir->port]->ier |= CIR_IEC;
+}
+
+void rx_int_enable(struct cir_port *cir)
+{
+	cir_regs[cir->port]->ier |= CIR_RDAIE;
+}
+
+void dump_regs(struct cir_port *cir)
+{
+	printk("mstcr %x ier %x iir %x cfr %x rcr %x tcr %x tfsr %x rfsr %x\n",
+	cir_regs[cir->port]->mstcr,
+	cir_regs[cir->port]->ier,
+	cir_regs[cir->port]->iir,
+	cir_regs[cir->port]->cfr,
+	cir_regs[cir->port]->rcr,
+	cir_regs[cir->port]->tcr,
+	cir_regs[cir->port]->tfsr,
+	cir_regs[cir->port]->rfsr);
+
+	while (cir_regs[cir->port]->iir & CIR_RDAI) {
+		printk("data %x\n", cir_regs[cir->port]->dr);
+	}
+}
+
+void dump_reg_addr(struct cir_port *cir)
+{
+	printk("dr %x mstcr %x ier %x iir %x cfr %x rcr %x tcr %x bdlr %x bdhr %x tfsr %x rfsr %x\n",
+	(unsigned)&cir_regs[cir->port]->dr,
+	(unsigned)&cir_regs[cir->port]->mstcr,
+	(unsigned)&cir_regs[cir->port]->ier,
+	(unsigned)&cir_regs[cir->port]->iir,
+	(unsigned)&cir_regs[cir->port]->cfr,
+	(unsigned)&cir_regs[cir->port]->rcr,
+	(unsigned)&cir_regs[cir->port]->tcr,
+	(unsigned)&cir_regs[cir->port]->bdlr,
+	(unsigned)&cir_regs[cir->port]->bdhr,
+	(unsigned)&cir_regs[cir->port]->tfsr,
+	(unsigned)&cir_regs[cir->port]->rfsr);
+}
+
+int cir_get_rx_count(struct cir_port *cir)
+{
+	return cir_regs[cir->port]->rfsr & CIR_RXFBC_MASK;
+}
+
+char cir_read_data(struct cir_port *cir)
+{
+	return cir_regs[cir->port]->dr;
+}
+
+char get_int_status(struct cir_port *cir)
+{
+	return cir_regs[cir->port]->iir;
+}
+#endif
diff --git a/arch/mips/ite-boards/generic/it8172_setup.c b/arch/mips/ite-boards/generic/it8172_setup.c
new file mode 100644
index 0000000..d808a67
--- /dev/null
+++ b/arch/mips/ite-boards/generic/it8172_setup.c
@@ -0,0 +1,309 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	IT8172/QED5231 board setup.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/serial_reg.h>
+#include <linux/major.h>
+#include <linux/kdev_t.h>
+#include <linux/root_dev.h>
+
+#include <asm/cpu.h>
+#include <asm/time.h>
+#include <asm/io.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/traps.h>
+#include <asm/it8172/it8172.h>
+#include <asm/it8712.h>
+
+extern struct resource ioport_resource;
+#ifdef CONFIG_SERIO_I8042
+int init_8712_keyboard(void);
+#endif
+
+extern int SearchIT8712(void);
+extern void InitLPCInterface(void);
+extern char * __init prom_getcmdline(void);
+extern void it8172_restart(char *command);
+extern void it8172_halt(void);
+extern void it8172_power_off(void);
+
+extern void (*board_time_init)(void);
+extern void (*board_timer_setup)(struct irqaction *irq);
+extern void it8172_time_init(void);
+extern void it8172_timer_setup(struct irqaction *irq);
+
+#ifdef CONFIG_IT8172_REVC
+struct {
+    struct resource ram;
+    struct resource pci_mem;
+    struct resource pci_io;
+    struct resource flash;
+    struct resource boot;
+} it8172_resources = {
+    { "RAM",           0,          0,          IORESOURCE_MEM }, /* to be initted */
+    { "PCI Mem",       0x10000000, 0x13FFFFFF, IORESOURCE_MEM },
+    { "PCI I/O",       0x14000000, 0x17FFFFFF                 },
+    { "Flash",         0x08000000, 0x0CFFFFFF                 },
+    { "Boot ROM",      0x1FC00000, 0x1FFFFFFF                 }
+};
+#else
+struct {
+    struct resource ram;
+    struct resource pci_mem0;
+    struct resource pci_mem1;
+    struct resource pci_io;
+    struct resource pci_mem2;
+    struct resource pci_mem3;
+    struct resource flash;
+    struct resource boot;
+} it8172_resources = {
+    { "RAM",           0,          0,          IORESOURCE_MEM }, /* to be initted */
+    { "PCI Mem0",      0x0C000000, 0x0FFFFFFF, IORESOURCE_MEM },
+    { "PCI Mem1",      0x10000000, 0x13FFFFFF, IORESOURCE_MEM },
+    { "PCI I/O",       0x14000000, 0x17FFFFFF                 },
+    { "PCI Mem2",      0x1A000000, 0x1BFFFFFF, IORESOURCE_MEM },
+    { "PCI Mem3",      0x1C000000, 0x1FBFFFFF, IORESOURCE_MEM },
+    { "Flash",         0x08000000, 0x0CFFFFFF                 },
+    { "Boot ROM",      0x1FC00000, 0x1FFFFFFF                 }
+};
+#endif
+
+
+void __init it8172_init_ram_resource(unsigned long memsize)
+{
+	it8172_resources.ram.end = memsize;
+}
+
+static void __init it8172_setup(void)
+{
+	unsigned short dsr;
+	char *argptr;
+
+	argptr = prom_getcmdline();
+#ifdef CONFIG_SERIAL_CONSOLE
+	if ((argptr = strstr(argptr, "console=")) == NULL) {
+		argptr = prom_getcmdline();
+		strcat(argptr, " console=ttyS0,115200");
+	}
+#endif
+
+	clear_c0_status(ST0_FR);
+
+	board_time_init = it8172_time_init;
+	board_timer_setup = it8172_timer_setup;
+
+	_machine_restart = it8172_restart;
+	_machine_halt = it8172_halt;
+	_machine_power_off = it8172_power_off;
+
+	/*
+	 * IO/MEM resources.
+	 * 
+	 * revisit this area.
+	 */
+	set_io_port_base(KSEG1);
+	ioport_resource.start = it8172_resources.pci_io.start;
+	ioport_resource.end = it8172_resources.pci_io.end;
+#ifdef CONFIG_IT8172_REVC
+	iomem_resource.start = it8172_resources.pci_mem.start;
+	iomem_resource.end = it8172_resources.pci_mem.end;
+#else
+	iomem_resource.start = it8172_resources.pci_mem0.start;
+	iomem_resource.end = it8172_resources.pci_mem3.end;
+#endif
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	ROOT_DEV = Root_RAM0;
+#endif
+
+	/*
+	 * Pull enabled devices out of standby
+	 */
+	IT_IO_READ16(IT_PM_DSR, dsr);
+
+	/*
+	 * Fixme: This breaks when these drivers are modules!!!
+	 */
+#ifdef CONFIG_SOUND_IT8172
+	dsr &= ~IT_PM_DSR_ACSB;
+#else
+	dsr |= IT_PM_DSR_ACSB;
+#endif
+#ifdef CONFIG_BLK_DEV_IT8172
+	dsr &= ~IT_PM_DSR_IDESB;
+#else
+	dsr |= IT_PM_DSR_IDESB;
+#endif
+	IT_IO_WRITE16(IT_PM_DSR, dsr);
+
+	InitLPCInterface();
+
+#ifdef CONFIG_MIPS_ITE8172
+	if (SearchIT8712()) {
+		printk("Found IT8712 Super IO\n");
+		/* enable IT8712 serial port */
+		LPCSetConfig(LDN_SERIAL1, 0x30, 0x01); /* enable */
+		LPCSetConfig(LDN_SERIAL1, 0x23, 0x01); /* clock selection */
+#ifdef CONFIG_SERIO_I8042
+		if (init_8712_keyboard()) {
+			printk("Unable to initialize keyboard\n");
+			LPCSetConfig(LDN_KEYBOARD, 0x30, 0x0); /* disable keyboard */
+		} else {
+			LPCSetConfig(LDN_KEYBOARD, 0x30, 0x1); /* enable keyboard */
+			LPCSetConfig(LDN_KEYBOARD, 0xf0, 0x2);
+			LPCSetConfig(LDN_KEYBOARD, 0x71, 0x3);
+
+			LPCSetConfig(LDN_MOUSE, 0x30, 0x1); /* enable mouse */
+
+			LPCSetConfig(0x4, 0x30, 0x1);
+			LPCSetConfig(0x4, 0xf4, LPCGetConfig(0x4, 0xf4) | 0x80);
+
+			if ((LPCGetConfig(LDN_KEYBOARD, 0x30) == 0) ||
+					(LPCGetConfig(LDN_MOUSE, 0x30) == 0))
+				printk("Error: keyboard or mouse not enabled\n");
+
+		}
+#endif
+	}
+	else {
+		printk("IT8712 Super IO not found\n");
+	}
+#endif
+
+#ifdef CONFIG_IT8172_CIR
+	{
+		unsigned long data;
+		//printk("Enabling CIR0\n");
+		IT_IO_READ16(IT_PM_DSR, data);
+		data &= ~IT_PM_DSR_CIR0SB;
+		IT_IO_WRITE16(IT_PM_DSR, data);
+		//printk("DSR register: %x\n", (unsigned)IT_IO_READ16(IT_PM_DSR, data));
+	}
+#endif
+#ifdef CONFIG_IT8172_SCR0
+	{
+		unsigned i;
+		/* Enable Smart Card Reader 0 */
+		/* First power it up */
+		IT_IO_READ16(IT_PM_DSR, i);
+		i &= ~IT_PM_DSR_SCR0SB;
+		IT_IO_WRITE16(IT_PM_DSR, i);
+		/* Then initialize its registers */
+		outb(( IT_SCR_SFR_GATE_UART_OFF     << IT_SCR_SFR_GATE_UART_BIT
+		      |IT_SCR_SFR_FET_CHARGE_213_US << IT_SCR_SFR_FET_CHARGE_BIT
+		      |IT_SCR_SFR_CARD_FREQ_3_5_MHZ << IT_SCR_SFR_CARD_FREQ_BIT
+		      |IT_SCR_SFR_FET_ACTIVE_INVERT << IT_SCR_SFR_FET_ACTIVE_BIT
+		      |IT_SCR_SFR_ENABLE_ON         << IT_SCR_SFR_ENABLE_BIT),
+		     IT8172_PCI_IO_BASE + IT_SCR0_BASE + IT_SCR_SFR);
+		outb(IT_SCR_SCDR_RESET_MODE_ASYNC << IT_SCR_SCDR_RESET_MODE_BIT,
+		     IT8172_PCI_IO_BASE + IT_SCR0_BASE + IT_SCR_SCDR);
+	}
+#endif /* CONFIG_IT8172_SCR0 */
+#ifdef CONFIG_IT8172_SCR1
+	{
+		unsigned i;
+		/* Enable Smart Card Reader 1 */
+		/* First power it up */
+		IT_IO_READ16(IT_PM_DSR, i);
+		i &= ~IT_PM_DSR_SCR1SB;
+		IT_IO_WRITE16(IT_PM_DSR, i);
+		/* Then initialize its registers */
+		outb(( IT_SCR_SFR_GATE_UART_OFF     << IT_SCR_SFR_GATE_UART_BIT
+		      |IT_SCR_SFR_FET_CHARGE_213_US << IT_SCR_SFR_FET_CHARGE_BIT
+		      |IT_SCR_SFR_CARD_FREQ_3_5_MHZ << IT_SCR_SFR_CARD_FREQ_BIT
+		      |IT_SCR_SFR_FET_ACTIVE_INVERT << IT_SCR_SFR_FET_ACTIVE_BIT
+		      |IT_SCR_SFR_ENABLE_ON         << IT_SCR_SFR_ENABLE_BIT),
+		     IT8172_PCI_IO_BASE + IT_SCR1_BASE + IT_SCR_SFR);
+		outb(IT_SCR_SCDR_RESET_MODE_ASYNC << IT_SCR_SCDR_RESET_MODE_BIT,
+		     IT8172_PCI_IO_BASE + IT_SCR1_BASE + IT_SCR_SCDR);
+	}
+#endif /* CONFIG_IT8172_SCR1 */
+}
+
+early_initcall(it8172_setup);
+
+#ifdef CONFIG_SERIO_I8042
+/*
+ * According to the ITE Special BIOS Note for waking up the
+ * keyboard controller...
+ */
+static int init_8712_keyboard(void)
+{
+	unsigned int cmd_port = 0x14000064;
+	unsigned int data_port = 0x14000060;
+	                         ^^^^^^^^^^^
+	Somebody here doesn't grok the concept of io ports.
+
+	unsigned char data;
+	int i;
+
+	outb(0xaa, cmd_port); /* send self-test cmd */
+	i = 0;
+	while (!(inb(cmd_port) & 0x1)) { /* wait output buffer full */
+		i++;
+		if (i > 0xffffff)
+			return 1;
+	}
+
+	data = inb(data_port);
+	outb(0xcb, cmd_port); /* set ps2 mode */
+	while (inb(cmd_port) & 0x2) { /* wait while input buffer full */
+		i++;
+		if (i > 0xffffff)
+			return 1;
+	}
+	outb(0x01, data_port);
+	while (inb(cmd_port) & 0x2) { /* wait while input buffer full */
+		i++;
+		if (i > 0xffffff)
+			return 1;
+	}
+
+	outb(0x60, cmd_port); /* write 8042 command byte */
+	while (inb(cmd_port) & 0x2) { /* wait while input buffer full */
+		i++;
+		if (i > 0xffffff)
+			return 1;
+	}
+	outb(0x45, data_port); /* at interface, keyboard enabled, system flag */
+	while (inb(cmd_port) & 0x2) { /* wait while input buffer full */
+		i++;
+		if (i > 0xffffff)
+			return 1;
+	}
+
+	outb(0xae, cmd_port); /* enable interface */
+	return 0;
+}
+#endif
diff --git a/arch/mips/ite-boards/generic/lpc.c b/arch/mips/ite-boards/generic/lpc.c
new file mode 100644
index 0000000..cc7584f
--- /dev/null
+++ b/arch/mips/ite-boards/generic/lpc.c
@@ -0,0 +1,144 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	ITE Semi IT8712 Super I/O functions.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <asm/io.h>
+#include <asm/types.h>
+#include <asm/it8712.h>
+#include <asm/it8172/it8172.h>
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+void LPCEnterMBPnP(void)
+{
+	int i;
+	unsigned char key[4] = {0x87, 0x01, 0x55, 0x55};
+
+	for (i = 0; i<4; i++)
+		outb(key[i], LPC_KEY_ADDR);
+
+}
+
+void LPCExitMBPnP(void)
+{
+	outb(0x02, LPC_KEY_ADDR);
+	outb(0x02, LPC_DATA_ADDR);
+}
+
+void LPCSetConfig(char LdnNumber, char Index, char data)
+{
+	LPCEnterMBPnP();				// Enter IT8712 MB PnP mode
+	outb(0x07, LPC_KEY_ADDR);
+	outb(LdnNumber, LPC_DATA_ADDR);
+	outb(Index, LPC_KEY_ADDR);
+	outb(data, LPC_DATA_ADDR);
+	LPCExitMBPnP();
+}
+
+char LPCGetConfig(char LdnNumber, char Index)
+{
+	char rtn;
+
+	LPCEnterMBPnP();				// Enter IT8712 MB PnP mode
+	outb(0x07, LPC_KEY_ADDR);
+	outb(LdnNumber, LPC_DATA_ADDR);
+	outb(Index, LPC_KEY_ADDR);
+	rtn = inb(LPC_DATA_ADDR);
+	LPCExitMBPnP();
+	return rtn;
+}
+
+int SearchIT8712(void)
+{
+	unsigned char Id1, Id2;
+	unsigned short Id;
+
+	LPCEnterMBPnP();
+	outb(0x20, LPC_KEY_ADDR); /* chip id byte 1 */
+	Id1 = inb(LPC_DATA_ADDR);
+	outb(0x21, LPC_KEY_ADDR); /* chip id byte 2 */
+	Id2 = inb(LPC_DATA_ADDR);
+	Id = (Id1 << 8) | Id2;
+	LPCExitMBPnP();
+	if (Id == 0x8712)
+		return TRUE;
+	else
+		return FALSE;
+}
+
+void InitLPCInterface(void)
+{
+	unsigned char bus, dev_fn;
+	unsigned long data;
+
+	bus = 0;
+	dev_fn = 1<<3 | 4;
+
+
+	/* pci cmd, SERR# Enable */
+	IT_WRITE(IT_CONFADDR,
+		 (bus         << IT_BUSNUM_SHF)   |
+		 (dev_fn      << IT_FUNCNUM_SHF) |
+		 ((0x4 / 4) << IT_REGNUM_SHF));
+	IT_READ(IT_CONFDATA, data);
+	data |= 0x0100;
+	IT_WRITE(IT_CONFADDR,
+		 (bus         << IT_BUSNUM_SHF)   |
+		 (dev_fn      << IT_FUNCNUM_SHF) |
+		 ((0x4 / 4) << IT_REGNUM_SHF));
+	IT_WRITE(IT_CONFDATA, data);
+
+	/* setup serial irq control register */
+	IT_WRITE(IT_CONFADDR,
+		 (bus         << IT_BUSNUM_SHF)   |
+		 (dev_fn      << IT_FUNCNUM_SHF) |
+		 ((0x48 / 4) << IT_REGNUM_SHF));
+	IT_READ(IT_CONFDATA, data);
+	data  = (data & 0xffff00ff) | 0xc400;
+	IT_WRITE(IT_CONFADDR,
+		 (bus         << IT_BUSNUM_SHF)   |
+		 (dev_fn      << IT_FUNCNUM_SHF) |
+		 ((0x48 / 4) << IT_REGNUM_SHF));
+	IT_WRITE(IT_CONFDATA, data);
+
+
+	/* Enable I/O Space Subtractive Decode */
+	/* default 0x4C is 0x3f220000 */
+	IT_WRITE(IT_CONFADDR,
+		 (bus         << IT_BUSNUM_SHF)   |
+		 (dev_fn      << IT_FUNCNUM_SHF) |
+		 ((0x4C / 4) << IT_REGNUM_SHF));
+	IT_WRITE(IT_CONFDATA, 0x3f2200f3);
+}
diff --git a/arch/mips/ite-boards/generic/pmon_prom.c b/arch/mips/ite-boards/generic/pmon_prom.c
new file mode 100644
index 0000000..6e505af
--- /dev/null
+++ b/arch/mips/ite-boards/generic/pmon_prom.c
@@ -0,0 +1,136 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *    PROM library initialisation code, assuming a version of
+ *    pmon is the boot code.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * This file was derived from Carsten Langgaard's
+ * arch/mips/mips-boards/xx files.
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+
+extern int prom_argc;
+extern char **prom_argv, **prom_envp;
+
+typedef struct
+{
+    char *name;
+/*    char *val; */
+}t_env_var;
+
+
+char * __init prom_getcmdline(void)
+{
+	return &(arcs_cmdline[0]);
+}
+
+void  __init prom_init_cmdline(void)
+{
+	char *cp;
+	int actr;
+
+	actr = 1; /* Always ignore argv[0] */
+
+	cp = &(arcs_cmdline[0]);
+	while(actr < prom_argc) {
+	        strcpy(cp, prom_argv[actr]);
+		cp += strlen(prom_argv[actr]);
+		*cp++ = ' ';
+		actr++;
+	}
+	if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
+		--cp;
+	*cp = '\0';
+
+}
+
+
+char *prom_getenv(char *envname)
+{
+	/*
+	 * Return a pointer to the given environment variable.
+	 * Environment variables are stored in the form of "memsize=64".
+	 */
+
+	t_env_var *env = (t_env_var *)prom_envp;
+	int i;
+
+	i = strlen(envname);
+
+	while(env->name) {
+		if(strncmp(envname, env->name, i) == 0) {
+			return(env->name + strlen(envname) + 1);
+		}
+		env++;
+	}
+	return(NULL);
+}
+
+static inline unsigned char str2hexnum(unsigned char c)
+{
+	if(c >= '0' && c <= '9')
+	return c - '0';
+	if(c >= 'a' && c <= 'f')
+	return c - 'a' + 10;
+	return 0; /* foo */
+}
+
+unsigned long __init prom_free_prom_memory(void)
+{
+	return 0;
+}
+
+unsigned long __init prom_get_memsize(void)
+{
+	char *memsize_str;
+	unsigned int memsize;
+
+	memsize_str = prom_getenv("memsize");
+	if (!memsize_str) {
+#ifdef CONFIG_MIPS_ITE8172
+		memsize = 32;
+#elif defined(CONFIG_MIPS_IVR)
+		memsize = 64;
+#else
+		memsize = 8;
+#endif
+		printk("memsize unknown: setting to %dMB\n", memsize);
+	} else {
+		printk("memsize: %s\n", memsize_str);
+		memsize = simple_strtol(memsize_str, NULL, 0);
+	}
+	return memsize;
+}
diff --git a/arch/mips/ite-boards/generic/puts.c b/arch/mips/ite-boards/generic/puts.c
new file mode 100644
index 0000000..20b02df
--- /dev/null
+++ b/arch/mips/ite-boards/generic/puts.c
@@ -0,0 +1,139 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Low level uart routines to directly access a 16550 uart.
+ *
+ * Copyright 2000,2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+
+#define SERIAL_BASE   0xB4011800	/* it8172 */
+#define SER_CMD       5
+#define SER_DATA      0x00
+#define TX_BUSY       0x20
+
+#define TIMEOUT       0xffff
+#undef SLOW_DOWN
+
+static const char digits[16] = "0123456789abcdef";
+static volatile unsigned char *const com1 = (unsigned char *) SERIAL_BASE;
+
+
+#ifdef SLOW_DOWN
+static inline void slow_down()
+{
+	int k;
+	for (k = 0; k < 10000; k++);
+}
+#else
+#define slow_down()
+#endif
+
+void putch(const unsigned char c)
+{
+	unsigned char ch;
+	int i = 0;
+
+	do {
+		ch = com1[SER_CMD];
+		slow_down();
+		i++;
+		if (i > TIMEOUT) {
+			break;
+		}
+	} while (0 == (ch & TX_BUSY));
+	com1[SER_DATA] = c;
+}
+
+void puts(unsigned char *cp)
+{
+	unsigned char ch;
+	int i = 0;
+
+	while (*cp) {
+		do {
+			ch = com1[SER_CMD];
+			slow_down();
+			i++;
+			if (i > TIMEOUT) {
+				break;
+			}
+		} while (0 == (ch & TX_BUSY));
+		com1[SER_DATA] = *cp++;
+	}
+	putch('\r');
+	putch('\n');
+}
+
+void fputs(unsigned char *cp)
+{
+	unsigned char ch;
+	int i = 0;
+
+	while (*cp) {
+
+		do {
+			ch = com1[SER_CMD];
+			slow_down();
+			i++;
+			if (i > TIMEOUT) {
+				break;
+			}
+		} while (0 == (ch & TX_BUSY));
+		com1[SER_DATA] = *cp++;
+	}
+}
+
+
+void put64(uint64_t ul)
+{
+	int cnt;
+	unsigned ch;
+
+	cnt = 16;		/* 16 nibbles in a 64 bit long */
+	putch('0');
+	putch('x');
+	do {
+		cnt--;
+		ch = (unsigned char) (ul >> cnt * 4) & 0x0F;
+		putch(digits[ch]);
+	} while (cnt > 0);
+}
+
+void put32(unsigned u)
+{
+	int cnt;
+	unsigned ch;
+
+	cnt = 8;		/* 8 nibbles in a 32 bit long */
+	putch('0');
+	putch('x');
+	do {
+		cnt--;
+		ch = (unsigned char) (u >> cnt * 4) & 0x0F;
+		putch(digits[ch]);
+	} while (cnt > 0);
+}
diff --git a/arch/mips/ite-boards/generic/reset.c b/arch/mips/ite-boards/generic/reset.c
new file mode 100644
index 0000000..03bd5ba
--- /dev/null
+++ b/arch/mips/ite-boards/generic/reset.c
@@ -0,0 +1,60 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	ITE 8172 reset routines.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/cacheflush.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+
+void it8172_restart()
+{
+	set_c0_status(ST0_BEV | ST0_ERL);
+	change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+	flush_cache_all();
+	write_c0_wired(0);
+	__asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
+}
+
+void it8172_halt(void)
+{
+	printk(KERN_NOTICE "\n** You can safely turn off the power\n");
+	while (1)
+		__asm__(".set\tmips3\n\t"
+	                "wait\n\t"
+			".set\tmips0");
+}
+
+void it8172_power_off(void)
+{
+	it8172_halt();
+}
diff --git a/arch/mips/ite-boards/generic/time.c b/arch/mips/ite-boards/generic/time.c
new file mode 100644
index 0000000..30a6c0d
--- /dev/null
+++ b/arch/mips/ite-boards/generic/time.c
@@ -0,0 +1,247 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * Copyright (C) 2003 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * Setting up the clock on the MIPS boards.
+ */
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/spinlock.h>
+
+#include <asm/time.h>
+#include <asm/mipsregs.h>
+#include <asm/ptrace.h>
+#include <asm/it8172/it8172.h>
+#include <asm/it8172/it8172_int.h>
+#include <asm/debug.h>
+
+#define IT8172_RTC_ADR_REG  (IT8172_PCI_IO_BASE + IT_RTC_BASE)
+#define IT8172_RTC_DAT_REG  (IT8172_RTC_ADR_REG + 1)
+#define IT8172_RTC_CENTURY_REG  (IT8172_PCI_IO_BASE + IT_RTC_CENTURY)
+
+static volatile char *rtc_adr_reg = (char*)KSEG1ADDR(IT8172_RTC_ADR_REG);
+static volatile char *rtc_dat_reg = (char*)KSEG1ADDR(IT8172_RTC_DAT_REG);
+static volatile char *rtc_century_reg = (char*)KSEG1ADDR(IT8172_RTC_CENTURY_REG);
+
+unsigned char it8172_rtc_read_data(unsigned long addr)
+{
+	unsigned char retval;
+
+	*rtc_adr_reg = addr;
+	retval =  *rtc_dat_reg;
+	return retval;
+}
+
+void it8172_rtc_write_data(unsigned char data, unsigned long addr)
+{
+	*rtc_adr_reg = addr;
+	*rtc_dat_reg = data;
+}
+
+#undef 	CMOS_READ
+#undef 	CMOS_WRITE
+#define	CMOS_READ(addr)			it8172_rtc_read_data(addr)
+#define CMOS_WRITE(data, addr) 		it8172_rtc_write_data(data, addr)
+
+static unsigned char saved_control;	/* remember rtc control reg */
+static inline int rtc_24h(void) { return saved_control & RTC_24H; }
+static inline int rtc_dm_binary(void) { return saved_control & RTC_DM_BINARY; }
+
+static inline unsigned char
+bin_to_hw(unsigned char c)
+{
+	if (rtc_dm_binary()) 
+		return c;
+	else
+		return ((c/10) << 4) + (c%10);
+}
+
+static inline unsigned char
+hw_to_bin(unsigned char c)
+{
+	if (rtc_dm_binary())
+		return c;
+	else
+		return (c>>4)*10 + (c &0xf);
+}
+
+/* 0x80 bit indicates pm in 12-hour format */
+static inline unsigned char
+hour_bin_to_hw(unsigned char c)
+{
+	if (rtc_24h()) 
+		return bin_to_hw(c);
+	if (c >= 12) 
+		return 0x80 | bin_to_hw((c==12)?12:c-12);  /* 12 is 12pm */
+	else
+		return bin_to_hw((c==0)?12:c);	/* 0 is 12 AM, not 0 am */
+}
+
+static inline unsigned char
+hour_hw_to_bin(unsigned char c)
+{
+	unsigned char tmp = hw_to_bin(c&0x3f);
+	if (rtc_24h())
+		return tmp;
+	if (c & 0x80) 
+		return (tmp==12)?12:tmp+12;  	/* 12pm is 12, not 24 */
+	else 
+		return (tmp==12)?0:tmp;		/* 12am is 0 */
+}
+
+static unsigned long r4k_offset; /* Amount to increment compare reg each time */
+static unsigned long r4k_cur;    /* What counter should be at next timer irq */
+extern unsigned int mips_hpt_frequency;
+
+/*
+ * Figure out the r4k offset, the amount to increment the compare
+ * register for each time tick.
+ * Use the RTC to calculate offset.
+ */
+static unsigned long __init cal_r4koff(void)
+{
+	unsigned int flags;
+
+	local_irq_save(flags);
+
+	/* Start counter exactly on falling edge of update flag */
+	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
+	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
+
+	/* Start r4k counter. */
+	write_c0_count(0);
+
+	/* Read counter exactly on falling edge of update flag */
+	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
+	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
+
+	mips_hpt_frequency = read_c0_count();
+
+	/* restore interrupts */
+	local_irq_restore(flags);
+
+	return (mips_hpt_frequency / HZ);
+}
+
+static unsigned long 
+it8172_rtc_get_time(void)
+{
+	unsigned int year, mon, day, hour, min, sec;
+	unsigned int flags;
+
+	/* avoid update-in-progress. */
+	for (;;) {
+		local_irq_save(flags);
+		if (! (CMOS_READ(RTC_REG_A) & RTC_UIP))
+			break;
+		/* don't hold intr closed all the time */
+		local_irq_restore(flags);
+	}
+
+	/* Read regs. */
+	sec = hw_to_bin(CMOS_READ(RTC_SECONDS));
+	min = hw_to_bin(CMOS_READ(RTC_MINUTES));
+	hour = hour_hw_to_bin(CMOS_READ(RTC_HOURS));
+	day = hw_to_bin(CMOS_READ(RTC_DAY_OF_MONTH));
+	mon = hw_to_bin(CMOS_READ(RTC_MONTH));
+	year = hw_to_bin(CMOS_READ(RTC_YEAR)) + 
+		hw_to_bin(*rtc_century_reg) * 100;
+
+	/* restore interrupts */
+	local_irq_restore(flags);
+		
+	return mktime(year, mon, day, hour, min, sec);
+}
+
+static int
+it8172_rtc_set_time(unsigned long t)
+{
+	struct rtc_time tm;
+	unsigned int flags;
+
+	/* convert */
+	to_tm(t, &tm);
+
+	/* avoid update-in-progress. */
+	for (;;) {
+		local_irq_save(flags);
+		if (! (CMOS_READ(RTC_REG_A) & RTC_UIP))
+			break;
+		/* don't hold intr closed all the time */
+		local_irq_restore(flags);
+	}
+
+	*rtc_century_reg = bin_to_hw(tm.tm_year/100);
+	CMOS_WRITE(bin_to_hw(tm.tm_sec), RTC_SECONDS);
+	CMOS_WRITE(bin_to_hw(tm.tm_min), RTC_MINUTES);
+	CMOS_WRITE(hour_bin_to_hw(tm.tm_hour), RTC_HOURS);
+	CMOS_WRITE(bin_to_hw(tm.tm_mday), RTC_DAY_OF_MONTH);
+	CMOS_WRITE(bin_to_hw(tm.tm_mon+1), RTC_MONTH);	/* tm_mon starts from 0 */
+	CMOS_WRITE(bin_to_hw(tm.tm_year%100), RTC_YEAR);
+
+	/* restore interrupts */
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+void __init it8172_time_init(void)
+{
+        unsigned int est_freq, flags;
+
+	local_irq_save(flags);
+
+	saved_control = CMOS_READ(RTC_CONTROL);
+
+	printk("calculating r4koff... ");
+	r4k_offset = cal_r4koff();
+	printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset);
+
+	est_freq = 2*r4k_offset*HZ;
+	est_freq += 5000;    /* round */
+	est_freq -= est_freq%10000;
+	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
+	       (est_freq%1000000)*100/1000000);
+
+	local_irq_restore(flags);
+
+	rtc_get_time = it8172_rtc_get_time;
+	rtc_set_time = it8172_rtc_set_time;
+}
+
+#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
+void __init it8172_timer_setup(struct irqaction *irq)
+{
+	puts("timer_setup\n");
+	put32(NR_IRQS);
+	puts("");
+        /* we are using the cpu counter for timer interrupts */
+	setup_irq(MIPS_CPU_TIMER_IRQ, irq);
+
+        /* to generate the first timer interrupt */
+	r4k_cur = (read_c0_count() + r4k_offset);
+	write_c0_compare(r4k_cur);
+	set_c0_status(ALLINTS);
+}
diff --git a/arch/mips/ite-boards/ivr/Makefile b/arch/mips/ite-boards/ivr/Makefile
new file mode 100644
index 0000000..e4fa604
--- /dev/null
+++ b/arch/mips/ite-boards/ivr/Makefile
@@ -0,0 +1,10 @@
+#
+#  Copyright 2000 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc.
+#     	ppopov@mvista.com or source@mvista.com
+#
+# Makefile for the Globespan IVR board,
+# board-specific files.
+#
+
+obj-y		+= init.o
diff --git a/arch/mips/ite-boards/ivr/README b/arch/mips/ite-boards/ivr/README
new file mode 100644
index 0000000..aa7d8db
--- /dev/null
+++ b/arch/mips/ite-boards/ivr/README
@@ -0,0 +1,3 @@
+This is not really a board made by ITE Semi, but it's very
+similar to the ITE QED-4N-S01B board.  The IVR board is made
+by Globespan and it's a reference board for the PVR chip.
diff --git a/arch/mips/ite-boards/ivr/init.c b/arch/mips/ite-boards/ivr/init.c
new file mode 100644
index 0000000..ea4e193
--- /dev/null
+++ b/arch/mips/ite-boards/ivr/init.c
@@ -0,0 +1,84 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	IVR board setup.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <asm/it8172/it8172.h>
+#include <asm/it8172/it8172_dbg.h>
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+
+extern char _end;
+extern void  __init prom_init_cmdline(void);
+extern unsigned long __init prom_get_memsize(void);
+extern void __init it8172_init_ram_resource(unsigned long memsize);
+
+#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+#define PFN_ALIGN(x)	(((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
+
+const char *get_system_type(void)
+{
+	return "Globespan IVR";
+}
+
+void __init prom_init(void)
+{
+	unsigned long mem_size;
+	unsigned long pcicr;
+
+	prom_argc = fw_arg0;
+	prom_argv = (char **) fw_arg1;
+	prom_envp = (int *) fw_arg3;
+
+	mips_machgroup = MACH_GROUP_GLOBESPAN;
+	mips_machtype = MACH_IVR;  /* Globespan's iTVC15 reference board */
+
+	prom_init_cmdline();
+
+	/* pmon does not set memsize */
+	mem_size = prom_get_memsize();
+	mem_size = mem_size << 20;
+
+	/*
+	 * make the entire physical memory visible to pci bus masters
+	 */
+	IT_READ(IT_MC_PCICR, pcicr);
+	pcicr &= ~0x1f;
+	pcicr |= (mem_size - 1) >> 22;
+	IT_WRITE(IT_MC_PCICR, pcicr);
+
+	it8172_init_ram_resource(mem_size);
+	add_memory_region(0, mem_size, BOOT_MEM_RAM);
+}
diff --git a/arch/mips/ite-boards/qed-4n-s01b/Makefile b/arch/mips/ite-boards/qed-4n-s01b/Makefile
new file mode 100644
index 0000000..bb9972a
--- /dev/null
+++ b/arch/mips/ite-boards/qed-4n-s01b/Makefile
@@ -0,0 +1,10 @@
+#
+#  Copyright 2000 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc.
+#     	ppopov@mvista.com or source@mvista.com
+#
+# Makefile for the ITE 8172 (qed-4n-s01b) board, board
+# specific files.
+#
+
+obj-y := init.o
diff --git a/arch/mips/ite-boards/qed-4n-s01b/README b/arch/mips/ite-boards/qed-4n-s01b/README
new file mode 100644
index 0000000..fb4b519
--- /dev/null
+++ b/arch/mips/ite-boards/qed-4n-s01b/README
@@ -0,0 +1,2 @@
+This is an ITE (www.iteusa.com) eval board for the ITE 8172G
+system controller, with a QED 5231 CPU.
diff --git a/arch/mips/ite-boards/qed-4n-s01b/init.c b/arch/mips/ite-boards/qed-4n-s01b/init.c
new file mode 100644
index 0000000..56dca7e
--- /dev/null
+++ b/arch/mips/ite-boards/qed-4n-s01b/init.c
@@ -0,0 +1,85 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	IT8172/QED5231 board setup.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <asm/it8172/it8172.h>
+#include <asm/it8172/it8172_dbg.h>
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+
+extern char _end;
+extern void  __init prom_init_cmdline(void);
+extern unsigned long __init prom_get_memsize(void);
+extern void __init it8172_init_ram_resource(unsigned long memsize);
+
+#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+#define PFN_ALIGN(x)	(((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
+
+const char *get_system_type(void)
+{
+	return "ITE QED-4N-S01B";
+}
+
+void __init prom_init(void)
+{
+	unsigned long mem_size;
+	unsigned long pcicr;
+
+	prom_argc = fw_arg0;
+	prom_argv = (char **) fw_arg1;
+	prom_envp = (int *) fw_arg3;
+
+	mips_machgroup = MACH_GROUP_ITE;
+	mips_machtype = MACH_QED_4N_S01B;  /* ITE board name/number */
+
+	prom_init_cmdline();
+	mem_size = prom_get_memsize();
+
+	printk("Memory size: %dMB\n", (unsigned)mem_size);
+
+	mem_size <<= 20; /* MB */
+
+	/*
+	 * make the entire physical memory visible to pci bus masters
+	 */
+	IT_READ(IT_MC_PCICR, pcicr);
+	pcicr &= ~0x1f;
+	pcicr |= (mem_size - 1) >> 22;
+	IT_WRITE(IT_MC_PCICR, pcicr);
+
+	it8172_init_ram_resource(mem_size);
+	add_memory_region(0, mem_size, BOOT_MEM_RAM);
+}
diff --git a/arch/mips/jazz/Makefile b/arch/mips/jazz/Makefile
new file mode 100644
index 0000000..8574924
--- /dev/null
+++ b/arch/mips/jazz/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the Jazz family specific parts of the kernel
+#
+
+obj-y	 	:= int-handler.o irq.o jazzdma.o reset.o setup.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/jazz/int-handler.S b/arch/mips/jazz/int-handler.S
new file mode 100644
index 0000000..4dbcf91
--- /dev/null
+++ b/arch/mips/jazz/int-handler.S
@@ -0,0 +1,282 @@
+/*
+ * 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, 1996, 1997, 1998 by Ralf Baechle and Andreas Busse
+ *
+ * Jazz family specific interrupt stuff
+ *
+ * To do: On Jazz machines we remap some non-ISA interrupts to ISA
+ *        interrupts.  These interrupts should use their own vectors.
+ *        Squeeze the last cycles out of the handlers.  Only a dead
+ *        cycle is a good cycle.
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/jazz.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/*
+ * jazz_handle_int: Interrupt handler for the ACER Pica-61 boards
+ */
+		.set	noreorder
+
+		NESTED(jazz_handle_int, PT_SIZE, ra)
+		.set	noat
+		SAVE_ALL
+		CLI
+		.set	at
+
+		/*
+		 * Get pending interrupts
+		 */
+		mfc0	t0,CP0_CAUSE		# get pending interrupts
+		mfc0	t1,CP0_STATUS		# get enabled interrupts
+		and	t0,t1			# isolate allowed ones
+		andi	t0,0xff00		# isolate pending bits
+		beqz	t0,3f
+		sll	t0,16			# delay slot
+
+		/*
+		 * Find irq with highest priority
+		 * FIXME: This is slow - use binary search
+		 */
+		la	t1,ll_vectors
+1:		bltz	t0,2f			# found pending irq
+		sll	t0,1
+		b	1b
+		subu	t1,PTRSIZE		# delay slot
+
+		/*
+		 * Do the low-level stuff
+		 */
+2:		lw	t0,(t1)
+		jr	t0
+		nop				# delay slot
+		END(jazz_handle_int)
+
+ll_sw0:		li	s1,~IE_SW0
+		mfc0	t0,CP0_CAUSE
+		and	t0,s1
+		mtc0	t0,CP0_CAUSE
+		PANIC("Unimplemented sw0 handler")
+
+ll_sw1:		li	s1,~IE_SW1
+		mfc0	t0,CP0_CAUSE
+		and	t0,s1
+		mtc0	t0,CP0_CAUSE
+		PANIC("Unimplemented sw1 handler")
+
+ll_local_dma:	li	s1,~IE_IRQ0
+		PANIC("Unimplemented local_dma handler")
+
+ll_local_dev:	lbu	t0,JAZZ_IO_IRQ_SOURCE
+#if PTRSIZE == 8	/* True 64 bit kernel */
+		dsll	t0,1
+#endif
+		.set	reorder
+		LONG_L	t0,local_vector(t0)
+		jr	t0
+		.set	noreorder
+
+/*
+ * The braindead PICA hardware gives us no way to distinguish if we really
+ * received interrupt 7 from the (E)ISA bus or if we just received an
+ * interrupt with no findable cause.  This sometimes happens with braindead
+ * cards.  Oh well - for all the Jazz boxes slots are more or less just
+ * whistles and bells and we're aware of the problem.
+ */
+ll_isa_irq:	lw	a0, JAZZ_EISA_IRQ_ACK
+
+		jal	do_IRQ
+		 move	a1,sp
+
+		j	ret_from_irq
+		nop
+
+/*
+ * Hmm...  This is not just a plain PC clone so the question is
+ * which devices on Jazz machines can generate an (E)ISA NMI?
+ * (Writing to nonexistent memory?)
+ */
+ll_isa_nmi:	li	s1,~IE_IRQ3
+		PANIC("Unimplemented isa_nmi handler")
+
+/*
+ * Timer IRQ - remapped to be more similar to an IBM compatible.
+ *
+ * The timer interrupt is handled specially to ensure that the jiffies
+ * variable is updated at all times.  Specifically, the timer interrupt is
+ * just like the complete handlers except that it is invoked with interrupts
+ * disabled and should never re-enable them.  If other interrupts were
+ * allowed to be processed while the timer interrupt is active, then the
+ * other interrupts would have to avoid using the jiffies variable for delay
+ * and interval timing operations to avoid hanging the system.
+ */
+ll_timer:	lw	zero,JAZZ_TIMER_REGISTER # timer irq cleared on read
+		li	s1,~IE_IRQ4
+
+		li	a0, JAZZ_TIMER_IRQ
+		jal	do_IRQ
+		 move	a1,sp
+
+		mfc0	t0,CP0_STATUS		# disable interrupts again
+		ori	t0,1
+		xori	t0,1
+		mtc0	t0,CP0_STATUS
+
+		j	ret_from_irq
+		 nop
+
+/*
+ * CPU count/compare IRQ (unused)
+ */
+ll_count:	j	ret_from_irq
+		 mtc0	zero,CP0_COMPARE
+
+#if 0
+/*
+ * Call the handler for the interrupt
+ * (Currently unused)
+ */
+call_real:	/*
+		 * temporarily disable interrupt
+		 */
+		mfc0	t2,CP0_STATUS
+		and	t2,s1
+		mtc0	t2,CP0_STATUS
+		nor	s1,zero,s1
+		jal	do_IRQ
+
+		/*
+		 * reenable interrupt
+		 */
+		mfc0	t2,CP0_STATUS
+		or	t2,s1
+		mtc0	t2,CP0_STATUS
+		j	ret_from_irq
+#endif
+
+		.data
+		PTR	ll_sw0			# SW0
+		PTR	ll_sw1			# SW1
+		PTR	ll_local_dma		# Local DMA
+		PTR	ll_local_dev		# Local devices
+		PTR	ll_isa_irq		# ISA IRQ
+		PTR	ll_isa_nmi		# ISA NMI
+		PTR	ll_timer		# Timer
+ll_vectors:	PTR	ll_count		# Count/Compare IRQ
+
+		/*
+		 * Interrupt handlers for local devices.
+		 */
+		.text
+		.set	reorder
+loc_no_irq:	PANIC("Unimplemented loc_no_irq handler")
+/*
+ * Parallel port IRQ
+ */
+loc_parallel:	li	s1,~JAZZ_IE_PARALLEL
+		li	a0,JAZZ_PARALLEL_IRQ
+		b	loc_call
+
+/*
+ * Floppy IRQ
+ */
+loc_floppy:	li	s1,~JAZZ_IE_FLOPPY
+		li	a0,JAZZ_FLOPPY_IRQ
+		b	loc_call
+
+/*
+ * Sound IRQ
+ */
+loc_sound:	PANIC("Unimplemented loc_sound handler")
+loc_video:	PANIC("Unimplemented loc_video handler")
+
+/*
+ * Ethernet interrupt handler
+ */
+loc_ethernet: 	li	s1,~JAZZ_IE_ETHERNET
+		li	a0,JAZZ_ETHERNET_IRQ
+		b	loc_call
+
+/*
+ * SCSI interrupt handler
+ */
+loc_scsi:	li	s1,~JAZZ_IE_SCSI
+		li	a0,JAZZ_SCSI_IRQ
+		b	loc_call
+
+/*
+ * Keyboard interrupt handler
+ */
+loc_keyboard:	li	s1,~JAZZ_IE_KEYBOARD
+		li	a0,JAZZ_KEYBOARD_IRQ
+		b	loc_call
+
+/*
+ * Mouse interrupt handler
+ */
+loc_mouse:	li	s1,~JAZZ_IE_MOUSE
+		li	a0,JAZZ_MOUSE_IRQ
+		b	loc_call
+
+/*
+ * Serial port 1 IRQ
+ */
+loc_serial1:	li	s1,~JAZZ_IE_SERIAL1
+		li	a0,JAZZ_SERIAL1_IRQ
+		b	loc_call
+
+/*
+ * Serial port 2 IRQ
+ */
+loc_serial2:	li	s1,~JAZZ_IE_SERIAL2
+		li	a0,JAZZ_SERIAL2_IRQ
+		b	loc_call
+
+/*
+ * Call the interrupt handler for an interrupt generated by a
+ * local device.
+ */
+loc_call:	/*
+		 * Temporarily disable interrupt source
+		 */
+		lhu	t2,JAZZ_IO_IRQ_ENABLE
+		and	t2,s1
+		sh	t2,JAZZ_IO_IRQ_ENABLE
+
+ 		nor	s1,zero,s1
+		jal	do_IRQ
+
+ 		/*
+ 		 * Reenable interrupt
+ 		 */
+		lhu	t2,JAZZ_IO_IRQ_ENABLE
+ 		or	t2,s1
+		sh	t2,JAZZ_IO_IRQ_ENABLE
+
+ 		j	ret_from_irq
+
+/*
+ * "Jump extender" to reach spurious_interrupt
+ */
+3:		j	spurious_interrupt
+
+/*
+ * Vectors for interrupts generated by local devices
+ */
+		.data
+local_vector:	PTR	loc_no_irq
+		PTR	loc_parallel
+		PTR	loc_floppy
+		PTR	loc_sound
+		PTR	loc_video
+		PTR	loc_ethernet
+		PTR	loc_scsi
+		PTR	loc_keyboard
+		PTR	loc_mouse
+		PTR	loc_serial1
+		PTR	loc_serial2
diff --git a/arch/mips/jazz/io.c b/arch/mips/jazz/io.c
new file mode 100644
index 0000000..e869044
--- /dev/null
+++ b/arch/mips/jazz/io.c
@@ -0,0 +1,135 @@
+/*
+ * 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.
+ *
+ * Low level I/O functions for Jazz family machines.
+ *
+ * Copyright (C) 1997 by Ralf Baechle.
+ */
+#include <linux/string.h>
+#include <linux/spinlock.h>
+#include <asm/addrspace.h>
+#include <asm/system.h>
+#include <asm/jazz.h>
+
+/*
+ * Map an 16mb segment of the EISA address space to 0xe3000000;
+ */
+static inline void map_eisa_address(unsigned long address)
+{
+  /* XXX */
+  /* We've got an wired entry in the TLB.  We just need to modify it.
+     fast and clean.  But since we want to get rid of wired entries
+     things are a little bit more complicated ... */
+}
+
+static unsigned char jazz_readb(unsigned long addr)
+{
+	unsigned char res;
+
+	map_eisa_address(addr);
+	addr &= 0xffffff;
+	res = *(volatile unsigned char *) (JAZZ_EISA_BASE + addr);
+
+	return res;
+}
+
+static unsigned short jazz_readw(unsigned long addr)
+{
+	unsigned short res;
+
+	map_eisa_address(addr);
+	addr &= 0xffffff;
+	res = *(volatile unsigned char *) (JAZZ_EISA_BASE + addr);
+
+	return res;
+}
+
+static unsigned int jazz_readl(unsigned long addr)
+{
+	unsigned int res;
+
+	map_eisa_address(addr);
+	addr &= 0xffffff;
+	res = *(volatile unsigned char *) (JAZZ_EISA_BASE + addr);
+
+	return res;
+}
+
+static void jazz_writeb(unsigned char val, unsigned long addr)
+{
+	map_eisa_address(addr);
+	addr &= 0xffffff;
+	*(volatile unsigned char *) (JAZZ_EISA_BASE + addr) = val;
+}
+
+static void jazz_writew(unsigned short val, unsigned long addr)
+{
+	map_eisa_address(addr);
+	addr &= 0xffffff;
+	*(volatile unsigned char *) (JAZZ_EISA_BASE + addr) = val;
+}
+
+static void jazz_writel(unsigned int val, unsigned long addr)
+{
+	map_eisa_address(addr);
+	addr &= 0xffffff;
+	*(volatile unsigned char *) (JAZZ_EISA_BASE + addr) = val;
+}
+
+static void jazz_memset_io(unsigned long addr, int val, unsigned long len)
+{
+	unsigned long waddr;
+
+	waddr = JAZZ_EISA_BASE | (addr & 0xffffff);
+	while(len) {
+		unsigned long fraglen;
+
+		fraglen = (~addr + 1) & 0xffffff;
+		fraglen = (fraglen < len) ? fraglen : len;
+		map_eisa_address(addr);
+		memset((char *)waddr, val, fraglen);
+		addr += fraglen;
+		waddr = waddr + fraglen - 0x1000000;
+		len -= fraglen;
+	}
+}
+
+static void jazz_memcpy_fromio(unsigned long to, unsigned long from, unsigned long len)
+{
+	unsigned long waddr;
+
+	waddr = JAZZ_EISA_BASE | (from & 0xffffff);
+	while(len) {
+		unsigned long fraglen;
+
+		fraglen = (~from + 1) & 0xffffff;
+		fraglen = (fraglen < len) ? fraglen : len;
+		map_eisa_address(from);
+		memcpy((void *)to, (void *)waddr, fraglen);
+		to += fraglen;
+		from += fraglen;
+		waddr = waddr + fraglen - 0x1000000;
+		len -= fraglen;
+	}
+}
+
+static void jazz_memcpy_toio(unsigned long to, unsigned long from, unsigned long len)
+{
+	unsigned long waddr;
+
+	waddr = JAZZ_EISA_BASE | (to & 0xffffff);
+	while(len) {
+		unsigned long fraglen;
+
+		fraglen = (~to + 1) & 0xffffff;
+		fraglen = (fraglen < len) ? fraglen : len;
+		map_eisa_address(to);
+		memcpy((char *)to + JAZZ_EISA_BASE, (void *)from, fraglen);
+		to += fraglen;
+		from += fraglen;
+		waddr = waddr + fraglen - 0x1000000;
+		len -= fraglen;
+	}
+}
diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c
new file mode 100644
index 0000000..0b608fa
--- /dev/null
+++ b/arch/mips/jazz/irq.c
@@ -0,0 +1,100 @@
+/*
+ * 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) 1992 Linus Torvalds
+ * Copyright (C) 1994 - 2001, 2003 Ralf Baechle
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+
+#include <asm/i8259.h>
+#include <asm/io.h>
+#include <asm/jazz.h>
+
+extern asmlinkage void jazz_handle_int(void);
+
+static DEFINE_SPINLOCK(r4030_lock);
+
+static void enable_r4030_irq(unsigned int irq)
+{
+	unsigned int mask = 1 << (irq - JAZZ_PARALLEL_IRQ);
+	unsigned long flags;
+
+	spin_lock_irqsave(&r4030_lock, flags);
+	mask |= r4030_read_reg16(JAZZ_IO_IRQ_ENABLE);
+	r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, mask);
+	spin_unlock_irqrestore(&r4030_lock, flags);
+}
+
+static unsigned int startup_r4030_irq(unsigned int irq)
+{
+	enable_r4030_irq(irq);
+	return 0; /* never anything pending */
+}
+
+#define shutdown_r4030_irq	disable_r4030_irq
+
+void disable_r4030_irq(unsigned int irq)
+{
+	unsigned int mask = ~(1 << (irq - JAZZ_PARALLEL_IRQ));
+	unsigned long flags;
+
+	spin_lock_irqsave(&r4030_lock, flags);
+	mask &= r4030_read_reg16(JAZZ_IO_IRQ_ENABLE);
+	r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, mask);
+	spin_unlock_irqrestore(&r4030_lock, flags);
+}
+
+#define mask_and_ack_r4030_irq disable_r4030_irq
+
+static void end_r4030_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_r4030_irq(irq);
+}
+
+static struct hw_interrupt_type r4030_irq_type = {
+	"R4030",
+	startup_r4030_irq,
+	shutdown_r4030_irq,
+	enable_r4030_irq,
+	disable_r4030_irq,
+	mask_and_ack_r4030_irq,
+	end_r4030_irq,
+	NULL
+};
+
+void __init init_r4030_ints(void)
+{
+	int i;
+
+	for (i = JAZZ_PARALLEL_IRQ; i <= JAZZ_TIMER_IRQ; i++) {
+		irq_desc[i].status     = IRQ_DISABLED;
+		irq_desc[i].action     = 0;
+		irq_desc[i].depth      = 1;
+		irq_desc[i].handler    = &r4030_irq_type;
+	}
+
+	r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, 0);
+	r4030_read_reg16(JAZZ_IO_IRQ_SOURCE);		/* clear pending IRQs */
+	r4030_read_reg32(JAZZ_R4030_INVAL_ADDR);	/* clear error bits */
+}
+
+/*
+ * On systems with i8259-style interrupt controllers we assume for
+ * driver compatibility reasons interrupts 0 - 15 to be the i8259
+ * interrupts even if the hardware uses a different interrupt numbering.
+ */
+void __init arch_init_irq(void)
+{
+	set_except_vector(0, jazz_handle_int);
+
+	init_i8259_irqs();			/* Integrated i8259  */
+	init_r4030_ints();
+
+	change_c0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1);
+}
diff --git a/arch/mips/jazz/jazzdma.c b/arch/mips/jazz/jazzdma.c
new file mode 100644
index 0000000..46e421e
--- /dev/null
+++ b/arch/mips/jazz/jazzdma.c
@@ -0,0 +1,565 @@
+/*
+ * Mips Jazz DMA controller support
+ * Copyright (C) 1995, 1996 by Andreas Busse
+ *
+ * NOTE: Some of the argument checking could be removed when
+ * things have settled down. Also, instead of returning 0xffffffff
+ * on failure of vdma_alloc() one could leave page #0 unused
+ * and return the more usual NULL pointer as logical address.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/spinlock.h>
+#include <asm/mipsregs.h>
+#include <asm/jazz.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/dma.h>
+#include <asm/jazzdma.h>
+#include <asm/pgtable.h>
+
+/*
+ * Set this to one to enable additional vdma debug code.
+ */
+#define CONF_DEBUG_VDMA 0
+
+static unsigned long vdma_pagetable_start;
+
+static DEFINE_SPINLOCK(vdma_lock);
+
+/*
+ * Debug stuff
+ */
+#define vdma_debug     ((CONF_DEBUG_VDMA) ? debuglvl : 0)
+
+static int debuglvl = 3;
+
+/*
+ * Initialize the pagetable with a one-to-one mapping of
+ * the first 16 Mbytes of main memory and declare all
+ * entries to be unused. Using this method will at least
+ * allow some early device driver operations to work.
+ */
+static inline void vdma_pgtbl_init(void)
+{
+	VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *) vdma_pagetable_start;
+	unsigned long paddr = 0;
+	int i;
+
+	for (i = 0; i < VDMA_PGTBL_ENTRIES; i++) {
+		pgtbl[i].frame = paddr;
+		pgtbl[i].owner = VDMA_PAGE_EMPTY;
+		paddr += VDMA_PAGESIZE;
+	}
+}
+
+/*
+ * Initialize the Jazz R4030 dma controller
+ */
+void __init vdma_init(void)
+{
+	/*
+	 * Allocate 32k of memory for DMA page tables.  This needs to be page
+	 * aligned and should be uncached to avoid cache flushing after every
+	 * update.
+	 */
+	vdma_pagetable_start = alloc_bootmem_low_pages(VDMA_PGTBL_SIZE);
+	if (!vdma_pagetable_start)
+		BUG();
+	dma_cache_wback_inv(vdma_pagetable_start, VDMA_PGTBL_SIZE);
+	vdma_pagetable_start = KSEG1ADDR(vdma_pagetable_start);
+
+	/*
+	 * Clear the R4030 translation table
+	 */
+	vdma_pgtbl_init();
+
+	r4030_write_reg32(JAZZ_R4030_TRSTBL_BASE,
+			  CPHYSADDR(vdma_pagetable_start));
+	r4030_write_reg32(JAZZ_R4030_TRSTBL_LIM, VDMA_PGTBL_SIZE);
+	r4030_write_reg32(JAZZ_R4030_TRSTBL_INV, 0);
+
+	printk("VDMA: R4030 DMA pagetables initialized.\n");
+}
+
+/*
+ * Allocate DMA pagetables using a simple first-fit algorithm
+ */
+unsigned long vdma_alloc(unsigned long paddr, unsigned long size)
+{
+	VDMA_PGTBL_ENTRY *entry = (VDMA_PGTBL_ENTRY *) vdma_pagetable_start;
+	int first, last, pages, frame, i;
+	unsigned long laddr, flags;
+
+	/* check arguments */
+
+	if (paddr > 0x1fffffff) {
+		if (vdma_debug)
+			printk("vdma_alloc: Invalid physical address: %08lx\n",
+			       paddr);
+		return VDMA_ERROR;	/* invalid physical address */
+	}
+	if (size > 0x400000 || size == 0) {
+		if (vdma_debug)
+			printk("vdma_alloc: Invalid size: %08lx\n", size);
+		return VDMA_ERROR;	/* invalid physical address */
+	}
+
+	spin_lock_irqsave(&vdma_lock, flags);
+	/*
+	 * Find free chunk
+	 */
+	pages = (size + 4095) >> 12;	/* no. of pages to allocate */
+	first = 0;
+	while (1) {
+		while (entry[first].owner != VDMA_PAGE_EMPTY &&
+		       first < VDMA_PGTBL_ENTRIES) first++;
+		if (first + pages > VDMA_PGTBL_ENTRIES) {	/* nothing free */
+			spin_unlock_irqrestore(&vdma_lock, flags);
+			return VDMA_ERROR;
+		}
+
+		last = first + 1;
+		while (entry[last].owner == VDMA_PAGE_EMPTY
+		       && last - first < pages)
+			last++;
+
+		if (last - first == pages)
+			break;	/* found */
+	}
+
+	/*
+	 * Mark pages as allocated
+	 */
+	laddr = (first << 12) + (paddr & (VDMA_PAGESIZE - 1));
+	frame = paddr & ~(VDMA_PAGESIZE - 1);
+
+	for (i = first; i < last; i++) {
+		entry[i].frame = frame;
+		entry[i].owner = laddr;
+		frame += VDMA_PAGESIZE;
+	}
+
+	/*
+	 * Update translation table and return logical start address
+	 */
+	r4030_write_reg32(JAZZ_R4030_TRSTBL_INV, 0);
+
+	if (vdma_debug > 1)
+		printk("vdma_alloc: Allocated %d pages starting from %08lx\n",
+		     pages, laddr);
+
+	if (vdma_debug > 2) {
+		printk("LADDR: ");
+		for (i = first; i < last; i++)
+			printk("%08x ", i << 12);
+		printk("\nPADDR: ");
+		for (i = first; i < last; i++)
+			printk("%08x ", entry[i].frame);
+		printk("\nOWNER: ");
+		for (i = first; i < last; i++)
+			printk("%08x ", entry[i].owner);
+		printk("\n");
+	}
+
+	spin_unlock_irqrestore(&vdma_lock, flags);
+
+	return laddr;
+}
+
+EXPORT_SYMBOL(vdma_alloc);
+
+/*
+ * Free previously allocated dma translation pages
+ * Note that this does NOT change the translation table,
+ * it just marks the free'd pages as unused!
+ */
+int vdma_free(unsigned long laddr)
+{
+	VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *) vdma_pagetable_start;
+	int i;
+
+	i = laddr >> 12;
+
+	if (pgtbl[i].owner != laddr) {
+		printk
+		    ("vdma_free: trying to free other's dma pages, laddr=%8lx\n",
+		     laddr);
+		return -1;
+	}
+
+	while (pgtbl[i].owner == laddr && i < VDMA_PGTBL_ENTRIES) {
+		pgtbl[i].owner = VDMA_PAGE_EMPTY;
+		i++;
+	}
+
+	if (vdma_debug > 1)
+		printk("vdma_free: freed %ld pages starting from %08lx\n",
+		       i - (laddr >> 12), laddr);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(vdma_free);
+
+/*
+ * Map certain page(s) to another physical address.
+ * Caller must have allocated the page(s) before.
+ */
+int vdma_remap(unsigned long laddr, unsigned long paddr, unsigned long size)
+{
+	VDMA_PGTBL_ENTRY *pgtbl =
+	    (VDMA_PGTBL_ENTRY *) vdma_pagetable_start;
+	int first, pages, npages;
+
+	if (laddr > 0xffffff) {
+		if (vdma_debug)
+			printk
+			    ("vdma_map: Invalid logical address: %08lx\n",
+			     laddr);
+		return -EINVAL;	/* invalid logical address */
+	}
+	if (paddr > 0x1fffffff) {
+		if (vdma_debug)
+			printk
+			    ("vdma_map: Invalid physical address: %08lx\n",
+			     paddr);
+		return -EINVAL;	/* invalid physical address */
+	}
+
+	npages = pages =
+	    (((paddr & (VDMA_PAGESIZE - 1)) + size) >> 12) + 1;
+	first = laddr >> 12;
+	if (vdma_debug)
+		printk("vdma_remap: first=%x, pages=%x\n", first, pages);
+	if (first + pages > VDMA_PGTBL_ENTRIES) {
+		if (vdma_debug)
+			printk("vdma_alloc: Invalid size: %08lx\n", size);
+		return -EINVAL;
+	}
+
+	paddr &= ~(VDMA_PAGESIZE - 1);
+	while (pages > 0 && first < VDMA_PGTBL_ENTRIES) {
+		if (pgtbl[first].owner != laddr) {
+			if (vdma_debug)
+				printk("Trying to remap other's pages.\n");
+			return -EPERM;	/* not owner */
+		}
+		pgtbl[first].frame = paddr;
+		paddr += VDMA_PAGESIZE;
+		first++;
+		pages--;
+	}
+
+	/*
+	 * Update translation table
+	 */
+	r4030_write_reg32(JAZZ_R4030_TRSTBL_INV, 0);
+
+	if (vdma_debug > 2) {
+		int i;
+		pages = (((paddr & (VDMA_PAGESIZE - 1)) + size) >> 12) + 1;
+		first = laddr >> 12;
+		printk("LADDR: ");
+		for (i = first; i < first + pages; i++)
+			printk("%08x ", i << 12);
+		printk("\nPADDR: ");
+		for (i = first; i < first + pages; i++)
+			printk("%08x ", pgtbl[i].frame);
+		printk("\nOWNER: ");
+		for (i = first; i < first + pages; i++)
+			printk("%08x ", pgtbl[i].owner);
+		printk("\n");
+	}
+
+	return 0;
+}
+
+/*
+ * Translate a physical address to a logical address.
+ * This will return the logical address of the first
+ * match.
+ */
+unsigned long vdma_phys2log(unsigned long paddr)
+{
+	int i;
+	int frame;
+	VDMA_PGTBL_ENTRY *pgtbl =
+	    (VDMA_PGTBL_ENTRY *) vdma_pagetable_start;
+
+	frame = paddr & ~(VDMA_PAGESIZE - 1);
+
+	for (i = 0; i < VDMA_PGTBL_ENTRIES; i++) {
+		if (pgtbl[i].frame == frame)
+			break;
+	}
+
+	if (i == VDMA_PGTBL_ENTRIES)
+		return ~0UL;
+
+	return (i << 12) + (paddr & (VDMA_PAGESIZE - 1));
+}
+
+EXPORT_SYMBOL(vdma_phys2log);
+
+/*
+ * Translate a logical DMA address to a physical address
+ */
+unsigned long vdma_log2phys(unsigned long laddr)
+{
+	VDMA_PGTBL_ENTRY *pgtbl =
+	    (VDMA_PGTBL_ENTRY *) vdma_pagetable_start;
+
+	return pgtbl[laddr >> 12].frame + (laddr & (VDMA_PAGESIZE - 1));
+}
+
+EXPORT_SYMBOL(vdma_log2phys);
+
+/*
+ * Print DMA statistics
+ */
+void vdma_stats(void)
+{
+	int i;
+
+	printk("vdma_stats: CONFIG: %08x\n",
+	       r4030_read_reg32(JAZZ_R4030_CONFIG));
+	printk("R4030 translation table base: %08x\n",
+	       r4030_read_reg32(JAZZ_R4030_TRSTBL_BASE));
+	printk("R4030 translation table limit: %08x\n",
+	       r4030_read_reg32(JAZZ_R4030_TRSTBL_LIM));
+	printk("vdma_stats: INV_ADDR: %08x\n",
+	       r4030_read_reg32(JAZZ_R4030_INV_ADDR));
+	printk("vdma_stats: R_FAIL_ADDR: %08x\n",
+	       r4030_read_reg32(JAZZ_R4030_R_FAIL_ADDR));
+	printk("vdma_stats: M_FAIL_ADDR: %08x\n",
+	       r4030_read_reg32(JAZZ_R4030_M_FAIL_ADDR));
+	printk("vdma_stats: IRQ_SOURCE: %08x\n",
+	       r4030_read_reg32(JAZZ_R4030_IRQ_SOURCE));
+	printk("vdma_stats: I386_ERROR: %08x\n",
+	       r4030_read_reg32(JAZZ_R4030_I386_ERROR));
+	printk("vdma_chnl_modes:   ");
+	for (i = 0; i < 8; i++)
+		printk("%04x ",
+		       (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_MODE +
+						   (i << 5)));
+	printk("\n");
+	printk("vdma_chnl_enables: ");
+	for (i = 0; i < 8; i++)
+		printk("%04x ",
+		       (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
+						   (i << 5)));
+	printk("\n");
+}
+
+/*
+ * DMA transfer functions
+ */
+
+/*
+ * Enable a DMA channel. Also clear any error conditions.
+ */
+void vdma_enable(int channel)
+{
+	int status;
+
+	if (vdma_debug)
+		printk("vdma_enable: channel %d\n", channel);
+
+	/*
+	 * Check error conditions first
+	 */
+	status = r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5));
+	if (status & 0x400)
+		printk("VDMA: Channel %d: Address error!\n", channel);
+	if (status & 0x200)
+		printk("VDMA: Channel %d: Memory error!\n", channel);
+
+	/*
+	 * Clear all interrupt flags
+	 */
+	r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5),
+			  r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
+					   (channel << 5)) | R4030_TC_INTR
+			  | R4030_MEM_INTR | R4030_ADDR_INTR);
+
+	/*
+	 * Enable the desired channel
+	 */
+	r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5),
+			  r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
+					   (channel << 5)) |
+			  R4030_CHNL_ENABLE);
+}
+
+EXPORT_SYMBOL(vdma_enable);
+
+/*
+ * Disable a DMA channel
+ */
+void vdma_disable(int channel)
+{
+	if (vdma_debug) {
+		int status =
+		    r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
+				     (channel << 5));
+
+		printk("vdma_disable: channel %d\n", channel);
+		printk("VDMA: channel %d status: %04x (%s) mode: "
+		       "%02x addr: %06x count: %06x\n",
+		       channel, status,
+		       ((status & 0x600) ? "ERROR" : "OK"),
+		       (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_MODE +
+						   (channel << 5)),
+		       (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_ADDR +
+						   (channel << 5)),
+		       (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_COUNT +
+						   (channel << 5)));
+	}
+
+	r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5),
+			  r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
+					   (channel << 5)) &
+			  ~R4030_CHNL_ENABLE);
+
+	/*
+	 * After disabling a DMA channel a remote bus register should be
+	 * read to ensure that the current DMA acknowledge cycle is completed.
+	 */
+	*((volatile unsigned int *) JAZZ_DUMMY_DEVICE);
+}
+
+EXPORT_SYMBOL(vdma_disable);
+
+/*
+ * Set DMA mode. This function accepts the mode values used
+ * to set a PC-style DMA controller. For the SCSI and FDC
+ * channels, we also set the default modes each time we're
+ * called.
+ * NOTE: The FAST and BURST dma modes are supported by the
+ * R4030 Rev. 2 and PICA chipsets only. I leave them disabled
+ * for now.
+ */
+void vdma_set_mode(int channel, int mode)
+{
+	if (vdma_debug)
+		printk("vdma_set_mode: channel %d, mode 0x%x\n", channel,
+		       mode);
+
+	switch (channel) {
+	case JAZZ_SCSI_DMA:	/* scsi */
+		r4030_write_reg32(JAZZ_R4030_CHNL_MODE + (channel << 5),
+/*			  R4030_MODE_FAST | */
+/*			  R4030_MODE_BURST | */
+				  R4030_MODE_INTR_EN |
+				  R4030_MODE_WIDTH_16 |
+				  R4030_MODE_ATIME_80);
+		break;
+
+	case JAZZ_FLOPPY_DMA:	/* floppy */
+		r4030_write_reg32(JAZZ_R4030_CHNL_MODE + (channel << 5),
+/*			  R4030_MODE_FAST | */
+/*			  R4030_MODE_BURST | */
+				  R4030_MODE_INTR_EN |
+				  R4030_MODE_WIDTH_8 |
+				  R4030_MODE_ATIME_120);
+		break;
+
+	case JAZZ_AUDIOL_DMA:
+	case JAZZ_AUDIOR_DMA:
+		printk("VDMA: Audio DMA not supported yet.\n");
+		break;
+
+	default:
+		printk
+		    ("VDMA: vdma_set_mode() called with unsupported channel %d!\n",
+		     channel);
+	}
+
+	switch (mode) {
+	case DMA_MODE_READ:
+		r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5),
+				  r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
+						   (channel << 5)) &
+				  ~R4030_CHNL_WRITE);
+		break;
+
+	case DMA_MODE_WRITE:
+		r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5),
+				  r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
+						   (channel << 5)) |
+				  R4030_CHNL_WRITE);
+		break;
+
+	default:
+		printk
+		    ("VDMA: vdma_set_mode() called with unknown dma mode 0x%x\n",
+		     mode);
+	}
+}
+
+EXPORT_SYMBOL(vdma_set_mode);
+
+/*
+ * Set Transfer Address
+ */
+void vdma_set_addr(int channel, long addr)
+{
+	if (vdma_debug)
+		printk("vdma_set_addr: channel %d, addr %lx\n", channel,
+		       addr);
+
+	r4030_write_reg32(JAZZ_R4030_CHNL_ADDR + (channel << 5), addr);
+}
+
+EXPORT_SYMBOL(vdma_set_addr);
+
+/*
+ * Set Transfer Count
+ */
+void vdma_set_count(int channel, int count)
+{
+	if (vdma_debug)
+		printk("vdma_set_count: channel %d, count %08x\n", channel,
+		       (unsigned) count);
+
+	r4030_write_reg32(JAZZ_R4030_CHNL_COUNT + (channel << 5), count);
+}
+
+EXPORT_SYMBOL(vdma_set_count);
+
+/*
+ * Get Residual
+ */
+int vdma_get_residue(int channel)
+{
+	int residual;
+
+	residual = r4030_read_reg32(JAZZ_R4030_CHNL_COUNT + (channel << 5));
+
+	if (vdma_debug)
+		printk("vdma_get_residual: channel %d: residual=%d\n",
+		       channel, residual);
+
+	return residual;
+}
+
+/*
+ * Get DMA channel enable register
+ */
+int vdma_get_enable(int channel)
+{
+	int enable;
+
+	enable = r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5));
+
+	if (vdma_debug)
+		printk("vdma_get_enable: channel %d: enable=%d\n", channel,
+		       enable);
+
+	return enable;
+}
diff --git a/arch/mips/jazz/reset.c b/arch/mips/jazz/reset.c
new file mode 100644
index 0000000..2a97547
--- /dev/null
+++ b/arch/mips/jazz/reset.c
@@ -0,0 +1,69 @@
+/*
+ * Reset a Jazz machine.
+ *
+ * We don't trust the firmware so we do it the classic way by poking and
+ * stabbing at the keyboard controller ...
+ */
+#include <linux/jiffies.h>
+#include <asm/jazz.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/reboot.h>
+#include <asm/delay.h>
+
+#define KBD_STAT_IBF		0x02	/* Keyboard input buffer full */
+
+static void jazz_write_output(unsigned char val)
+{
+	int status;
+
+	do {
+		status = jazz_kh->command;
+	} while (status & KBD_STAT_IBF);
+	jazz_kh->data = val;
+}
+
+static void jazz_write_command(unsigned char val)
+{
+	int status;
+
+	do {
+		status = jazz_kh->command;
+	} while (status & KBD_STAT_IBF);
+	jazz_kh->command = val;
+}
+
+static unsigned char jazz_read_status(void)
+{
+	return jazz_kh->command;
+}
+
+static inline void kb_wait(void)
+{
+	unsigned long start = jiffies;
+	unsigned long timeout = start + HZ/2;
+
+	do {
+		if (! (jazz_read_status() & 0x02))
+			return;
+	} while (time_before_eq(jiffies, timeout));
+}
+
+void jazz_machine_restart(char *command)
+{
+	while(1) {
+		kb_wait();
+		jazz_write_command (0xd1);
+		kb_wait();
+		jazz_write_output (0x00);
+	}
+}
+
+void jazz_machine_halt(void)
+{
+}
+
+void jazz_machine_power_off(void)
+{
+	/* Jazz machines don't have a software power switch */
+}
diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c
new file mode 100644
index 0000000..fccb06f
--- /dev/null
+++ b/arch/mips/jazz/setup.c
@@ -0,0 +1,101 @@
+/*
+ * Setup pointers to hardware-dependent routines.
+ *
+ * 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) 1996, 1997, 1998, 2001 by Ralf Baechle
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ */
+#include <linux/config.h>
+#include <linux/eisa.h>
+#include <linux/hdreg.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/fb.h>
+#include <linux/ide.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/jazz.h>
+#include <asm/jazzdma.h>
+#include <asm/ptrace.h>
+#include <asm/reboot.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/time.h>
+#include <asm/traps.h>
+
+extern asmlinkage void jazz_handle_int(void);
+
+extern void jazz_machine_restart(char *command);
+extern void jazz_machine_halt(void);
+extern void jazz_machine_power_off(void);
+
+static void __init jazz_time_init(struct irqaction *irq)
+{
+	/* set the clock to 100 Hz */
+	r4030_write_reg32(JAZZ_TIMER_INTERVAL, 9);
+	setup_irq(JAZZ_TIMER_IRQ, irq);
+}
+
+static struct resource jazz_io_resources[] = {
+	{ "dma1", 0x00, 0x1f, IORESOURCE_BUSY },
+	{ "timer", 0x40, 0x5f, IORESOURCE_BUSY },
+	{ "dma page reg", 0x80, 0x8f, IORESOURCE_BUSY },
+	{ "dma2", 0xc0, 0xdf, IORESOURCE_BUSY },
+};
+
+static void __init jazz_setup(void)
+{
+	int i;
+
+	/* Map 0xe0000000 -> 0x0:800005C0, 0xe0010000 -> 0x1:30000580 */
+	add_wired_entry (0x02000017, 0x03c00017, 0xe0000000, PM_64K);
+
+	/* Map 0xe2000000 -> 0x0:900005C0, 0xe3010000 -> 0x0:910005C0 */
+	add_wired_entry (0x02400017, 0x02440017, 0xe2000000, PM_16M);
+
+	/* Map 0xe4000000 -> 0x0:600005C0, 0xe4100000 -> 400005C0 */
+	add_wired_entry (0x01800017, 0x01000017, 0xe4000000, PM_4M);
+
+	set_io_port_base(JAZZ_PORT_BASE);
+#ifdef CONFIG_EISA
+	if (mips_machtype == MACH_MIPS_MAGNUM_4000)
+		EISA_bus = 1;
+#endif
+	isa_slot_offset = 0xe3000000;
+
+	/* request I/O space for devices used on all i[345]86 PCs */
+	for (i = 0; i < ARRAY_SIZE(jazz_io_resources); i++)
+		request_resource(&ioport_resource, jazz_io_resources + i);
+
+        board_timer_setup = jazz_time_init;
+	/* The RTC is outside the port address space */
+
+	_machine_restart = jazz_machine_restart;
+	_machine_halt = jazz_machine_halt;
+	_machine_power_off = jazz_machine_power_off;
+
+#warning "Somebody should check if screen_info is ok for Jazz."
+
+	screen_info = (struct screen_info) {
+		0, 0,		/* orig-x, orig-y */
+		0,		/* unused */
+		0,		/* orig_video_page */
+		0,		/* orig_video_mode */
+		160,		/* orig_video_cols */
+		0, 0, 0,	/* unused, ega_bx, unused */
+		64,		/* orig_video_lines */
+		0,		/* orig_video_isVGA */
+		16		/* orig_video_points */
+	};
+
+	vdma_init();
+}
+
+early_initcall(jazz_setup);
diff --git a/arch/mips/jmr3927/common/Makefile b/arch/mips/jmr3927/common/Makefile
new file mode 100644
index 0000000..cb09a8e
--- /dev/null
+++ b/arch/mips/jmr3927/common/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the common code of TOSHIBA JMR-TX3927 board
+#
+
+obj-y	 += prom.o puts.o rtc_ds1742.o
diff --git a/arch/mips/jmr3927/common/prom.c b/arch/mips/jmr3927/common/prom.c
new file mode 100644
index 0000000..5d5838f
--- /dev/null
+++ b/arch/mips/jmr3927/common/prom.c
@@ -0,0 +1,81 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *    PROM library initialisation code, assuming a version of
+ *    pmon is the boot code.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *              ahennessy@mvista.com
+ *
+ * Based on arch/mips/au1000/common/prom.c
+ *
+ * This file was derived from Carsten Langgaard's
+ * arch/mips/mips-boards/xx files.
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+
+extern int prom_argc;
+extern char **prom_argv, **prom_envp;
+
+typedef struct
+{
+    char *name;
+/*    char *val; */
+}t_env_var;
+
+
+char * __init prom_getcmdline(void)
+{
+	return &(arcs_cmdline[0]);
+}
+
+void  __init prom_init_cmdline(void)
+{
+	char *cp;
+	int actr;
+
+	actr = 1; /* Always ignore argv[0] */
+
+	cp = &(arcs_cmdline[0]);
+	while(actr < prom_argc) {
+	        strcpy(cp, prom_argv[actr]);
+		cp += strlen(prom_argv[actr]);
+		*cp++ = ' ';
+		actr++;
+	}
+	if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
+		--cp;
+	*cp = '\0';
+}
+
+unsigned long __init prom_free_prom_memory(void)
+{
+	return 0;
+}
diff --git a/arch/mips/jmr3927/common/puts.c b/arch/mips/jmr3927/common/puts.c
new file mode 100644
index 0000000..1c1cad9
--- /dev/null
+++ b/arch/mips/jmr3927/common/puts.c
@@ -0,0 +1,168 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Low level uart routines to directly access a TX[34]927 SIO.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ahennessy@mvista.com or source@mvista.com
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * Based on arch/mips/au1000/common/puts.c
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+#include <asm/jmr3927/txx927.h>
+#include <asm/jmr3927/tx3927.h>
+#include <asm/jmr3927/jmr3927.h>
+
+#define TIMEOUT       0xffffff
+#define SLOW_DOWN
+
+static const char digits[16] = "0123456789abcdef";
+
+#ifdef SLOW_DOWN
+#define slow_down() { int k; for (k=0; k<10000; k++); }
+#else
+#define slow_down()
+#endif
+
+void
+putch(const unsigned char c)
+{
+        int i = 0;
+
+        do {
+            slow_down();
+            i++;
+            if (i>TIMEOUT) {
+                break;
+            }
+        } while (!(tx3927_sioptr(1)->cisr & TXx927_SICISR_TXALS));
+	tx3927_sioptr(1)->tfifo = c;
+	return;
+}
+
+unsigned char getch(void)
+{
+        int i = 0;
+	int dicr;
+	char c;
+
+	/* diable RX int. */
+	dicr = tx3927_sioptr(1)->dicr;
+	tx3927_sioptr(1)->dicr = 0;
+
+        do {
+            slow_down();
+            i++;
+            if (i>TIMEOUT) {
+                break;
+            }
+        } while (tx3927_sioptr(1)->disr & TXx927_SIDISR_UVALID)
+		;
+	c = tx3927_sioptr(1)->rfifo;
+
+	/* clear RX int. status */
+	tx3927_sioptr(1)->disr &= ~TXx927_SIDISR_RDIS;
+	/* enable RX int. */
+	tx3927_sioptr(1)->dicr = dicr;
+
+	return c;
+}
+void
+do_jmr3927_led_set(char n)
+{
+    /* and with current leds */
+    jmr3927_led_and_set(n);
+}
+
+void
+puts(unsigned char *cp)
+{
+    int i = 0;
+
+    while (*cp) {
+        do {
+            slow_down();
+            i++;
+            if (i>TIMEOUT) {
+                break;
+            }
+        } while (!(tx3927_sioptr(1)->cisr & TXx927_SICISR_TXALS));
+	tx3927_sioptr(1)->tfifo = *cp++;
+    }
+    putch('\r');
+    putch('\n');
+}
+
+void
+fputs(unsigned char *cp)
+{
+    int i = 0;
+
+    while (*cp) {
+        do {
+             slow_down();
+            i++;
+            if (i>TIMEOUT) {
+                break;
+            }
+        } while (!(tx3927_sioptr(1)->cisr & TXx927_SICISR_TXALS));
+	tx3927_sioptr(1)->tfifo = *cp++;
+    }
+}
+
+
+void
+put64(uint64_t ul)
+{
+    int cnt;
+    unsigned ch;
+
+    cnt = 16;            /* 16 nibbles in a 64 bit long */
+    putch('0');
+    putch('x');
+    do {
+        cnt--;
+        ch = (unsigned char)(ul >> cnt * 4) & 0x0F;
+                putch(digits[ch]);
+    } while (cnt > 0);
+}
+
+void
+put32(unsigned u)
+{
+    int cnt;
+    unsigned ch;
+
+    cnt = 8;            /* 8 nibbles in a 32 bit long */
+    putch('0');
+    putch('x');
+    do {
+        cnt--;
+        ch = (unsigned char)(u >> cnt * 4) & 0x0F;
+                putch(digits[ch]);
+    } while (cnt > 0);
+}
diff --git a/arch/mips/jmr3927/common/rtc_ds1742.c b/arch/mips/jmr3927/common/rtc_ds1742.c
new file mode 100644
index 0000000..1ae4318
--- /dev/null
+++ b/arch/mips/jmr3927/common/rtc_ds1742.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *              ahennessy@mvista.com
+ *
+ * arch/mips/jmr3927/common/rtc_ds1742.c
+ * Based on arch/mips/ddb5xxx/common/rtc_ds1386.c
+ *     low-level RTC hookups for s for Dallas 1742 chip.
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * This file exports a function, rtc_ds1386_init(), which expects an
+ * uncached base address as the argument.  It will set the two function
+ * pointers expected by the MIPS generic timer code.
+ */
+
+#include <linux/bcd.h>
+#include <linux/types.h>
+#include <linux/time.h>
+#include <linux/rtc.h>
+
+#include <asm/time.h>
+#include <asm/addrspace.h>
+
+#include <asm/jmr3927/ds1742rtc.h>
+#include <asm/debug.h>
+
+#define	EPOCH		2000
+
+static unsigned long rtc_base;
+
+static unsigned long
+rtc_ds1742_get_time(void)
+{
+	unsigned int year, month, day, hour, minute, second;
+	unsigned int century;
+
+	CMOS_WRITE(RTC_READ, RTC_CONTROL);
+	second = BCD2BIN(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK);
+	minute = BCD2BIN(CMOS_READ(RTC_MINUTES));
+	hour = BCD2BIN(CMOS_READ(RTC_HOURS));
+	day = BCD2BIN(CMOS_READ(RTC_DATE));
+	month = BCD2BIN(CMOS_READ(RTC_MONTH));
+	year = BCD2BIN(CMOS_READ(RTC_YEAR));
+	century = BCD2BIN(CMOS_READ(RTC_CENTURY) & RTC_CENTURY_MASK);
+	CMOS_WRITE(0, RTC_CONTROL);
+
+	year += century * 100;
+
+	return mktime(year, month, day, hour, minute, second);
+}
+extern void to_tm(unsigned long tim, struct rtc_time * tm);
+
+static int
+rtc_ds1742_set_time(unsigned long t)
+{
+	struct rtc_time tm;
+	u8 year, month, day, hour, minute, second;
+	u8 cmos_year, cmos_month, cmos_day, cmos_hour, cmos_minute, cmos_second;
+	int cmos_century;
+
+	CMOS_WRITE(RTC_READ, RTC_CONTROL);
+	cmos_second = (u8)(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK);
+	cmos_minute = (u8)CMOS_READ(RTC_MINUTES);
+	cmos_hour = (u8)CMOS_READ(RTC_HOURS);
+	cmos_day = (u8)CMOS_READ(RTC_DATE);
+	cmos_month = (u8)CMOS_READ(RTC_MONTH);
+	cmos_year = (u8)CMOS_READ(RTC_YEAR);
+	cmos_century = CMOS_READ(RTC_CENTURY) & RTC_CENTURY_MASK;
+
+	CMOS_WRITE(RTC_WRITE, RTC_CONTROL);
+
+	/* convert */
+	to_tm(t, &tm);
+
+	/* check each field one by one */
+	year = BIN2BCD(tm.tm_year - EPOCH);
+	if (year != cmos_year) {
+		CMOS_WRITE(year,RTC_YEAR);
+	}
+
+	month = BIN2BCD(tm.tm_mon);
+	if (month != (cmos_month & 0x1f)) {
+		CMOS_WRITE((month & 0x1f) | (cmos_month & ~0x1f),RTC_MONTH);
+	}
+
+	day = BIN2BCD(tm.tm_mday);
+	if (day != cmos_day) {
+
+		CMOS_WRITE(day, RTC_DATE);
+	}
+
+	if (cmos_hour & 0x40) {
+		/* 12 hour format */
+		hour = 0x40;
+		if (tm.tm_hour > 12) {
+			hour |= 0x20 | (BIN2BCD(hour-12) & 0x1f);
+		} else {
+			hour |= BIN2BCD(tm.tm_hour);
+		}
+	} else {
+		/* 24 hour format */
+		hour = BIN2BCD(tm.tm_hour) & 0x3f;
+	}
+	if (hour != cmos_hour) CMOS_WRITE(hour, RTC_HOURS);
+
+	minute = BIN2BCD(tm.tm_min);
+	if (minute !=  cmos_minute) {
+		CMOS_WRITE(minute, RTC_MINUTES);
+	}
+
+	second = BIN2BCD(tm.tm_sec);
+	if (second !=  cmos_second) {
+		CMOS_WRITE(second & RTC_SECONDS_MASK,RTC_SECONDS);
+	}
+
+	/* RTC_CENTURY and RTC_CONTROL share same address... */
+	CMOS_WRITE(cmos_century, RTC_CONTROL);
+
+	return 0;
+}
+
+void
+rtc_ds1742_init(unsigned long base)
+{
+	u8  cmos_second;
+
+	/* remember the base */
+	rtc_base = base;
+	db_assert((rtc_base & 0xe0000000) == KSEG1);
+
+	/* set the function pointers */
+	rtc_get_time = rtc_ds1742_get_time;
+	rtc_set_time = rtc_ds1742_set_time;
+
+	/* clear oscillator stop bit */
+	CMOS_WRITE(RTC_READ, RTC_CONTROL);
+	cmos_second = (u8)(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK);
+	CMOS_WRITE(RTC_WRITE, RTC_CONTROL);
+	CMOS_WRITE(cmos_second, RTC_SECONDS); /* clear msb */
+	CMOS_WRITE(0, RTC_CONTROL);
+}
diff --git a/arch/mips/jmr3927/rbhma3100/Makefile b/arch/mips/jmr3927/rbhma3100/Makefile
new file mode 100644
index 0000000..75bf418
--- /dev/null
+++ b/arch/mips/jmr3927/rbhma3100/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for TOSHIBA JMR-TX3927 board
+#
+
+obj-y	 			+= init.o int-handler.o irq.o setup.o
+obj-$(CONFIG_RUNTIME_DEBUG) 	+= debug.o
+obj-$(CONFIG_KGDB)		+= kgdb_io.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/jmr3927/rbhma3100/init.c b/arch/mips/jmr3927/rbhma3100/init.c
new file mode 100644
index 0000000..a0674d7
--- /dev/null
+++ b/arch/mips/jmr3927/rbhma3100/init.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *              ahennessy@mvista.com
+ *
+ * arch/mips/jmr3927/common/init.c
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
+#include <asm/jmr3927/jmr3927.h>
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+extern void  __init prom_init_cmdline(void);
+extern char *prom_getenv(char *envname);
+unsigned long mips_nofpu = 0;
+
+const char *get_system_type(void)
+{
+	return "Toshiba"
+#ifdef CONFIG_TOSHIBA_JMR3927
+	       " JMR_TX3927"
+#endif
+	;
+}
+
+extern void puts(unsigned char *cp);
+
+void __init prom_init(void)
+{
+#ifdef CONFIG_TOSHIBA_JMR3927
+	/* CCFG */
+	if ((tx3927_ccfgptr->ccfg & TX3927_CCFG_TLBOFF) == 0)
+		puts("Warning: TX3927 TLB off\n");
+#endif
+	prom_argc = fw_arg0;
+	prom_argv = (char **) fw_arg1;
+	prom_envp = (char **) fw_arg2;
+
+	mips_machgroup = MACH_GROUP_TOSHIBA;
+
+#ifdef CONFIG_TOSHIBA_JMR3927
+	mips_machtype = MACH_TOSHIBA_JMR3927;
+#endif
+
+	prom_init_cmdline();
+	add_memory_region(0, JMR3927_SDRAM_SIZE, BOOT_MEM_RAM);
+}
diff --git a/arch/mips/jmr3927/rbhma3100/int-handler.S b/arch/mips/jmr3927/rbhma3100/int-handler.S
new file mode 100644
index 0000000..f85bbf4
--- /dev/null
+++ b/arch/mips/jmr3927/rbhma3100/int-handler.S
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *              ahennessy@mvista.com
+ *
+ * Based on arch/mips/tsdb/kernel/int-handler.S
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/jmr3927/jmr3927.h>
+
+	/* A lot of complication here is taken away because:
+	 *
+	 * 1) We handle one interrupt and return, sitting in a loop
+	 *    and moving across all the pending IRQ bits in the cause
+	 *    register is _NOT_ the answer, the common case is one
+	 *    pending IRQ so optimize in that direction.
+	 *
+	 * 2) We need not check against bits in the status register
+	 *    IRQ mask, that would make this routine slow as hell.
+	 *
+	 * 3) Linux only thinks in terms of all IRQs on or all IRQs
+	 *    off, nothing in between like BSD spl() brain-damage.
+	 *
+	 */
+
+/* Flush write buffer (needed?)
+ * NOTE: TX39xx performs "non-blocking load", so explicitly use the target
+ * register of LBU to flush immediately.
+ */
+#define FLUSH_WB(tmp)	\
+	la	tmp, JMR3927_IOC_REV_ADDR; \
+	lbu	tmp, (tmp); \
+	move	tmp, zero;
+
+	.text
+	.set	noreorder
+	.set	noat
+	.align	5
+	NESTED(jmr3927_IRQ, PT_SIZE, sp)
+	SAVE_ALL
+	CLI
+	.set	at
+	jal	jmr3927_irc_irqdispatch
+	 move	a0, sp
+	FLUSH_WB(t0)
+	j	ret_from_irq
+	 nop
+	END(jmr3927_IRQ)
diff --git a/arch/mips/jmr3927/rbhma3100/irq.c b/arch/mips/jmr3927/rbhma3100/irq.c
new file mode 100644
index 0000000..b9799b8
--- /dev/null
+++ b/arch/mips/jmr3927/rbhma3100/irq.c
@@ -0,0 +1,466 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *              ahennessy@mvista.com
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <linux/errno.h>
+#include <linux/irq.h>
+#include <linux/kernel_stat.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/bitops.h>
+
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+#include <asm/ptrace.h>
+#include <asm/processor.h>
+#include <asm/jmr3927/irq.h>
+#include <asm/debug.h>
+#include <asm/jmr3927/jmr3927.h>
+
+#if JMR3927_IRQ_END > NR_IRQS
+#error JMR3927_IRQ_END > NR_IRQS
+#endif
+
+struct tb_irq_space* tb_irq_spaces;
+
+static int jmr3927_irq_base = -1;
+
+#ifdef CONFIG_PCI
+static int jmr3927_gen_iack(void)
+{
+	/* generate ACK cycle */
+#ifdef __BIG_ENDIAN
+	return (tx3927_pcicptr->iiadp >> 24) & 0xff;
+#else
+	return tx3927_pcicptr->iiadp & 0xff;
+#endif
+}
+#endif
+
+extern asmlinkage void jmr3927_IRQ(void);
+
+#define irc_dlevel	0
+#define irc_elevel	1
+
+static unsigned char irc_level[TX3927_NUM_IR] = {
+	5, 5, 5, 5, 5, 5,	/* INT[5:0] */
+	7, 7,			/* SIO */
+	5, 5, 5, 0, 0,		/* DMA, PIO, PCI */
+	6, 6, 6			/* TMR */
+};
+
+static void jmr3927_irq_disable(unsigned int irq_nr);
+static void jmr3927_irq_enable(unsigned int irq_nr);
+
+static DEFINE_SPINLOCK(jmr3927_irq_lock);
+
+static unsigned int jmr3927_irq_startup(unsigned int irq)
+{
+	jmr3927_irq_enable(irq);
+
+	return 0;
+}
+
+#define	jmr3927_irq_shutdown	jmr3927_irq_disable
+
+static void jmr3927_irq_ack(unsigned int irq)
+{
+	if (irq == JMR3927_IRQ_IRC_TMR0)
+		jmr3927_tmrptr->tisr = 0;       /* ack interrupt */
+
+	jmr3927_irq_disable(irq);
+}
+
+static void jmr3927_irq_end(unsigned int irq)
+{
+	jmr3927_irq_enable(irq);
+}
+
+static void jmr3927_irq_disable(unsigned int irq_nr)
+{
+	struct tb_irq_space* sp;
+	unsigned long flags;
+
+	spinlock_irqsave(&jmr3927_irq_lock, flags);
+	for (sp = tb_irq_spaces; sp; sp = sp->next) {
+		if (sp->start_irqno <= irq_nr &&
+		    irq_nr < sp->start_irqno + sp->nr_irqs) {
+			if (sp->mask_func)
+				sp->mask_func(irq_nr - sp->start_irqno,
+					      sp->space_id);
+			break;
+		}
+	}
+	spinlock_irqrestore(&jmr3927_irq_lock, flags);
+}
+
+static void jmr3927_irq_enable(unsigned int irq_nr)
+{
+	struct tb_irq_space* sp;
+	unsigned long flags;
+
+	spinlock_irqsave(&jmr3927_irq_lock, flags);
+	for (sp = tb_irq_spaces; sp; sp = sp->next) {
+		if (sp->start_irqno <= irq_nr &&
+		    irq_nr < sp->start_irqno + sp->nr_irqs) {
+			if (sp->unmask_func)
+				sp->unmask_func(irq_nr - sp->start_irqno,
+						sp->space_id);
+			break;
+		}
+	}
+	spinlock_irqrestore(&jmr3927_irq_lock, flags);
+}
+
+/*
+ * CP0_STATUS is a thread's resource (saved/restored on context switch).
+ * So disable_irq/enable_irq MUST handle IOC/ISAC/IRC registers.
+ */
+static void mask_irq_isac(int irq_nr, int space_id)
+{
+	/* 0: mask */
+	unsigned char imask =
+		jmr3927_isac_reg_in(JMR3927_ISAC_INTM_ADDR);
+	unsigned int bit  = 1 << irq_nr;
+	jmr3927_isac_reg_out(imask & ~bit, JMR3927_ISAC_INTM_ADDR);
+	/* flush write buffer */
+	(void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR);
+}
+static void unmask_irq_isac(int irq_nr, int space_id)
+{
+	/* 0: mask */
+	unsigned char imask = jmr3927_isac_reg_in(JMR3927_ISAC_INTM_ADDR);
+	unsigned int bit  = 1 << irq_nr;
+	jmr3927_isac_reg_out(imask | bit, JMR3927_ISAC_INTM_ADDR);
+	/* flush write buffer */
+	(void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR);
+}
+
+static void mask_irq_ioc(int irq_nr, int space_id)
+{
+	/* 0: mask */
+	unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR);
+	unsigned int bit = 1 << irq_nr;
+	jmr3927_ioc_reg_out(imask & ~bit, JMR3927_IOC_INTM_ADDR);
+	/* flush write buffer */
+	(void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR);
+}
+static void unmask_irq_ioc(int irq_nr, int space_id)
+{
+	/* 0: mask */
+	unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR);
+	unsigned int bit = 1 << irq_nr;
+	jmr3927_ioc_reg_out(imask | bit, JMR3927_IOC_INTM_ADDR);
+	/* flush write buffer */
+	(void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR);
+}
+
+static void mask_irq_irc(int irq_nr, int space_id)
+{
+	volatile unsigned long *ilrp = &tx3927_ircptr->ilr[irq_nr / 2];
+	if (irq_nr & 1)
+		*ilrp = (*ilrp & 0x00ff) | (irc_dlevel << 8);
+	else
+		*ilrp = (*ilrp & 0xff00) | irc_dlevel;
+	/* update IRCSR */
+	tx3927_ircptr->imr = 0;
+	tx3927_ircptr->imr = irc_elevel;
+}
+static void unmask_irq_irc(int irq_nr, int space_id)
+{
+	volatile unsigned long *ilrp = &tx3927_ircptr->ilr[irq_nr / 2];
+	if (irq_nr & 1)
+		*ilrp = (*ilrp & 0x00ff) | (irc_level[irq_nr] << 8);
+	else
+		*ilrp = (*ilrp & 0xff00) | irc_level[irq_nr];
+	/* update IRCSR */
+	tx3927_ircptr->imr = 0;
+	tx3927_ircptr->imr = irc_elevel;
+}
+
+struct tb_irq_space jmr3927_isac_irqspace = {
+	.next = NULL,
+	.start_irqno = JMR3927_IRQ_ISAC,
+	nr_irqs : JMR3927_NR_IRQ_ISAC,
+	.mask_func = mask_irq_isac,
+	.unmask_func = unmask_irq_isac,
+	.name = "ISAC",
+	.space_id = 0,
+	can_share : 0
+};
+struct tb_irq_space jmr3927_ioc_irqspace = {
+	.next = NULL,
+	.start_irqno = JMR3927_IRQ_IOC,
+	nr_irqs : JMR3927_NR_IRQ_IOC,
+	.mask_func = mask_irq_ioc,
+	.unmask_func = unmask_irq_ioc,
+	.name = "IOC",
+	.space_id = 0,
+	can_share : 1
+};
+struct tb_irq_space jmr3927_irc_irqspace = {
+	.next = NULL,
+	.start_irqno = JMR3927_IRQ_IRC,
+	nr_irqs : JMR3927_NR_IRQ_IRC,
+	.mask_func = mask_irq_irc,
+	.unmask_func = unmask_irq_irc,
+	.name = "on-chip",
+	.space_id = 0,
+	can_share : 0
+};
+
+void jmr3927_spurious(struct pt_regs *regs)
+{
+#ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND
+	tx_branch_likely_bug_fixup(regs);
+#endif
+	printk(KERN_WARNING "spurious interrupt (cause 0x%lx, pc 0x%lx, ra 0x%lx).\n",
+	       regs->cp0_cause, regs->cp0_epc, regs->regs[31]);
+}
+
+void jmr3927_irc_irqdispatch(struct pt_regs *regs)
+{
+	int irq;
+
+#ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND
+	tx_branch_likely_bug_fixup(regs);
+#endif
+	if ((regs->cp0_cause & CAUSEF_IP7) == 0) {
+#if 0
+		jmr3927_spurious(regs);
+#endif
+		return;
+	}
+	irq = (regs->cp0_cause >> CAUSEB_IP2) & 0x0f;
+
+	do_IRQ(irq + JMR3927_IRQ_IRC, regs);
+}
+
+static void jmr3927_ioc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned char istat = jmr3927_ioc_reg_in(JMR3927_IOC_INTS2_ADDR);
+	int i;
+
+	for (i = 0; i < JMR3927_NR_IRQ_IOC; i++) {
+		if (istat & (1 << i)) {
+			irq = JMR3927_IRQ_IOC + i;
+			do_IRQ(irq, regs);
+		}
+	}
+}
+
+static struct irqaction ioc_action = {
+	jmr3927_ioc_interrupt, 0, CPU_MASK_NONE, "IOC", NULL, NULL,
+};
+
+static void jmr3927_isac_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned char istat = jmr3927_isac_reg_in(JMR3927_ISAC_INTS2_ADDR);
+	int i;
+
+	for (i = 0; i < JMR3927_NR_IRQ_ISAC; i++) {
+		if (istat & (1 << i)) {
+			irq = JMR3927_IRQ_ISAC + i;
+			do_IRQ(irq, regs);
+		}
+	}
+}
+
+static struct irqaction isac_action = {
+	jmr3927_isac_interrupt, 0, CPU_MASK_NONE, "ISAC", NULL, NULL,
+};
+
+
+static void jmr3927_isaerr_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+{
+	printk(KERN_WARNING "ISA error interrupt (irq 0x%x).\n", irq);
+}
+static struct irqaction isaerr_action = {
+	jmr3927_isaerr_interrupt, 0, CPU_MASK_NONE, "ISA error", NULL, NULL,
+};
+
+static void jmr3927_pcierr_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+{
+	printk(KERN_WARNING "PCI error interrupt (irq 0x%x).\n", irq);
+	printk(KERN_WARNING "pcistat:%02x, lbstat:%04lx\n",
+	       tx3927_pcicptr->pcistat, tx3927_pcicptr->lbstat);
+}
+static struct irqaction pcierr_action = {
+	jmr3927_pcierr_interrupt, 0, CPU_MASK_NONE, "PCI error", NULL, NULL,
+};
+
+int jmr3927_ether1_irq = 0;
+
+void jmr3927_irq_init(u32 irq_base);
+
+void __init arch_init_irq(void)
+{
+	/* look for io board's presence */
+	int have_isac = jmr3927_have_isac();
+
+	/* Now, interrupt control disabled, */
+	/* all IRC interrupts are masked, */
+	/* all IRC interrupt mode are Low Active. */
+
+	if (have_isac) {
+
+		/* ETHER1 (NE2000 compatible 10M-Ether) parameter setup */
+		/* temporary enable interrupt control */
+		tx3927_ircptr->cer = 1;
+		/* ETHER1 Int. Is High-Active. */
+		if (tx3927_ircptr->ssr & (1 << 0))
+			jmr3927_ether1_irq = JMR3927_IRQ_IRC_INT0;
+#if 0	/* INT3 may be asserted by ether0 (even after reboot...) */
+		else if (tx3927_ircptr->ssr & (1 << 3))
+			jmr3927_ether1_irq = JMR3927_IRQ_IRC_INT3;
+#endif
+		/* disable interrupt control */
+		tx3927_ircptr->cer = 0;
+
+		/* Ether1: High Active */
+		if (jmr3927_ether1_irq) {
+			int ether1_irc = jmr3927_ether1_irq - JMR3927_IRQ_IRC;
+			tx3927_ircptr->cr[ether1_irc / 8] |=
+				TX3927_IRCR_HIGH << ((ether1_irc % 8) * 2);
+		}
+	}
+
+	/* mask all IOC interrupts */
+	jmr3927_ioc_reg_out(0, JMR3927_IOC_INTM_ADDR);
+	/* setup IOC interrupt mode (SOFT:High Active, Others:Low Active) */
+	jmr3927_ioc_reg_out(JMR3927_IOC_INTF_SOFT, JMR3927_IOC_INTP_ADDR);
+
+	if (have_isac) {
+		/* mask all ISAC interrupts */
+		jmr3927_isac_reg_out(0, JMR3927_ISAC_INTM_ADDR);
+		/* setup ISAC interrupt mode (ISAIRQ3,ISAIRQ5:Low Active ???) */
+		jmr3927_isac_reg_out(JMR3927_ISAC_INTF_IRQ3|JMR3927_ISAC_INTF_IRQ5, JMR3927_ISAC_INTP_ADDR);
+	}
+
+	/* clear PCI Soft interrupts */
+	jmr3927_ioc_reg_out(0, JMR3927_IOC_INTS1_ADDR);
+	/* clear PCI Reset interrupts */
+	jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
+
+	/* enable interrupt control */
+	tx3927_ircptr->cer = TX3927_IRCER_ICE;
+	tx3927_ircptr->imr = irc_elevel;
+
+	jmr3927_irq_init(NR_ISA_IRQS);
+
+	set_except_vector(0, jmr3927_IRQ);
+
+	/* setup irq space */
+	add_tb_irq_space(&jmr3927_isac_irqspace);
+	add_tb_irq_space(&jmr3927_ioc_irqspace);
+	add_tb_irq_space(&jmr3927_irc_irqspace);
+
+	/* setup IOC interrupt 1 (PCI, MODEM) */
+	setup_irq(JMR3927_IRQ_IOCINT, &ioc_action);
+
+	if (have_isac) {
+		setup_irq(JMR3927_IRQ_ISACINT, &isac_action);
+		setup_irq(JMR3927_IRQ_ISAC_ISAER, &isaerr_action);
+	}
+
+#ifdef CONFIG_PCI
+	setup_irq(JMR3927_IRQ_IRC_PCI, &pcierr_action);
+#endif
+
+	/* enable all CPU interrupt bits. */
+	set_c0_status(ST0_IM);	/* IE bit is still 0. */
+}
+
+static hw_irq_controller jmr3927_irq_controller = {
+	"jmr3927_irq",
+	jmr3927_irq_startup,
+	jmr3927_irq_shutdown,
+	jmr3927_irq_enable,
+	jmr3927_irq_disable,
+	jmr3927_irq_ack,
+	jmr3927_irq_end,
+};
+
+void jmr3927_irq_init(u32 irq_base)
+{
+	u32 i;
+
+	for (i= irq_base; i< irq_base + JMR3927_NR_IRQ_IRC + JMR3927_NR_IRQ_IOC; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &jmr3927_irq_controller;
+	}
+
+	jmr3927_irq_base = irq_base;
+}
+
+#ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND
+static int tx_branch_likely_bug_count = 0;
+static int have_tx_branch_likely_bug = 0;
+void tx_branch_likely_bug_fixup(struct pt_regs *regs)
+{
+	/* TX39/49-BUG: Under this condition, the insn in delay slot
+           of the branch likely insn is executed (not nullified) even
+           the branch condition is false. */
+	if (!have_tx_branch_likely_bug)
+		return;
+	if ((regs->cp0_epc & 0xfff) == 0xffc &&
+	    KSEGX(regs->cp0_epc) != KSEG0 &&
+	    KSEGX(regs->cp0_epc) != KSEG1) {
+		unsigned int insn = *(unsigned int*)(regs->cp0_epc - 4);
+		/* beql,bnel,blezl,bgtzl */
+		/* bltzl,bgezl,blezall,bgezall */
+		/* bczfl, bcztl */
+		if ((insn & 0xf0000000) == 0x50000000 ||
+		    (insn & 0xfc0e0000) == 0x04020000 ||
+		    (insn & 0xf3fe0000) == 0x41020000) {
+			regs->cp0_epc -= 4;
+			tx_branch_likely_bug_count++;
+			printk(KERN_INFO
+			       "fix branch-likery bug in %s (insn %08x)\n",
+			       current->comm, insn);
+		}
+	}
+}
+#endif
diff --git a/arch/mips/jmr3927/rbhma3100/kgdb_io.c b/arch/mips/jmr3927/rbhma3100/kgdb_io.c
new file mode 100644
index 0000000..269a42d
--- /dev/null
+++ b/arch/mips/jmr3927/rbhma3100/kgdb_io.c
@@ -0,0 +1,155 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Low level uart routines to directly access a TX[34]927 SIO.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ahennessy@mvista.com or source@mvista.com
+ *
+ * Based on arch/mips/ddb5xxx/ddb5477/kgdb_io.c
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+#include <asm/jmr3927/txx927.h>
+#include <asm/jmr3927/tx3927.h>
+#include <asm/jmr3927/jmr3927.h>
+
+#define TIMEOUT       0xffffff
+#define SLOW_DOWN
+
+static const char digits[16] = "0123456789abcdef";
+
+#ifdef SLOW_DOWN
+#define slow_down() { int k; for (k=0; k<10000; k++); }
+#else
+#define slow_down()
+#endif
+
+static int remoteDebugInitialized = 0;
+
+int putDebugChar(unsigned char c)
+{
+        int i = 0;
+
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(38400);
+	}
+
+        do {
+            slow_down();
+            i++;
+            if (i>TIMEOUT) {
+                break;
+            }
+        } while (!(tx3927_sioptr(0)->cisr & TXx927_SICISR_TXALS));
+	tx3927_sioptr(0)->tfifo = c;
+
+	return 1;
+}
+
+unsigned char getDebugChar(void)
+{
+        int i = 0;
+	int dicr;
+	char c;
+
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(38400);
+	}
+
+	/* diable RX int. */
+	dicr = tx3927_sioptr(0)->dicr;
+	tx3927_sioptr(0)->dicr = 0;
+
+        do {
+            slow_down();
+            i++;
+            if (i>TIMEOUT) {
+                break;
+            }
+        } while (tx3927_sioptr(0)->disr & TXx927_SIDISR_UVALID)
+		;
+	c = tx3927_sioptr(0)->rfifo;
+
+	/* clear RX int. status */
+	tx3927_sioptr(0)->disr &= ~TXx927_SIDISR_RDIS;
+	/* enable RX int. */
+	tx3927_sioptr(0)->dicr = dicr;
+
+	return c;
+}
+
+void debugInit(int baud)
+{
+	/*
+	volatile unsigned long lcr;
+	volatile unsigned long dicr;
+	volatile unsigned long disr;
+	volatile unsigned long cisr;
+	volatile unsigned long fcr;
+	volatile unsigned long flcr;
+	volatile unsigned long bgr;
+	volatile unsigned long tfifo;
+	volatile unsigned long rfifo;
+	*/
+
+	tx3927_sioptr(0)->lcr = 0x020;
+	tx3927_sioptr(0)->dicr = 0;
+	tx3927_sioptr(0)->disr = 0x4100;
+	tx3927_sioptr(0)->cisr = 0x014;
+	tx3927_sioptr(0)->fcr = 0;
+	tx3927_sioptr(0)->flcr = 0x02;
+	tx3927_sioptr(0)->bgr = ((JMR3927_BASE_BAUD + baud / 2) / baud) |
+		TXx927_SIBGR_BCLK_T0;
+#if 0
+	/*
+	 * Reset the UART.
+	 */
+	tx3927_sioptr(0)->fcr = TXx927_SIFCR_SWRST;
+	while (tx3927_sioptr(0)->fcr & TXx927_SIFCR_SWRST)
+		;
+
+	/*
+	 * and set the speed of the serial port
+	 * (currently hardwired to 9600 8N1
+	 */
+
+	tx3927_sioptr(0)->lcr = TXx927_SILCR_UMODE_8BIT |
+		TXx927_SILCR_USBL_1BIT |
+		TXx927_SILCR_SCS_IMCLK_BG;
+	tx3927_sioptr(0)->bgr =
+		((JMR3927_BASE_BAUD + baud / 2) / baud) |
+		TXx927_SIBGR_BCLK_T0;
+
+	/* HW RTS/CTS control */
+	if (ser->flags & ASYNC_HAVE_CTS_LINE)
+		tx3927_sioptr(0)->flcr = TXx927_SIFLCR_RCS | TXx927_SIFLCR_TES |
+			TXx927_SIFLCR_RTSTL_MAX /* 15 */;
+	/* Enable RX/TX */
+	tx3927_sioptr(0)->flcr &= ~(TXx927_SIFLCR_RSDE | TXx927_SIFLCR_TSDE);
+#endif
+}
diff --git a/arch/mips/jmr3927/rbhma3100/setup.c b/arch/mips/jmr3927/rbhma3100/setup.c
new file mode 100644
index 0000000..32039bb
--- /dev/null
+++ b/arch/mips/jmr3927/rbhma3100/setup.c
@@ -0,0 +1,510 @@
+/***********************************************************************
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *              ahennessy@mvista.com
+ *
+ * Based on arch/mips/ddb5xxx/ddb5477/setup.c
+ *
+ *     Setup file for JMR3927.
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***********************************************************************
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/kdev_t.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/ide.h>
+#include <linux/ioport.h>
+#include <linux/param.h>	/* for HZ */
+#include <linux/delay.h>
+
+#include <asm/addrspace.h>
+#include <asm/time.h>
+#include <asm/bcache.h>
+#include <asm/irq.h>
+#include <asm/reboot.h>
+#include <asm/gdb-stub.h>
+#include <asm/jmr3927/jmr3927.h>
+#include <asm/mipsregs.h>
+#include <asm/traps.h>
+
+/* Tick Timer divider */
+#define JMR3927_TIMER_CCD	0	/* 1/2 */
+#define JMR3927_TIMER_CLK	(JMR3927_IMCLK / (2 << JMR3927_TIMER_CCD))
+
+unsigned char led_state = 0xf;
+
+struct {
+    struct resource ram0;
+    struct resource ram1;
+    struct resource pcimem;
+    struct resource iob;
+    struct resource ioc;
+    struct resource pciio;
+    struct resource jmy1394;
+    struct resource rom1;
+    struct resource rom0;
+    struct resource sio0;
+    struct resource sio1;
+} jmr3927_resources = {
+    { "RAM0",           0,         0x01FFFFFF,  IORESOURCE_MEM },
+    { "RAM1",          0x02000000, 0x03FFFFFF,  IORESOURCE_MEM },
+    { "PCIMEM",        0x08000000, 0x07FFFFFF,  IORESOURCE_MEM },
+    { "IOB",           0x10000000, 0x13FFFFFF                  },
+    { "IOC",           0x14000000, 0x14FFFFFF                  },
+    { "PCIIO",         0x15000000, 0x15FFFFFF                  },
+    { "JMY1394",       0x1D000000, 0x1D3FFFFF                  },
+    { "ROM1",          0x1E000000, 0x1E3FFFFF                  },
+    { "ROM0",          0x1FC00000, 0x1FFFFFFF                  },
+    { "SIO0",          0xFFFEF300, 0xFFFEF3FF                  },
+    { "SIO1",          0xFFFEF400, 0xFFFEF4FF                  },
+};
+
+/* don't enable - see errata */
+int jmr3927_ccfg_toeon = 0;
+
+static inline void do_reset(void)
+{
+#ifdef CONFIG_TC35815
+	extern void tc35815_killall(void);
+	tc35815_killall();
+#endif
+#if 1	/* Resetting PCI bus */
+	jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
+	jmr3927_ioc_reg_out(JMR3927_IOC_RESET_PCI, JMR3927_IOC_RESET_ADDR);
+	(void)jmr3927_ioc_reg_in(JMR3927_IOC_RESET_ADDR);	/* flush WB */
+	mdelay(1);
+	jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
+#endif
+	jmr3927_ioc_reg_out(JMR3927_IOC_RESET_CPU, JMR3927_IOC_RESET_ADDR);
+}
+
+static void jmr3927_machine_restart(char *command)
+{
+	local_irq_disable();
+	puts("Rebooting...");
+	do_reset();
+}
+
+static void jmr3927_machine_halt(void)
+{
+	puts("JMR-TX3927 halted.\n");
+	while (1);
+}
+
+static void jmr3927_machine_power_off(void)
+{
+	puts("JMR-TX3927 halted. Please turn off the power.\n");
+	while (1);
+}
+
+#define USE_RTC_DS1742
+#ifdef USE_RTC_DS1742
+extern void rtc_ds1742_init(unsigned long base);
+#endif
+static void __init jmr3927_time_init(void)
+{
+#ifdef USE_RTC_DS1742
+	if (jmr3927_have_nvram()) {
+	        rtc_ds1742_init(JMR3927_IOC_NVRAMB_ADDR);
+	}
+#endif
+}
+
+unsigned long jmr3927_do_gettimeoffset(void);
+extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
+
+static void __init jmr3927_timer_setup(struct irqaction *irq)
+{
+	do_gettimeoffset = jmr3927_do_gettimeoffset;
+
+	jmr3927_tmrptr->cpra = JMR3927_TIMER_CLK / HZ;
+	jmr3927_tmrptr->itmr = TXx927_TMTITMR_TIIE | TXx927_TMTITMR_TZCE;
+	jmr3927_tmrptr->ccdr = JMR3927_TIMER_CCD;
+	jmr3927_tmrptr->tcr =
+		TXx927_TMTCR_TCE | TXx927_TMTCR_CCDE | TXx927_TMTCR_TMODE_ITVL;
+
+	setup_irq(JMR3927_IRQ_TICK, irq);
+}
+
+#define USECS_PER_JIFFY (1000000/HZ)
+
+unsigned long jmr3927_do_gettimeoffset(void)
+{
+       unsigned long count;
+       unsigned long res = 0;
+
+       /* MUST read TRR before TISR. */
+       count = jmr3927_tmrptr->trr;
+
+       if (jmr3927_tmrptr->tisr & TXx927_TMTISR_TIIS) {
+               /* timer interrupt is pending.  use Max value. */
+               res = USECS_PER_JIFFY - 1;
+       } else {
+               /* convert to usec */
+               /* res = count / (JMR3927_TIMER_CLK / 1000000); */
+               res = (count << 7) / ((JMR3927_TIMER_CLK << 7) / 1000000);
+
+               /*
+                * Due to possible jiffies inconsistencies, we need to check
+                * the result so that we'll get a timer that is monotonic.
+                */
+               if (res >= USECS_PER_JIFFY)
+                       res = USECS_PER_JIFFY-1;
+       }
+
+       return res;
+}
+
+
+//#undef DO_WRITE_THROUGH
+#define DO_WRITE_THROUGH
+#define DO_ENABLE_CACHE
+
+extern char * __init prom_getcmdline(void);
+static void jmr3927_board_init(void);
+extern struct resource pci_io_resource;
+extern struct resource pci_mem_resource;
+
+static void __init jmr3927_setup(void)
+{
+	char *argptr;
+
+	set_io_port_base(JMR3927_PORT_BASE + JMR3927_PCIIO);
+
+	board_time_init = jmr3927_time_init;
+	board_timer_setup = jmr3927_timer_setup;
+
+	_machine_restart = jmr3927_machine_restart;
+	_machine_halt = jmr3927_machine_halt;
+	_machine_power_off = jmr3927_machine_power_off;
+
+	/*
+	 * IO/MEM resources.
+	 */
+	ioport_resource.start = pci_io_resource.start;
+	ioport_resource.end = pci_io_resource.end;
+	iomem_resource.start = pci_mem_resource.start;
+	iomem_resource.end = pci_mem_resource.end;
+
+	/* Reboot on panic */
+	panic_timeout = 180;
+
+	{
+		unsigned int conf;
+		conf = read_c0_conf();
+	}
+
+#if 1
+	/* cache setup */
+	{
+		unsigned int conf;
+#ifdef DO_ENABLE_CACHE
+		int mips_ic_disable = 0, mips_dc_disable = 0;
+#else
+		int mips_ic_disable = 1, mips_dc_disable = 1;
+#endif
+#ifdef DO_WRITE_THROUGH
+		int mips_config_cwfon = 0;
+		int mips_config_wbon = 0;
+#else
+		int mips_config_cwfon = 1;
+		int mips_config_wbon = 1;
+#endif
+
+		conf = read_c0_conf();
+		conf &= ~(TX39_CONF_ICE | TX39_CONF_DCE | TX39_CONF_WBON | TX39_CONF_CWFON);
+		conf |= mips_ic_disable ? 0 : TX39_CONF_ICE;
+		conf |= mips_dc_disable ? 0 : TX39_CONF_DCE;
+		conf |= mips_config_wbon ? TX39_CONF_WBON : 0;
+		conf |= mips_config_cwfon ? TX39_CONF_CWFON : 0;
+
+		write_c0_conf(conf);
+		write_c0_cache(0);
+	}
+#endif
+
+	/* initialize board */
+	jmr3927_board_init();
+
+	argptr = prom_getcmdline();
+
+	if ((argptr = strstr(argptr, "toeon")) != NULL) {
+			jmr3927_ccfg_toeon = 1;
+	}
+	argptr = prom_getcmdline();
+	if ((argptr = strstr(argptr, "ip=")) == NULL) {
+		argptr = prom_getcmdline();
+		strcat(argptr, " ip=bootp");
+	}
+
+#ifdef CONFIG_TXX927_SERIAL_CONSOLE
+	argptr = prom_getcmdline();
+	if ((argptr = strstr(argptr, "console=")) == NULL) {
+		argptr = prom_getcmdline();
+		strcat(argptr, " console=ttyS1,115200");
+	}
+#endif
+}
+
+early_initcall(jmr3927_setup);
+
+
+static void tx3927_setup(void);
+
+#ifdef CONFIG_PCI
+unsigned long mips_pci_io_base;
+unsigned long mips_pci_io_size;
+unsigned long mips_pci_mem_base;
+unsigned long mips_pci_mem_size;
+/* for legacy I/O, PCI I/O PCI Bus address must be 0 */
+unsigned long mips_pci_io_pciaddr = 0;
+#endif
+
+static void __init jmr3927_board_init(void)
+{
+	char *argptr;
+
+#ifdef CONFIG_PCI
+	mips_pci_io_base = JMR3927_PCIIO;
+	mips_pci_io_size = JMR3927_PCIIO_SIZE;
+	mips_pci_mem_base = JMR3927_PCIMEM;
+	mips_pci_mem_size = JMR3927_PCIMEM_SIZE;
+#endif
+
+	tx3927_setup();
+
+	if (jmr3927_have_isac()) {
+
+#ifdef CONFIG_FB_E1355
+		argptr = prom_getcmdline();
+		if ((argptr = strstr(argptr, "video=")) == NULL) {
+			argptr = prom_getcmdline();
+			strcat(argptr, " video=e1355fb:crt16h");
+		}
+#endif
+
+#ifdef CONFIG_BLK_DEV_IDE
+		/* overrides PCI-IDE */
+#endif
+	}
+
+	/* SIO0 DTR on */
+	jmr3927_ioc_reg_out(0, JMR3927_IOC_DTR_ADDR);
+
+	jmr3927_led_set(0);
+
+
+	if (jmr3927_have_isac())
+		jmr3927_io_led_set(0);
+	printk("JMR-TX3927 (Rev %d) --- IOC(Rev %d) DIPSW:%d,%d,%d,%d\n",
+	       jmr3927_ioc_reg_in(JMR3927_IOC_BREV_ADDR) & JMR3927_REV_MASK,
+	       jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR) & JMR3927_REV_MASK,
+	       jmr3927_dipsw1(), jmr3927_dipsw2(),
+	       jmr3927_dipsw3(), jmr3927_dipsw4());
+	if (jmr3927_have_isac())
+		printk("JMI-3927IO2 --- ISAC(Rev %d) DIPSW:%01x\n",
+		       jmr3927_isac_reg_in(JMR3927_ISAC_REV_ADDR) & JMR3927_REV_MASK,
+		       jmr3927_io_dipsw());
+}
+
+static void __init tx3927_setup(void)
+{
+	int i;
+
+	/* SDRAMC are configured by PROM */
+
+	/* ROMC */
+	tx3927_romcptr->cr[1] = JMR3927_ROMCE1 | 0x00030048;
+	tx3927_romcptr->cr[2] = JMR3927_ROMCE2 | 0x000064c8;
+	tx3927_romcptr->cr[3] = JMR3927_ROMCE3 | 0x0003f698;
+	tx3927_romcptr->cr[5] = JMR3927_ROMCE5 | 0x0000f218;
+
+	/* CCFG */
+	/* enable Timeout BusError */
+	if (jmr3927_ccfg_toeon)
+		tx3927_ccfgptr->ccfg |= TX3927_CCFG_TOE;
+
+	/* clear BusErrorOnWrite flag */
+	tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_BEOW;
+	/* Disable PCI snoop */
+	tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_PSNP;
+
+#ifdef DO_WRITE_THROUGH
+	/* Enable PCI SNOOP - with write through only */
+	tx3927_ccfgptr->ccfg |= TX3927_CCFG_PSNP;
+#endif
+
+	/* Pin selection */
+	tx3927_ccfgptr->pcfg &= ~TX3927_PCFG_SELALL;
+	tx3927_ccfgptr->pcfg |=
+		TX3927_PCFG_SELSIOC(0) | TX3927_PCFG_SELSIO_ALL |
+		(TX3927_PCFG_SELDMA_ALL & ~TX3927_PCFG_SELDMA(1));
+
+	printk("TX3927 -- CRIR:%08lx CCFG:%08lx PCFG:%08lx\n",
+	       tx3927_ccfgptr->crir,
+	       tx3927_ccfgptr->ccfg, tx3927_ccfgptr->pcfg);
+
+	/* IRC */
+	/* disable interrupt control */
+	tx3927_ircptr->cer = 0;
+	/* mask all IRC interrupts */
+	tx3927_ircptr->imr = 0;
+	for (i = 0; i < TX3927_NUM_IR / 2; i++) {
+		tx3927_ircptr->ilr[i] = 0;
+	}
+	/* setup IRC interrupt mode (Low Active) */
+	for (i = 0; i < TX3927_NUM_IR / 8; i++) {
+		tx3927_ircptr->cr[i] = 0;
+	}
+
+	/* TMR */
+	/* disable all timers */
+	for (i = 0; i < TX3927_NR_TMR; i++) {
+		tx3927_tmrptr(i)->tcr = TXx927_TMTCR_CRE;
+		tx3927_tmrptr(i)->tisr = 0;
+		tx3927_tmrptr(i)->cpra = 0xffffffff;
+		tx3927_tmrptr(i)->itmr = 0;
+		tx3927_tmrptr(i)->ccdr = 0;
+		tx3927_tmrptr(i)->pgmr = 0;
+	}
+
+	/* DMA */
+	tx3927_dmaptr->mcr = 0;
+	for (i = 0; i < sizeof(tx3927_dmaptr->ch) / sizeof(tx3927_dmaptr->ch[0]); i++) {
+		/* reset channel */
+		tx3927_dmaptr->ch[i].ccr = TX3927_DMA_CCR_CHRST;
+		tx3927_dmaptr->ch[i].ccr = 0;
+	}
+	/* enable DMA */
+#ifdef __BIG_ENDIAN
+	tx3927_dmaptr->mcr = TX3927_DMA_MCR_MSTEN;
+#else
+	tx3927_dmaptr->mcr = TX3927_DMA_MCR_MSTEN | TX3927_DMA_MCR_LE;
+#endif
+
+#ifdef CONFIG_PCI
+	/* PCIC */
+	printk("TX3927 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:",
+	       tx3927_pcicptr->did, tx3927_pcicptr->vid,
+	       tx3927_pcicptr->rid);
+	if (!(tx3927_ccfgptr->ccfg & TX3927_CCFG_PCIXARB)) {
+		printk("External\n");
+		/* XXX */
+	} else {
+		printk("Internal\n");
+
+		/* Reset PCI Bus */
+		jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
+		udelay(100);
+		jmr3927_ioc_reg_out(JMR3927_IOC_RESET_PCI,
+				    JMR3927_IOC_RESET_ADDR);
+		udelay(100);
+		jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
+
+
+		/* Disable External PCI Config. Access */
+		tx3927_pcicptr->lbc = TX3927_PCIC_LBC_EPCAD;
+#ifdef __BIG_ENDIAN
+		tx3927_pcicptr->lbc |= TX3927_PCIC_LBC_IBSE |
+			TX3927_PCIC_LBC_TIBSE |
+			TX3927_PCIC_LBC_TMFBSE | TX3927_PCIC_LBC_MSDSE;
+#endif
+		/* LB->PCI mappings */
+		tx3927_pcicptr->iomas = ~(mips_pci_io_size - 1);
+		tx3927_pcicptr->ilbioma = mips_pci_io_base;
+		tx3927_pcicptr->ipbioma = mips_pci_io_pciaddr;
+		tx3927_pcicptr->mmas = ~(mips_pci_mem_size - 1);
+		tx3927_pcicptr->ilbmma = mips_pci_mem_base;
+		tx3927_pcicptr->ipbmma = mips_pci_mem_base;
+		/* PCI->LB mappings */
+		tx3927_pcicptr->iobas = 0xffffffff;
+		tx3927_pcicptr->ioba = 0;
+		tx3927_pcicptr->tlbioma = 0;
+		tx3927_pcicptr->mbas = ~(mips_pci_mem_size - 1);
+		tx3927_pcicptr->mba = 0;
+		tx3927_pcicptr->tlbmma = 0;
+#ifndef JMR3927_INIT_INDIRECT_PCI
+		/* Enable Direct mapping Address Space Decoder */
+		tx3927_pcicptr->lbc |= TX3927_PCIC_LBC_ILMDE | TX3927_PCIC_LBC_ILIDE;
+#endif
+
+		/* Clear All Local Bus Status */
+		tx3927_pcicptr->lbstat = TX3927_PCIC_LBIM_ALL;
+		/* Enable All Local Bus Interrupts */
+		tx3927_pcicptr->lbim = TX3927_PCIC_LBIM_ALL;
+		/* Clear All PCI Status Error */
+		tx3927_pcicptr->pcistat = TX3927_PCIC_PCISTATIM_ALL;
+		/* Enable All PCI Status Error Interrupts */
+		tx3927_pcicptr->pcistatim = TX3927_PCIC_PCISTATIM_ALL;
+
+		/* PCIC Int => IRC IRQ10 */
+		tx3927_pcicptr->il = TX3927_IR_PCI;
+#if 1
+		/* Target Control (per errata) */
+		tx3927_pcicptr->tc = TX3927_PCIC_TC_OF8E | TX3927_PCIC_TC_IF8E;
+#endif
+
+		/* Enable Bus Arbiter */
+#if 0
+		tx3927_pcicptr->req_trace = 0x73737373;
+#endif
+		tx3927_pcicptr->pbapmc = TX3927_PCIC_PBAPMC_PBAEN;
+
+		tx3927_pcicptr->pcicmd = PCI_COMMAND_MASTER |
+			PCI_COMMAND_MEMORY |
+#if 1
+			PCI_COMMAND_IO |
+#endif
+			PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
+	}
+#endif /* CONFIG_PCI */
+
+	/* PIO */
+	/* PIO[15:12] connected to LEDs */
+	tx3927_pioptr->dir = 0x0000f000;
+	tx3927_pioptr->maskcpu = 0;
+	tx3927_pioptr->maskext = 0;
+	{
+		unsigned int conf;
+
+	conf = read_c0_conf();
+               if (!(conf & TX39_CONF_ICE))
+                       printk("TX3927 I-Cache disabled.\n");
+               if (!(conf & TX39_CONF_DCE))
+                       printk("TX3927 D-Cache disabled.\n");
+               else if (!(conf & TX39_CONF_WBON))
+                       printk("TX3927 D-Cache WriteThrough.\n");
+               else if (!(conf & TX39_CONF_CWFON))
+                       printk("TX3927 D-Cache WriteBack.\n");
+               else
+                       printk("TX3927 D-Cache WriteBack (CWF) .\n");
+	}
+}
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
new file mode 100644
index 0000000..a0230ee
--- /dev/null
+++ b/arch/mips/kernel/Makefile
@@ -0,0 +1,65 @@
+#
+# Makefile for the Linux/MIPS kernel.
+#
+
+extra-y		:= head.o init_task.o vmlinux.lds
+
+obj-y		+= cpu-probe.o branch.o entry.o genex.o irq.o process.o \
+		   ptrace.o reset.o semaphore.o setup.o signal.o syscall.o \
+		   time.o traps.o unaligned.o
+
+binfmt_irix-objs	:= irixelf.o irixinv.o irixioctl.o irixsig.o	\
+			   irix5sys.o sysirix.o
+
+ifdef CONFIG_MODULES
+obj-y				+= mips_ksyms.o module.o
+obj-$(CONFIG_MIPS32)		+= module-elf32.o
+obj-$(CONFIG_MIPS64)		+= module-elf64.o
+endif
+
+obj-$(CONFIG_CPU_R3000)		+= r2300_fpu.o r2300_switch.o
+obj-$(CONFIG_CPU_TX39XX)	+= r2300_fpu.o r2300_switch.o
+obj-$(CONFIG_CPU_TX49XX)	+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_R4000)		+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_VR41XX)	+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_R4300)		+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_R4X00)		+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_R5000)		+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_R5432)		+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_R8000)		+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_RM7000)	+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_RM9000)	+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_NEVADA)	+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_R10000)	+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_SB1)		+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_MIPS32)	+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_MIPS64)	+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_R6000)		+= r6000_fpu.o r4k_switch.o
+
+obj-$(CONFIG_SMP)		+= smp.o
+
+obj-$(CONFIG_NO_ISA)		+= dma-no-isa.o
+obj-$(CONFIG_I8259)		+= i8259.o
+obj-$(CONFIG_IRQ_CPU)		+= irq_cpu.o
+obj-$(CONFIG_IRQ_CPU_RM7K)	+= irq-rm7000.o
+obj-$(CONFIG_IRQ_CPU_RM9K)	+= irq-rm9000.o
+obj-$(CONFIG_IRQ_MV64340)	+= irq-mv6434x.o
+
+obj-$(CONFIG_MIPS32)		+= scall32-o32.o
+obj-$(CONFIG_MIPS64)		+= scall64-64.o
+obj-$(CONFIG_BINFMT_IRIX)	+= binfmt_irix.o
+obj-$(CONFIG_MIPS32_COMPAT)	+= ioctl32.o linux32.o signal32.o
+obj-$(CONFIG_MIPS32_N32)	+= binfmt_elfn32.o scall64-n32.o signal_n32.o
+obj-$(CONFIG_MIPS32_O32)	+= binfmt_elfo32.o scall64-o32.o ptrace32.o
+
+obj-$(CONFIG_KGDB)		+= gdb-low.o gdb-stub.o
+obj-$(CONFIG_PROC_FS)		+= proc.o
+
+obj-$(CONFIG_MIPS64)		+= cpu-bugs64.o
+
+obj-$(CONFIG_GEN_RTC)		+= genrtc.o
+
+CFLAGS_cpu-bugs64.o	= $(shell if $(CC) $(CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi)
+CFLAGS_ioctl32.o	+= -Ifs/
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/kernel/binfmt_elfn32.c b/arch/mips/kernel/binfmt_elfn32.c
new file mode 100644
index 0000000..ed47041
--- /dev/null
+++ b/arch/mips/kernel/binfmt_elfn32.c
@@ -0,0 +1,119 @@
+/*
+ * Support for n32 Linux/MIPS ELF binaries.
+ *
+ * Copyright (C) 1999, 2001 Ralf Baechle
+ * Copyright (C) 1999, 2001 Silicon Graphics, Inc.
+ *
+ * Heavily inspired by the 32-bit Sparc compat code which is
+ * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller (davem@redhat.com)
+ * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek   (jj@ultra.linux.cz)
+ */
+
+#define ELF_ARCH		EM_MIPS
+#define ELF_CLASS		ELFCLASS32
+#ifdef __MIPSEB__
+#define ELF_DATA		ELFDATA2MSB;
+#else /* __MIPSEL__ */
+#define ELF_DATA		ELFDATA2LSB;
+#endif
+
+/* ELF register definitions */
+#define ELF_NGREG	45
+#define ELF_NFPREG	33
+
+typedef unsigned long elf_greg_t;
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef double elf_fpreg_t;
+typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(hdr)						\
+({									\
+	int __res = 1;							\
+	struct elfhdr *__h = (hdr);					\
+									\
+	if (__h->e_machine != EM_MIPS)					\
+		__res = 0;						\
+	if (__h->e_ident[EI_CLASS] != ELFCLASS32)			\
+		__res = 0;						\
+	if (((__h->e_flags & EF_MIPS_ABI2) == 0) ||			\
+	    ((__h->e_flags & EF_MIPS_ABI) != 0))			\
+		__res = 0;						\
+									\
+	__res;								\
+})
+
+#define TASK32_SIZE		0x7fff8000UL
+#undef ELF_ET_DYN_BASE
+#define ELF_ET_DYN_BASE         (TASK32_SIZE / 3 * 2)
+
+#include <asm/processor.h>
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/elfcore.h>
+#include <linux/compat.h>
+
+#define elf_prstatus elf_prstatus32
+struct elf_prstatus32
+{
+	struct elf_siginfo pr_info;	/* Info associated with signal */
+	short	pr_cursig;		/* Current signal */
+	unsigned int pr_sigpend;	/* Set of pending signals */
+	unsigned int pr_sighold;	/* Set of held signals */
+	pid_t	pr_pid;
+	pid_t	pr_ppid;
+	pid_t	pr_pgrp;
+	pid_t	pr_sid;
+	struct compat_timeval pr_utime;	/* User time */
+	struct compat_timeval pr_stime;	/* System time */
+	struct compat_timeval pr_cutime;/* Cumulative user time */
+	struct compat_timeval pr_cstime;/* Cumulative system time */
+	elf_gregset_t pr_reg;	/* GP registers */
+	int pr_fpvalid;		/* True if math co-processor being used.  */
+};
+
+#define elf_prpsinfo elf_prpsinfo32
+struct elf_prpsinfo32
+{
+	char	pr_state;	/* numeric process state */
+	char	pr_sname;	/* char for pr_state */
+	char	pr_zomb;	/* zombie */
+	char	pr_nice;	/* nice val */
+	unsigned int pr_flag;	/* flags */
+	__kernel_uid_t	pr_uid;
+	__kernel_gid_t	pr_gid;
+	pid_t	pr_pid, pr_ppid, pr_pgrp, pr_sid;
+	/* Lots missing */
+	char	pr_fname[16];	/* filename of executable */
+	char	pr_psargs[ELF_PRARGSZ];	/* initial part of arg list */
+};
+
+#define elf_addr_t	u32
+#define elf_caddr_t	u32
+#define init_elf_binfmt init_elfn32_binfmt
+
+#define jiffies_to_timeval jiffies_to_compat_timeval
+static __inline__ void
+jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
+{
+	/*
+	 * Convert jiffies to nanoseconds and seperate with
+	 * one divide.
+	 */
+	u64 nsec = (u64)jiffies * TICK_NSEC; 
+	value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &value->tv_usec);
+	value->tv_usec /= NSEC_PER_USEC;
+}
+
+#define ELF_CORE_EFLAGS EF_MIPS_ABI2
+
+MODULE_DESCRIPTION("Binary format loader for compatibility with n32 Linux/MIPS binaries");
+MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)");
+
+#undef MODULE_DESCRIPTION
+#undef MODULE_AUTHOR
+
+#include "../../../fs/binfmt_elf.c"
diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c
new file mode 100644
index 0000000..ee21b18
--- /dev/null
+++ b/arch/mips/kernel/binfmt_elfo32.c
@@ -0,0 +1,139 @@
+/*
+ * Support for o32 Linux/MIPS ELF binaries.
+ *
+ * Copyright (C) 1999, 2001 Ralf Baechle
+ * Copyright (C) 1999, 2001 Silicon Graphics, Inc.
+ *
+ * Heavily inspired by the 32-bit Sparc compat code which is
+ * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller (davem@redhat.com)
+ * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek   (jj@ultra.linux.cz)
+ */
+
+#define ELF_ARCH		EM_MIPS
+#define ELF_CLASS		ELFCLASS32
+#ifdef __MIPSEB__
+#define ELF_DATA		ELFDATA2MSB;
+#else /* __MIPSEL__ */
+#define ELF_DATA		ELFDATA2LSB;
+#endif
+
+/* ELF register definitions */
+#define ELF_NGREG	45
+#define ELF_NFPREG	33
+
+typedef unsigned int elf_greg_t;
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef double elf_fpreg_t;
+typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(hdr)						\
+({									\
+	int __res = 1;							\
+	struct elfhdr *__h = (hdr);					\
+									\
+	if (__h->e_machine != EM_MIPS)					\
+		__res = 0;						\
+	if (__h->e_ident[EI_CLASS] != ELFCLASS32)			\
+		__res = 0;						\
+	if ((__h->e_flags & EF_MIPS_ABI2) != 0)				\
+		__res = 0;						\
+	if (((__h->e_flags & EF_MIPS_ABI) != 0) &&			\
+	    ((__h->e_flags & EF_MIPS_ABI) != EF_MIPS_ABI_O32))		\
+		__res = 0;						\
+									\
+	__res;								\
+})
+
+#define TASK32_SIZE		0x7fff8000UL
+#undef ELF_ET_DYN_BASE
+#define ELF_ET_DYN_BASE         (TASK32_SIZE / 3 * 2)
+
+#include <asm/processor.h>
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/elfcore.h>
+#include <linux/compat.h>
+
+#define elf_prstatus elf_prstatus32
+struct elf_prstatus32
+{
+	struct elf_siginfo pr_info;	/* Info associated with signal */
+	short	pr_cursig;		/* Current signal */
+	unsigned int pr_sigpend;	/* Set of pending signals */
+	unsigned int pr_sighold;	/* Set of held signals */
+	pid_t	pr_pid;
+	pid_t	pr_ppid;
+	pid_t	pr_pgrp;
+	pid_t	pr_sid;
+	struct compat_timeval pr_utime;	/* User time */
+	struct compat_timeval pr_stime;	/* System time */
+	struct compat_timeval pr_cutime;/* Cumulative user time */
+	struct compat_timeval pr_cstime;/* Cumulative system time */
+	elf_gregset_t pr_reg;	/* GP registers */
+	int pr_fpvalid;		/* True if math co-processor being used.  */
+};
+
+#define elf_prpsinfo elf_prpsinfo32
+struct elf_prpsinfo32
+{
+	char	pr_state;	/* numeric process state */
+	char	pr_sname;	/* char for pr_state */
+	char	pr_zomb;	/* zombie */
+	char	pr_nice;	/* nice val */
+	unsigned int pr_flag;	/* flags */
+	__kernel_uid_t	pr_uid;
+	__kernel_gid_t	pr_gid;
+	pid_t	pr_pid, pr_ppid, pr_pgrp, pr_sid;
+	/* Lots missing */
+	char	pr_fname[16];	/* filename of executable */
+	char	pr_psargs[ELF_PRARGSZ];	/* initial part of arg list */
+};
+
+#define elf_addr_t	u32
+#define elf_caddr_t	u32
+#define init_elf_binfmt init_elf32_binfmt
+
+#define jiffies_to_timeval jiffies_to_compat_timeval
+static __inline__ void
+jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
+{
+	/*
+	 * Convert jiffies to nanoseconds and seperate with
+	 * one divide.
+	 */
+	u64 nsec = (u64)jiffies * TICK_NSEC; 
+	value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &value->tv_usec);
+	value->tv_usec /= NSEC_PER_USEC;
+}
+
+#undef ELF_CORE_COPY_REGS
+#define ELF_CORE_COPY_REGS(_dest,_regs) elf32_core_copy_regs(_dest,_regs);
+
+void elf32_core_copy_regs(elf_gregset_t _dest, struct pt_regs *_regs)
+{
+	int i;
+
+	memset(_dest, 0, sizeof(elf_gregset_t));
+
+	/* XXXKW the 6 is from EF_REG0 in gdb/gdb/mips-linux-tdep.c, include/asm-mips/reg.h */
+	for (i=6; i<38; i++)
+		_dest[i] = (elf_greg_t) _regs->regs[i-6];
+	_dest[i++] = (elf_greg_t) _regs->lo;
+	_dest[i++] = (elf_greg_t) _regs->hi;
+	_dest[i++] = (elf_greg_t) _regs->cp0_epc;
+	_dest[i++] = (elf_greg_t) _regs->cp0_badvaddr;
+	_dest[i++] = (elf_greg_t) _regs->cp0_status;
+	_dest[i++] = (elf_greg_t) _regs->cp0_cause;
+}
+
+MODULE_DESCRIPTION("Binary format loader for compatibility with o32 Linux/MIPS binaries");
+MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)");
+
+#undef MODULE_DESCRIPTION
+#undef MODULE_AUTHOR
+
+#include "../../../fs/binfmt_elf.c"
diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c
new file mode 100644
index 0000000..01117e9
--- /dev/null
+++ b/arch/mips/kernel/branch.c
@@ -0,0 +1,199 @@
+/*
+ * 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) 1996, 97, 2000, 2001 by Ralf Baechle
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <asm/branch.h>
+#include <asm/cpu.h>
+#include <asm/cpu-features.h>
+#include <asm/inst.h>
+#include <asm/ptrace.h>
+#include <asm/uaccess.h>
+
+/*
+ * Compute the return address and do emulate branch simulation, if required.
+ */
+int __compute_return_epc(struct pt_regs *regs)
+{
+	unsigned int *addr, bit, fcr31;
+	long epc;
+	union mips_instruction insn;
+
+	epc = regs->cp0_epc;
+	if (epc & 3)
+		goto unaligned;
+
+	/*
+	 * Read the instruction
+	 */
+	addr = (unsigned int *) epc;
+	if (__get_user(insn.word, addr)) {
+		force_sig(SIGSEGV, current);
+		return -EFAULT;
+	}
+
+	regs->regs[0] = 0;
+	switch (insn.i_format.opcode) {
+	/*
+	 * jr and jalr are in r_format format.
+	 */
+	case spec_op:
+		switch (insn.r_format.func) {
+		case jalr_op:
+			regs->regs[insn.r_format.rd] = epc + 8;
+			/* Fall through */
+		case jr_op:
+			regs->cp0_epc = regs->regs[insn.r_format.rs];
+			break;
+		}
+		break;
+
+	/*
+	 * This group contains:
+	 * bltz_op, bgez_op, bltzl_op, bgezl_op,
+	 * bltzal_op, bgezal_op, bltzall_op, bgezall_op.
+	 */
+	case bcond_op:
+		switch (insn.i_format.rt) {
+	 	case bltz_op:
+		case bltzl_op:
+			if ((long)regs->regs[insn.i_format.rs] < 0)
+				epc = epc + 4 + (insn.i_format.simmediate << 2);
+			else
+				epc += 8;
+			regs->cp0_epc = epc;
+			break;
+
+		case bgez_op:
+		case bgezl_op:
+			if ((long)regs->regs[insn.i_format.rs] >= 0)
+				epc = epc + 4 + (insn.i_format.simmediate << 2);
+			else
+				epc += 8;
+			regs->cp0_epc = epc;
+			break;
+
+		case bltzal_op:
+		case bltzall_op:
+			regs->regs[31] = epc + 8;
+			if ((long)regs->regs[insn.i_format.rs] < 0)
+				epc = epc + 4 + (insn.i_format.simmediate << 2);
+			else
+				epc += 8;
+			regs->cp0_epc = epc;
+			break;
+
+		case bgezal_op:
+		case bgezall_op:
+			regs->regs[31] = epc + 8;
+			if ((long)regs->regs[insn.i_format.rs] >= 0)
+				epc = epc + 4 + (insn.i_format.simmediate << 2);
+			else
+				epc += 8;
+			regs->cp0_epc = epc;
+			break;
+		}
+		break;
+
+	/*
+	 * These are unconditional and in j_format.
+	 */
+	case jal_op:
+		regs->regs[31] = regs->cp0_epc + 8;
+	case j_op:
+		epc += 4;
+		epc >>= 28;
+		epc <<= 28;
+		epc |= (insn.j_format.target << 2);
+		regs->cp0_epc = epc;
+		break;
+
+	/*
+	 * These are conditional and in i_format.
+	 */
+	case beq_op:
+	case beql_op:
+		if (regs->regs[insn.i_format.rs] ==
+		    regs->regs[insn.i_format.rt])
+			epc = epc + 4 + (insn.i_format.simmediate << 2);
+		else
+			epc += 8;
+		regs->cp0_epc = epc;
+		break;
+
+	case bne_op:
+	case bnel_op:
+		if (regs->regs[insn.i_format.rs] !=
+		    regs->regs[insn.i_format.rt])
+			epc = epc + 4 + (insn.i_format.simmediate << 2);
+		else
+			epc += 8;
+		regs->cp0_epc = epc;
+		break;
+
+	case blez_op: /* not really i_format */
+	case blezl_op:
+		/* rt field assumed to be zero */
+		if ((long)regs->regs[insn.i_format.rs] <= 0)
+			epc = epc + 4 + (insn.i_format.simmediate << 2);
+		else
+			epc += 8;
+		regs->cp0_epc = epc;
+		break;
+
+	case bgtz_op:
+	case bgtzl_op:
+		/* rt field assumed to be zero */
+		if ((long)regs->regs[insn.i_format.rs] > 0)
+			epc = epc + 4 + (insn.i_format.simmediate << 2);
+		else
+			epc += 8;
+		regs->cp0_epc = epc;
+		break;
+
+	/*
+	 * And now the FPA/cp1 branch instructions.
+	 */
+	case cop1_op:
+		if (!cpu_has_fpu)
+			fcr31 = current->thread.fpu.soft.fcr31;
+		else
+			asm volatile("cfc1\t%0,$31" : "=r" (fcr31));
+		bit = (insn.i_format.rt >> 2);
+		bit += (bit != 0);
+		bit += 23;
+		switch (insn.i_format.rt) {
+		case 0:	/* bc1f */
+		case 2:	/* bc1fl */
+			if (~fcr31 & (1 << bit))
+				epc = epc + 4 + (insn.i_format.simmediate << 2);
+			else
+				epc += 8;
+			regs->cp0_epc = epc;
+			break;
+
+		case 1:	/* bc1t */
+		case 3:	/* bc1tl */
+			if (fcr31 & (1 << bit))
+				epc = epc + 4 + (insn.i_format.simmediate << 2);
+			else
+				epc += 8;
+			regs->cp0_epc = epc;
+			break;
+		}
+		break;
+	}
+
+	return 0;
+
+unaligned:
+	printk("%s: unaligned epc - sending SIGBUS.\n", current->comm);
+	force_sig(SIGBUS, current);
+	return -EFAULT;
+}
diff --git a/arch/mips/kernel/cpu-bugs64.c b/arch/mips/kernel/cpu-bugs64.c
new file mode 100644
index 0000000..11ebe5d
--- /dev/null
+++ b/arch/mips/kernel/cpu-bugs64.c
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2003, 2004  Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/ptrace.h>
+#include <linux/stddef.h>
+
+#include <asm/bugs.h>
+#include <asm/compiler.h>
+#include <asm/cpu.h>
+#include <asm/fpu.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+static inline void align_mod(const int align, const int mod)
+{
+	asm volatile(
+		".set	push\n\t"
+		".set	noreorder\n\t"
+		".balign %0\n\t"
+		".rept	%1\n\t"
+		"nop\n\t"
+		".endr\n\t"
+		".set	pop"
+		:
+		: "n" (align), "n" (mod));
+}
+
+static inline void mult_sh_align_mod(long *v1, long *v2, long *w,
+				     const int align, const int mod)
+{
+	unsigned long flags;
+	int m1, m2;
+	long p, s, lv1, lv2, lw;
+
+	/*
+	 * We want the multiply and the shift to be isolated from the
+	 * rest of the code to disable gcc optimizations.  Hence the
+	 * asm statements that execute nothing, but make gcc not know
+	 * what the values of m1, m2 and s are and what lv2 and p are
+	 * used for.
+	 */
+
+	local_irq_save(flags);
+	/*
+	 * The following code leads to a wrong result of the first
+	 * dsll32 when executed on R4000 rev. 2.2 or 3.0 (PRId
+	 * 00000422 or 00000430, respectively).
+	 *
+	 * See "MIPS R4000PC/SC Errata, Processor Revision 2.2 and
+	 * 3.0" by MIPS Technologies, Inc., errata #16 and #28 for
+	 * details.  I got no permission to duplicate them here,
+	 * sigh... --macro
+	 */
+	asm volatile(
+		""
+		: "=r" (m1), "=r" (m2), "=r" (s)
+		: "0" (5), "1" (8), "2" (5));
+	align_mod(align, mod);
+	/*
+	 * The trailing nop is needed to fullfill the two-instruction
+	 * requirement between reading hi/lo and staring a mult/div.
+	 * Leaving it out may cause gas insert a nop itself breaking
+	 * the desired alignment of the next chunk.
+	 */
+	asm volatile(
+		".set	push\n\t"
+		".set	noat\n\t"
+		".set	noreorder\n\t"
+		".set	nomacro\n\t"
+		"mult	%2, %3\n\t"
+		"dsll32	%0, %4, %5\n\t"
+		"mflo	$0\n\t"
+		"dsll32	%1, %4, %5\n\t"
+		"nop\n\t"
+		".set	pop"
+		: "=&r" (lv1), "=r" (lw)
+		: "r" (m1), "r" (m2), "r" (s), "I" (0)
+		: "hi", "lo", GCC_REG_ACCUM);
+	/* We have to use single integers for m1 and m2 and a double
+	 * one for p to be sure the mulsidi3 gcc's RTL multiplication
+	 * instruction has the workaround applied.  Older versions of
+	 * gcc have correct umulsi3 and mulsi3, but other
+	 * multiplication variants lack the workaround.
+	 */
+	asm volatile(
+		""
+		: "=r" (m1), "=r" (m2), "=r" (s)
+		: "0" (m1), "1" (m2), "2" (s));
+	align_mod(align, mod);
+	p = m1 * m2;
+	lv2 = s << 32;
+	asm volatile(
+		""
+		: "=r" (lv2)
+		: "0" (lv2), "r" (p));
+	local_irq_restore(flags);
+
+	*v1 = lv1;
+	*v2 = lv2;
+	*w = lw;
+}
+
+static inline void check_mult_sh(void)
+{
+	long v1[8], v2[8], w[8];
+	int bug, fix, i;
+
+	printk("Checking for the multiply/shift bug... ");
+
+	/*
+	 * Testing discovered false negatives for certain code offsets
+	 * into cache lines.  Hence we test all possible offsets for
+	 * the worst assumption of an R4000 I-cache line width of 32
+	 * bytes.
+	 *
+	 * We can't use a loop as alignment directives need to be
+	 * immediates.
+	 */
+	mult_sh_align_mod(&v1[0], &v2[0], &w[0], 32, 0);
+	mult_sh_align_mod(&v1[1], &v2[1], &w[1], 32, 1);
+	mult_sh_align_mod(&v1[2], &v2[2], &w[2], 32, 2);
+	mult_sh_align_mod(&v1[3], &v2[3], &w[3], 32, 3);
+	mult_sh_align_mod(&v1[4], &v2[4], &w[4], 32, 4);
+	mult_sh_align_mod(&v1[5], &v2[5], &w[5], 32, 5);
+	mult_sh_align_mod(&v1[6], &v2[6], &w[6], 32, 6);
+	mult_sh_align_mod(&v1[7], &v2[7], &w[7], 32, 7);
+
+	bug = 0;
+	for (i = 0; i < 8; i++)
+		if (v1[i] != w[i])
+			bug = 1;
+		
+	if (bug == 0) {
+		printk("no.\n");
+		return;
+	}
+
+	printk("yes, workaround... ");
+
+	fix = 1;
+	for (i = 0; i < 8; i++)
+		if (v2[i] != w[i])
+			fix = 0;
+		
+	if (fix == 1) {
+		printk("yes.\n");
+		return;
+	}
+
+	printk("no.\n");
+	panic("Reliable operation impossible!\n"
+#ifndef CONFIG_CPU_R4000
+	      "Configure for R4000 to enable the workaround."
+#else
+	      "Please report to <linux-mips@linux-mips.org>."
+#endif
+	      );
+}
+
+static volatile int daddi_ov __initdata = 0;
+
+asmlinkage void __init do_daddi_ov(struct pt_regs *regs)
+{
+	daddi_ov = 1;
+	regs->cp0_epc += 4;
+}
+
+static inline void check_daddi(void)
+{
+	extern asmlinkage void handle_daddi_ov(void);
+	unsigned long flags;
+	void *handler;
+	long v, tmp;
+
+	printk("Checking for the daddi bug... ");
+
+	local_irq_save(flags);
+	handler = set_except_vector(12, handle_daddi_ov);
+	/*
+	 * The following code fails to trigger an overflow exception
+	 * when executed on R4000 rev. 2.2 or 3.0 (PRId 00000422 or
+	 * 00000430, respectively).
+	 *
+	 * See "MIPS R4000PC/SC Errata, Processor Revision 2.2 and
+	 * 3.0" by MIPS Technologies, Inc., erratum #23 for details.
+	 * I got no permission to duplicate it here, sigh... --macro
+	 */
+	asm volatile(
+		".set	push\n\t"
+		".set	noat\n\t"
+		".set	noreorder\n\t"
+		".set	nomacro\n\t"
+		"addiu	%1, $0, %2\n\t"
+		"dsrl	%1, %1, 1\n\t"
+#ifdef HAVE_AS_SET_DADDI
+		".set	daddi\n\t"
+#endif
+		"daddi	%0, %1, %3\n\t"
+		".set	pop"
+		: "=r" (v), "=&r" (tmp)
+		: "I" (0xffffffffffffdb9a), "I" (0x1234));
+	set_except_vector(12, handler);
+	local_irq_restore(flags);
+
+	if (daddi_ov) {
+		printk("no.\n");
+		return;
+	}
+
+	printk("yes, workaround... ");
+
+	local_irq_save(flags);
+	handler = set_except_vector(12, handle_daddi_ov);
+	asm volatile(
+		"addiu	%1, $0, %2\n\t"
+		"dsrl	%1, %1, 1\n\t"
+		"daddi	%0, %1, %3"
+		: "=r" (v), "=&r" (tmp)
+		: "I" (0xffffffffffffdb9a), "I" (0x1234));
+	set_except_vector(12, handler);
+	local_irq_restore(flags);
+
+	if (daddi_ov) {
+		printk("yes.\n");
+		return;
+	}
+
+	printk("no.\n");
+	panic("Reliable operation impossible!\n"
+#if !defined(CONFIG_CPU_R4000) && !defined(CONFIG_CPU_R4400)
+	      "Configure for R4000 or R4400 to enable the workaround."
+#else
+	      "Please report to <linux-mips@linux-mips.org>."
+#endif
+	      );
+}
+
+static inline void check_daddiu(void)
+{
+	long v, w, tmp;
+
+	printk("Checking for the daddiu bug... ");
+
+	/*
+	 * The following code leads to a wrong result of daddiu when
+	 * executed on R4400 rev. 1.0 (PRId 00000440).
+	 *
+	 * See "MIPS R4400PC/SC Errata, Processor Revision 1.0" by
+	 * MIPS Technologies, Inc., erratum #7 for details.
+	 *
+	 * According to "MIPS R4000PC/SC Errata, Processor Revision
+	 * 2.2 and 3.0" by MIPS Technologies, Inc., erratum #41 this
+	 * problem affects R4000 rev. 2.2 and 3.0 (PRId 00000422 and
+	 * 00000430, respectively), too.  Testing failed to trigger it
+	 * so far.
+	 *
+	 * I got no permission to duplicate the errata here, sigh...
+	 * --macro
+	 */
+	asm volatile(
+		".set	push\n\t"
+		".set	noat\n\t"
+		".set	noreorder\n\t"
+		".set	nomacro\n\t"
+		"addiu	%2, $0, %3\n\t"
+		"dsrl	%2, %2, 1\n\t"
+#ifdef HAVE_AS_SET_DADDI
+		".set	daddi\n\t"
+#endif
+		"daddiu	%0, %2, %4\n\t"
+		"addiu	%1, $0, %4\n\t"
+		"daddu	%1, %2\n\t"
+		".set	pop"
+		: "=&r" (v), "=&r" (w), "=&r" (tmp)
+		: "I" (0xffffffffffffdb9a), "I" (0x1234));
+
+	if (v == w) {
+		printk("no.\n");
+		return;
+	}
+
+	printk("yes, workaround... ");
+
+	asm volatile(
+		"addiu	%2, $0, %3\n\t"
+		"dsrl	%2, %2, 1\n\t"
+		"daddiu	%0, %2, %4\n\t"
+		"addiu	%1, $0, %4\n\t"
+		"daddu	%1, %2"
+		: "=&r" (v), "=&r" (w), "=&r" (tmp)
+		: "I" (0xffffffffffffdb9a), "I" (0x1234));
+
+	if (v == w) {
+		printk("yes.\n");
+		return;
+	}
+
+	printk("no.\n");
+	panic("Reliable operation impossible!\n"
+#if !defined(CONFIG_CPU_R4000) && !defined(CONFIG_CPU_R4400)
+	      "Configure for R4000 or R4400 to enable the workaround."
+#else
+	      "Please report to <linux-mips@linux-mips.org>."
+#endif
+	      );
+}
+
+void __init check_bugs64(void)
+{
+	check_mult_sh();
+	check_daddi();
+	check_daddiu();
+}
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
new file mode 100644
index 0000000..4bb8495
--- /dev/null
+++ b/arch/mips/kernel/cpu-probe.c
@@ -0,0 +1,598 @@
+/*
+ * Processor capabilities determination functions.
+ *
+ * Copyright (C) xxxx  the Anonymous
+ * Copyright (C) 2003  Maciej W. Rozycki
+ * Copyright (C) 1994 - 2003 Ralf Baechle
+ * Copyright (C) 2001 MIPS Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/ptrace.h>
+#include <linux/stddef.h>
+
+#include <asm/bugs.h>
+#include <asm/cpu.h>
+#include <asm/fpu.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+/*
+ * Not all of the MIPS CPUs have the "wait" instruction available. Moreover,
+ * the implementation of the "wait" feature differs between CPU families. This
+ * points to the function that implements CPU specific wait.
+ * The wait instruction stops the pipeline and reduces the power consumption of
+ * the CPU very much.
+ */
+void (*cpu_wait)(void) = NULL;
+
+static void r3081_wait(void)
+{
+	unsigned long cfg = read_c0_conf();
+	write_c0_conf(cfg | R30XX_CONF_HALT);
+}
+
+static void r39xx_wait(void)
+{
+	unsigned long cfg = read_c0_conf();
+	write_c0_conf(cfg | TX39_CONF_HALT);
+}
+
+static void r4k_wait(void)
+{
+	__asm__(".set\tmips3\n\t"
+		"wait\n\t"
+		".set\tmips0");
+}
+
+/*
+ * The Au1xxx wait is available only if we run CONFIG_PM and
+ * the timer setup found we had a 32KHz counter available.
+ * There are still problems with functions that may call au1k_wait
+ * directly, but that will be discovered pretty quickly.
+ */
+extern void (*au1k_wait_ptr)(void);
+
+void au1k_wait(void)
+{
+#ifdef CONFIG_PM
+	/* using the wait instruction makes CP0 counter unusable */
+	__asm__(".set\tmips3\n\t"
+		"wait\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		".set\tmips0");
+#else
+	__asm__("nop\n\t"
+		"nop");
+#endif
+}
+
+static inline void check_wait(void)
+{
+	struct cpuinfo_mips *c = &current_cpu_data;
+
+	printk("Checking for 'wait' instruction... ");
+	switch (c->cputype) {
+	case CPU_R3081:
+	case CPU_R3081E:
+		cpu_wait = r3081_wait;
+		printk(" available.\n");
+		break;
+	case CPU_TX3927:
+		cpu_wait = r39xx_wait;
+		printk(" available.\n");
+		break;
+	case CPU_R4200:
+/*	case CPU_R4300: */
+	case CPU_R4600:
+	case CPU_R4640:
+	case CPU_R4650:
+	case CPU_R4700:
+	case CPU_R5000:
+	case CPU_NEVADA:
+	case CPU_RM7000:
+	case CPU_RM9000:
+	case CPU_TX49XX:
+	case CPU_4KC:
+	case CPU_4KEC:
+	case CPU_4KSC:
+	case CPU_5KC:
+/*	case CPU_20KC:*/
+	case CPU_24K:
+	case CPU_25KF:
+		cpu_wait = r4k_wait;
+		printk(" available.\n");
+		break;
+#ifdef CONFIG_PM
+	case CPU_AU1000:
+	case CPU_AU1100:
+	case CPU_AU1500:
+		if (au1k_wait_ptr != NULL) {
+			cpu_wait = au1k_wait_ptr;
+			printk(" available.\n");
+		}
+		else {
+			printk(" unavailable.\n");
+		}
+		break;
+#endif
+	default:
+		printk(" unavailable.\n");
+		break;
+	}
+}
+
+void __init check_bugs32(void)
+{
+	check_wait();
+}
+
+/*
+ * Probe whether cpu has config register by trying to play with
+ * alternate cache bit and see whether it matters.
+ * It's used by cpu_probe to distinguish between R3000A and R3081.
+ */
+static inline int cpu_has_confreg(void)
+{
+#ifdef CONFIG_CPU_R3000
+	extern unsigned long r3k_cache_size(unsigned long);
+	unsigned long size1, size2;
+	unsigned long cfg = read_c0_conf();
+
+	size1 = r3k_cache_size(ST0_ISC);
+	write_c0_conf(cfg ^ R30XX_CONF_AC);
+	size2 = r3k_cache_size(ST0_ISC);
+	write_c0_conf(cfg);
+	return size1 != size2;
+#else
+	return 0;
+#endif
+}
+
+/*
+ * Get the FPU Implementation/Revision.
+ */
+static inline unsigned long cpu_get_fpu_id(void)
+{
+	unsigned long tmp, fpu_id;
+
+	tmp = read_c0_status();
+	__enable_fpu();
+	fpu_id = read_32bit_cp1_register(CP1_REVISION);
+	write_c0_status(tmp);
+	return fpu_id;
+}
+
+/*
+ * Check the CPU has an FPU the official way.
+ */
+static inline int __cpu_has_fpu(void)
+{
+	return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE);
+}
+
+#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \
+		| MIPS_CPU_COUNTER)
+
+static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
+{
+	switch (c->processor_id & 0xff00) {
+	case PRID_IMP_R2000:
+		c->cputype = CPU_R2000;
+		c->isa_level = MIPS_CPU_ISA_I;
+		c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX;
+		if (__cpu_has_fpu())
+			c->options |= MIPS_CPU_FPU;
+		c->tlbsize = 64;
+		break;
+	case PRID_IMP_R3000:
+		if ((c->processor_id & 0xff) == PRID_REV_R3000A)
+			if (cpu_has_confreg())
+				c->cputype = CPU_R3081E;
+			else
+				c->cputype = CPU_R3000A;
+		else
+			c->cputype = CPU_R3000;
+		c->isa_level = MIPS_CPU_ISA_I;
+		c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX;
+		if (__cpu_has_fpu())
+			c->options |= MIPS_CPU_FPU;
+		c->tlbsize = 64;
+		break;
+	case PRID_IMP_R4000:
+		if (read_c0_config() & CONF_SC) {
+			if ((c->processor_id & 0xff) >= PRID_REV_R4400)
+				c->cputype = CPU_R4400PC;
+			else
+				c->cputype = CPU_R4000PC;
+		} else {
+			if ((c->processor_id & 0xff) >= PRID_REV_R4400)
+				c->cputype = CPU_R4400SC;
+			else
+				c->cputype = CPU_R4000SC;
+		}
+
+		c->isa_level = MIPS_CPU_ISA_III;
+		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
+		             MIPS_CPU_WATCH | MIPS_CPU_VCE |
+		             MIPS_CPU_LLSC;
+		c->tlbsize = 48;
+		break;
+	case PRID_IMP_VR41XX:
+		switch (c->processor_id & 0xf0) {
+#ifndef CONFIG_VR4181
+		case PRID_REV_VR4111:
+			c->cputype = CPU_VR4111;
+			break;
+#else
+		case PRID_REV_VR4181:
+			c->cputype = CPU_VR4181;
+			break;
+#endif
+		case PRID_REV_VR4121:
+			c->cputype = CPU_VR4121;
+			break;
+		case PRID_REV_VR4122:
+			if ((c->processor_id & 0xf) < 0x3)
+				c->cputype = CPU_VR4122;
+			else
+				c->cputype = CPU_VR4181A;
+			break;
+		case PRID_REV_VR4130:
+			if ((c->processor_id & 0xf) < 0x4)
+				c->cputype = CPU_VR4131;
+			else
+				c->cputype = CPU_VR4133;
+			break;
+		default:
+			printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
+			c->cputype = CPU_VR41XX;
+			break;
+		}
+		c->isa_level = MIPS_CPU_ISA_III;
+		c->options = R4K_OPTS;
+		c->tlbsize = 32;
+		break;
+	case PRID_IMP_R4300:
+		c->cputype = CPU_R4300;
+		c->isa_level = MIPS_CPU_ISA_III;
+		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
+		             MIPS_CPU_LLSC;
+		c->tlbsize = 32;
+		break;
+	case PRID_IMP_R4600:
+		c->cputype = CPU_R4600;
+		c->isa_level = MIPS_CPU_ISA_III;
+		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC;
+		c->tlbsize = 48;
+		break;
+	#if 0
+ 	case PRID_IMP_R4650:
+		/*
+		 * This processor doesn't have an MMU, so it's not
+		 * "real easy" to run Linux on it. It is left purely
+		 * for documentation.  Commented out because it shares
+		 * it's c0_prid id number with the TX3900.
+		 */
+ 		c->cputype = CPU_R4650;
+	 	c->isa_level = MIPS_CPU_ISA_III;
+		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC;
+	        c->tlbsize = 48;
+		break;
+	#endif
+	case PRID_IMP_TX39:
+		c->isa_level = MIPS_CPU_ISA_I;
+		c->options = MIPS_CPU_TLB;
+
+		if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) {
+			c->cputype = CPU_TX3927;
+			c->tlbsize = 64;
+		} else {
+			switch (c->processor_id & 0xff) {
+			case PRID_REV_TX3912:
+				c->cputype = CPU_TX3912;
+				c->tlbsize = 32;
+				break;
+			case PRID_REV_TX3922:
+				c->cputype = CPU_TX3922;
+				c->tlbsize = 64;
+				break;
+			default:
+				c->cputype = CPU_UNKNOWN;
+				break;
+			}
+		}
+		break;
+	case PRID_IMP_R4700:
+		c->cputype = CPU_R4700;
+		c->isa_level = MIPS_CPU_ISA_III;
+		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
+		             MIPS_CPU_LLSC;
+		c->tlbsize = 48;
+		break;
+	case PRID_IMP_TX49:
+		c->cputype = CPU_TX49XX;
+		c->isa_level = MIPS_CPU_ISA_III;
+		c->options = R4K_OPTS | MIPS_CPU_LLSC;
+		if (!(c->processor_id & 0x08))
+			c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR;
+		c->tlbsize = 48;
+		break;
+	case PRID_IMP_R5000:
+		c->cputype = CPU_R5000;
+		c->isa_level = MIPS_CPU_ISA_IV;
+		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
+		             MIPS_CPU_LLSC;
+		c->tlbsize = 48;
+		break;
+	case PRID_IMP_R5432:
+		c->cputype = CPU_R5432;
+		c->isa_level = MIPS_CPU_ISA_IV;
+		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
+		             MIPS_CPU_WATCH | MIPS_CPU_LLSC;
+		c->tlbsize = 48;
+		break;
+	case PRID_IMP_R5500:
+		c->cputype = CPU_R5500;
+		c->isa_level = MIPS_CPU_ISA_IV;
+		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
+		             MIPS_CPU_WATCH | MIPS_CPU_LLSC;
+		c->tlbsize = 48;
+		break;
+	case PRID_IMP_NEVADA:
+		c->cputype = CPU_NEVADA;
+		c->isa_level = MIPS_CPU_ISA_IV;
+		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
+		             MIPS_CPU_DIVEC | MIPS_CPU_LLSC;
+		c->tlbsize = 48;
+		break;
+	case PRID_IMP_R6000:
+		c->cputype = CPU_R6000;
+		c->isa_level = MIPS_CPU_ISA_II;
+		c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
+		             MIPS_CPU_LLSC;
+		c->tlbsize = 32;
+		break;
+	case PRID_IMP_R6000A:
+		c->cputype = CPU_R6000A;
+		c->isa_level = MIPS_CPU_ISA_II;
+		c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
+		             MIPS_CPU_LLSC;
+		c->tlbsize = 32;
+		break;
+	case PRID_IMP_RM7000:
+		c->cputype = CPU_RM7000;
+		c->isa_level = MIPS_CPU_ISA_IV;
+		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
+		             MIPS_CPU_LLSC;
+		/*
+		 * Undocumented RM7000:  Bit 29 in the info register of
+		 * the RM7000 v2.0 indicates if the TLB has 48 or 64
+		 * entries.
+		 *
+		 * 29      1 =>    64 entry JTLB
+		 *         0 =>    48 entry JTLB
+		 */
+		c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48;
+		break;
+	case PRID_IMP_RM9000:
+		c->cputype = CPU_RM9000;
+		c->isa_level = MIPS_CPU_ISA_IV;
+		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
+		             MIPS_CPU_LLSC;
+		/*
+		 * Bit 29 in the info register of the RM9000
+		 * indicates if the TLB has 48 or 64 entries.
+		 *
+		 * 29      1 =>    64 entry JTLB
+		 *         0 =>    48 entry JTLB
+		 */
+		c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48;
+		break;
+	case PRID_IMP_R8000:
+		c->cputype = CPU_R8000;
+		c->isa_level = MIPS_CPU_ISA_IV;
+		c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+		             MIPS_CPU_FPU | MIPS_CPU_32FPR |
+		             MIPS_CPU_LLSC;
+		c->tlbsize = 384;      /* has weird TLB: 3-way x 128 */
+		break;
+	case PRID_IMP_R10000:
+		c->cputype = CPU_R10000;
+		c->isa_level = MIPS_CPU_ISA_IV;
+		c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+		             MIPS_CPU_FPU | MIPS_CPU_32FPR |
+			     MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
+		             MIPS_CPU_LLSC;
+		c->tlbsize = 64;
+		break;
+	case PRID_IMP_R12000:
+		c->cputype = CPU_R12000;
+		c->isa_level = MIPS_CPU_ISA_IV;
+		c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+		             MIPS_CPU_FPU | MIPS_CPU_32FPR |
+			     MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
+		             MIPS_CPU_LLSC;
+		c->tlbsize = 64;
+		break;
+	}
+}
+
+static inline void decode_config1(struct cpuinfo_mips *c)
+{
+	unsigned long config0 = read_c0_config();
+	unsigned long config1;
+
+	if ((config0 & (1 << 31)) == 0)
+		return;			/* actually wort a panic() */
+
+	/* MIPS32 or MIPS64 compliant CPU. Read Config 1 register. */
+	c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+		MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC |
+		MIPS_CPU_LLSC | MIPS_CPU_MCHECK;
+	config1 = read_c0_config1();
+	if (config1 & (1 << 3))
+		c->options |= MIPS_CPU_WATCH;
+	if (config1 & (1 << 2))
+		c->options |= MIPS_CPU_MIPS16;
+	if (config1 & (1 << 1))
+		c->options |= MIPS_CPU_EJTAG;
+	if (config1 & 1) {
+		c->options |= MIPS_CPU_FPU;
+		c->options |= MIPS_CPU_32FPR;
+	}
+	c->scache.flags = MIPS_CACHE_NOT_PRESENT;
+
+	c->tlbsize = ((config1 >> 25) & 0x3f) + 1;
+}
+
+static inline void cpu_probe_mips(struct cpuinfo_mips *c)
+{
+	decode_config1(c);
+	switch (c->processor_id & 0xff00) {
+	case PRID_IMP_4KC:
+		c->cputype = CPU_4KC;
+		c->isa_level = MIPS_CPU_ISA_M32;
+		break;
+	case PRID_IMP_4KEC:
+		c->cputype = CPU_4KEC;
+		c->isa_level = MIPS_CPU_ISA_M32;
+		break;
+	case PRID_IMP_4KSC:
+		c->cputype = CPU_4KSC;
+		c->isa_level = MIPS_CPU_ISA_M32;
+		break;
+	case PRID_IMP_5KC:
+		c->cputype = CPU_5KC;
+		c->isa_level = MIPS_CPU_ISA_M64;
+		break;
+	case PRID_IMP_20KC:
+		c->cputype = CPU_20KC;
+		c->isa_level = MIPS_CPU_ISA_M64;
+		break;
+	case PRID_IMP_24K:
+		c->cputype = CPU_24K;
+		c->isa_level = MIPS_CPU_ISA_M32;
+		break;
+	case PRID_IMP_25KF:
+		c->cputype = CPU_25KF;
+		c->isa_level = MIPS_CPU_ISA_M64;
+		/* Probe for L2 cache */
+		c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
+		break;
+	}
+}
+
+static inline void cpu_probe_alchemy(struct cpuinfo_mips *c)
+{
+	decode_config1(c);
+	switch (c->processor_id & 0xff00) {
+	case PRID_IMP_AU1_REV1:
+	case PRID_IMP_AU1_REV2:
+		switch ((c->processor_id >> 24) & 0xff) {
+		case 0:
+ 			c->cputype = CPU_AU1000;
+			break;
+		case 1:
+			c->cputype = CPU_AU1500;
+			break;
+		case 2:
+			c->cputype = CPU_AU1100;
+			break;
+		case 3:
+			c->cputype = CPU_AU1550;
+			break;
+		default:
+			panic("Unknown Au Core!");
+			break;
+		}
+		c->isa_level = MIPS_CPU_ISA_M32;
+		break;
+	}
+}
+
+static inline void cpu_probe_sibyte(struct cpuinfo_mips *c)
+{
+	decode_config1(c);
+	switch (c->processor_id & 0xff00) {
+	case PRID_IMP_SB1:
+		c->cputype = CPU_SB1;
+		c->isa_level = MIPS_CPU_ISA_M64;
+		c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+		             MIPS_CPU_COUNTER | MIPS_CPU_DIVEC |
+		             MIPS_CPU_MCHECK | MIPS_CPU_EJTAG |
+		             MIPS_CPU_WATCH | MIPS_CPU_LLSC;
+#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS
+		/* FPU in pass1 is known to have issues. */
+		c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR;
+#endif
+		break;
+	}
+}
+
+static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c)
+{
+	decode_config1(c);
+	switch (c->processor_id & 0xff00) {
+	case PRID_IMP_SR71000:
+		c->cputype = CPU_SR71000;
+		c->isa_level = MIPS_CPU_ISA_M64;
+		c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+		             MIPS_CPU_4KTLB | MIPS_CPU_FPU |
+		             MIPS_CPU_COUNTER | MIPS_CPU_MCHECK;
+		c->scache.ways = 8;
+		c->tlbsize = 64;
+		break;
+	}
+}
+
+__init void cpu_probe(void)
+{
+	struct cpuinfo_mips *c = &current_cpu_data;
+
+	c->processor_id	= PRID_IMP_UNKNOWN;
+	c->fpu_id	= FPIR_IMP_NONE;
+	c->cputype	= CPU_UNKNOWN;
+
+	c->processor_id = read_c0_prid();
+	switch (c->processor_id & 0xff0000) {
+	case PRID_COMP_LEGACY:
+		cpu_probe_legacy(c);
+		break;
+	case PRID_COMP_MIPS:
+		cpu_probe_mips(c);
+		break;
+	case PRID_COMP_ALCHEMY:
+		cpu_probe_alchemy(c);
+		break;
+	case PRID_COMP_SIBYTE:
+		cpu_probe_sibyte(c);
+		break;
+
+	case PRID_COMP_SANDCRAFT:
+		cpu_probe_sandcraft(c);
+		break;
+	default:
+		c->cputype = CPU_UNKNOWN;
+	}
+	if (c->options & MIPS_CPU_FPU)
+		c->fpu_id = cpu_get_fpu_id();
+}
+
+__init void cpu_report(void)
+{
+	struct cpuinfo_mips *c = &current_cpu_data;
+
+	printk("CPU revision is: %08x\n", c->processor_id);
+	if (c->options & MIPS_CPU_FPU)
+		printk("FPU revision is: %08x\n", c->fpu_id);
+}
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
new file mode 100644
index 0000000..5eb4291
--- /dev/null
+++ b/arch/mips/kernel/entry.S
@@ -0,0 +1,155 @@
+/*
+ * 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) 1994 - 2000, 2001, 2003 Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ */
+#include <linux/config.h>
+
+#include <asm/asm.h>
+#include <asm/asmmacro.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+#include <asm/isadep.h>
+#include <asm/thread_info.h>
+#include <asm/war.h>
+
+#ifdef CONFIG_PREEMPT
+	.macro	preempt_stop reg=t0
+	.endm
+#else
+	.macro	preempt_stop reg=t0
+	local_irq_disable \reg
+	.endm
+#define resume_kernel	restore_all
+#endif
+
+	.text
+	.align	5
+FEXPORT(ret_from_exception)
+	preempt_stop
+FEXPORT(ret_from_irq)
+	LONG_L	t0, PT_STATUS(sp)		# returning to kernel mode?
+	andi	t0, t0, KU_USER
+	beqz	t0, resume_kernel
+
+FEXPORT(resume_userspace)
+	local_irq_disable	t0	# make sure we dont miss an
+					# interrupt setting need_resched
+					# between sampling and return
+	LONG_L	a2, TI_FLAGS($28)	# current->work
+	andi	a2, _TIF_WORK_MASK	# (ignoring syscall_trace)
+	bnez	a2, work_pending
+	j	restore_all
+
+#ifdef CONFIG_PREEMPT
+ENTRY(resume_kernel)
+	lw	t0, TI_PRE_COUNT($28)
+	bnez	t0, restore_all
+need_resched:
+	LONG_L	t0, TI_FLAGS($28)
+	andi	t1, t0, _TIF_NEED_RESCHED
+	beqz	t1, restore_all
+	LONG_L	t0, PT_STATUS(sp)		# Interrupts off?
+	andi	t0, 1
+	beqz	t0, restore_all
+	li	t0, PREEMPT_ACTIVE
+	sw	t0, TI_PRE_COUNT($28)
+	local_irq_enable t0
+	jal	schedule
+	sw	zero, TI_PRE_COUNT($28)
+	local_irq_disable t0
+	b	need_resched
+#endif
+
+FEXPORT(ret_from_fork)
+	jal	schedule_tail		# a0 = task_t *prev
+
+FEXPORT(syscall_exit)
+	local_irq_disable		# make sure need_resched and
+					# signals dont change between
+					# sampling and return
+	LONG_L	a2, TI_FLAGS($28)	# current->work
+	li	t0, _TIF_ALLWORK_MASK
+	and	t0, a2, t0
+	bnez	t0, syscall_exit_work
+
+FEXPORT(restore_all)			# restore full frame
+	.set	noat
+	RESTORE_TEMP
+	RESTORE_AT
+	RESTORE_STATIC
+FEXPORT(restore_partial)		# restore partial frame
+	RESTORE_SOME
+	RESTORE_SP_AND_RET
+	.set	at
+
+FEXPORT(work_pending)
+	andi	t0, a2, _TIF_NEED_RESCHED
+	beqz	t0, work_notifysig
+work_resched:
+	jal	schedule
+
+	local_irq_disable t0		# make sure need_resched and
+					# signals dont change between
+					# sampling and return
+	LONG_L	a2, TI_FLAGS($28)
+	andi	t0, a2, _TIF_WORK_MASK	# is there any work to be done
+					# other than syscall tracing?
+	beqz	t0, restore_all
+	andi	t0, a2, _TIF_NEED_RESCHED
+	bnez	t0, work_resched
+
+work_notifysig:				# deal with pending signals and
+					# notify-resume requests
+	move	a0, sp
+	li	a1, 0
+	jal	do_notify_resume	# a2 already loaded
+	j	restore_all
+
+FEXPORT(syscall_exit_work_partial)
+	SAVE_STATIC
+FEXPORT(syscall_exit_work)
+	LONG_L	t0, TI_FLAGS($28)
+	li	t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+	and	t0, t1
+	beqz	t0, work_pending	# trace bit is set
+	local_irq_enable		# could let do_syscall_trace()
+					# call schedule() instead
+	move	a0, sp
+	li	a1, 1
+	jal	do_syscall_trace
+	b	resume_userspace
+
+/*
+ * Common spurious interrupt handler.
+ */
+	.text
+	.align  5
+LEAF(spurious_interrupt)
+	/*
+	 * Someone tried to fool us by sending an interrupt but we
+	 * couldn't find a cause for it.
+	 */
+#ifdef CONFIG_SMP
+	lui     t1, %hi(irq_err_count)
+1:	ll      t0, %lo(irq_err_count)(t1)
+	addiu   t0, 1
+	sc      t0, %lo(irq_err_count)(t1)
+#if R10000_LLSC_WAR
+	beqzl	t0, 1b
+#else
+	beqz	t0, 1b
+#endif
+#else
+	lui     t1, %hi(irq_err_count)
+	lw      t0, %lo(irq_err_count)(t1)
+	addiu   t0, 1
+	sw      t0, %lo(irq_err_count)(t1)
+#endif
+	j	ret_from_irq
+	END(spurious_interrupt)
diff --git a/arch/mips/kernel/gdb-low.S b/arch/mips/kernel/gdb-low.S
new file mode 100644
index 0000000..ece6dda
--- /dev/null
+++ b/arch/mips/kernel/gdb-low.S
@@ -0,0 +1,370 @@
+/*
+ * gdb-low.S contains the low-level trap handler for the GDB stub.
+ *
+ * Copyright (C) 1995 Andreas Busse
+ */
+#include <linux/config.h>
+#include <linux/sys.h>
+
+#include <asm/asm.h>
+#include <asm/errno.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/gdb-stub.h>
+
+#ifdef CONFIG_MIPS32
+#define DMFC0	mfc0
+#define DMTC0	mtc0
+#define LDC1	lwc1
+#define SDC1	lwc1
+#endif
+#ifdef CONFIG_MIPS64
+#define DMFC0	dmfc0
+#define DMTC0	dmtc0
+#define LDC1	ldc1
+#define SDC1	ldc1
+#endif
+
+/*
+ * [jsun] We reserves about 2x GDB_FR_SIZE in stack.  The lower (addressed)
+ * part is used to store registers and passed to exception handler.
+ * The upper part is reserved for "call func" feature where gdb client
+ * saves some of the regs, setups call frame and passes args.
+ *
+ * A trace shows about 200 bytes are used to store about half of all regs.
+ * The rest should be big enough for frame setup and passing args.
+ */
+
+/*
+ * The low level trap handler
+ */
+		.align 	5
+		NESTED(trap_low, GDB_FR_SIZE, sp)
+ 		.set	noat
+		.set 	noreorder
+
+		mfc0	k0, CP0_STATUS
+		sll	k0, 3     		/* extract cu0 bit */
+		bltz	k0, 1f
+		move	k1, sp
+
+		/*
+		 * Called from user mode, go somewhere else.
+		 */
+		lui	k1, %hi(saved_vectors)
+		mfc0	k0, CP0_CAUSE
+		andi	k0, k0, 0x7c
+		add	k1, k1, k0
+		lw	k0, %lo(saved_vectors)(k1)
+		jr	k0
+		nop
+1:
+		move	k0, sp
+		subu	sp, k1, GDB_FR_SIZE*2	# see comment above
+		LONG_S	k0, GDB_FR_REG29(sp)
+		LONG_S	$2, GDB_FR_REG2(sp)
+
+/*
+ * First save the CP0 and special registers
+ */
+
+		mfc0	v0, CP0_STATUS
+		LONG_S	v0, GDB_FR_STATUS(sp)
+		mfc0	v0, CP0_CAUSE
+		LONG_S	v0, GDB_FR_CAUSE(sp)
+		DMFC0	v0, CP0_EPC
+		LONG_S	v0, GDB_FR_EPC(sp)
+		DMFC0	v0, CP0_BADVADDR
+		LONG_S	v0, GDB_FR_BADVADDR(sp)
+		mfhi	v0
+		LONG_S	v0, GDB_FR_HI(sp)
+		mflo	v0
+		LONG_S	v0, GDB_FR_LO(sp)
+
+/*
+ * Now the integer registers
+ */
+
+		LONG_S	zero, GDB_FR_REG0(sp)		/* I know... */
+		LONG_S	$1, GDB_FR_REG1(sp)
+		/* v0 already saved */
+		LONG_S	$3, GDB_FR_REG3(sp)
+		LONG_S	$4, GDB_FR_REG4(sp)
+		LONG_S	$5, GDB_FR_REG5(sp)
+		LONG_S	$6, GDB_FR_REG6(sp)
+		LONG_S	$7, GDB_FR_REG7(sp)
+		LONG_S	$8, GDB_FR_REG8(sp)
+		LONG_S	$9, GDB_FR_REG9(sp)
+		LONG_S	$10, GDB_FR_REG10(sp)
+		LONG_S	$11, GDB_FR_REG11(sp)
+		LONG_S	$12, GDB_FR_REG12(sp)
+		LONG_S	$13, GDB_FR_REG13(sp)
+		LONG_S	$14, GDB_FR_REG14(sp)
+		LONG_S	$15, GDB_FR_REG15(sp)
+		LONG_S	$16, GDB_FR_REG16(sp)
+		LONG_S	$17, GDB_FR_REG17(sp)
+		LONG_S	$18, GDB_FR_REG18(sp)
+		LONG_S	$19, GDB_FR_REG19(sp)
+		LONG_S	$20, GDB_FR_REG20(sp)
+		LONG_S	$21, GDB_FR_REG21(sp)
+		LONG_S	$22, GDB_FR_REG22(sp)
+		LONG_S	$23, GDB_FR_REG23(sp)
+		LONG_S	$24, GDB_FR_REG24(sp)
+		LONG_S	$25, GDB_FR_REG25(sp)
+		LONG_S	$26, GDB_FR_REG26(sp)
+		LONG_S	$27, GDB_FR_REG27(sp)
+		LONG_S	$28, GDB_FR_REG28(sp)
+		/* sp already saved */
+		LONG_S	$30, GDB_FR_REG30(sp)
+		LONG_S	$31, GDB_FR_REG31(sp)
+
+		CLI				/* disable interrupts */
+
+/*
+ * Followed by the floating point registers
+ */
+		mfc0	v0, CP0_STATUS		/* FPU enabled? */
+		srl	v0, v0, 16
+		andi	v0, v0, (ST0_CU1 >> 16)
+
+		beqz	v0,2f			/* disabled, skip */
+		 nop
+
+		SDC1	$0, GDB_FR_FPR0(sp)
+		SDC1	$1, GDB_FR_FPR1(sp)
+		SDC1	$2, GDB_FR_FPR2(sp)
+		SDC1	$3, GDB_FR_FPR3(sp)
+		SDC1	$4, GDB_FR_FPR4(sp)
+		SDC1	$5, GDB_FR_FPR5(sp)
+		SDC1	$6, GDB_FR_FPR6(sp)
+		SDC1	$7, GDB_FR_FPR7(sp)
+		SDC1	$8, GDB_FR_FPR8(sp)
+		SDC1	$9, GDB_FR_FPR9(sp)
+		SDC1	$10, GDB_FR_FPR10(sp)
+		SDC1	$11, GDB_FR_FPR11(sp)
+		SDC1	$12, GDB_FR_FPR12(sp)
+		SDC1	$13, GDB_FR_FPR13(sp)
+		SDC1	$14, GDB_FR_FPR14(sp)
+		SDC1	$15, GDB_FR_FPR15(sp)
+		SDC1	$16, GDB_FR_FPR16(sp)
+		SDC1	$17, GDB_FR_FPR17(sp)
+		SDC1	$18, GDB_FR_FPR18(sp)
+		SDC1	$19, GDB_FR_FPR19(sp)
+		SDC1	$20, GDB_FR_FPR20(sp)
+		SDC1	$21, GDB_FR_FPR21(sp)
+		SDC1	$22, GDB_FR_FPR22(sp)
+		SDC1	$23, GDB_FR_FPR23(sp)
+		SDC1	$24, GDB_FR_FPR24(sp)
+		SDC1	$25, GDB_FR_FPR25(sp)
+		SDC1	$26, GDB_FR_FPR26(sp)
+		SDC1	$27, GDB_FR_FPR27(sp)
+		SDC1	$28, GDB_FR_FPR28(sp)
+		SDC1	$29, GDB_FR_FPR29(sp)
+		SDC1	$30, GDB_FR_FPR30(sp)
+		SDC1	$31, GDB_FR_FPR31(sp)
+
+/*
+ * FPU control registers
+ */
+
+		cfc1	v0, CP1_STATUS
+		LONG_S	v0, GDB_FR_FSR(sp)
+		cfc1	v0, CP1_REVISION
+		LONG_S	v0, GDB_FR_FIR(sp)
+
+/*
+ * Current stack frame ptr
+ */
+
+2:
+		LONG_S	sp, GDB_FR_FRP(sp)
+
+/*
+ * CP0 registers (R4000/R4400 unused registers skipped)
+ */
+
+		mfc0	v0, CP0_INDEX
+		LONG_S	v0, GDB_FR_CP0_INDEX(sp)
+		mfc0	v0, CP0_RANDOM
+		LONG_S	v0, GDB_FR_CP0_RANDOM(sp)
+		DMFC0	v0, CP0_ENTRYLO0
+		LONG_S	v0, GDB_FR_CP0_ENTRYLO0(sp)
+		DMFC0	v0, CP0_ENTRYLO1
+		LONG_S	v0, GDB_FR_CP0_ENTRYLO1(sp)
+		DMFC0	v0, CP0_CONTEXT
+		LONG_S	v0, GDB_FR_CP0_CONTEXT(sp)
+		mfc0	v0, CP0_PAGEMASK
+		LONG_S	v0, GDB_FR_CP0_PAGEMASK(sp)
+		mfc0	v0, CP0_WIRED
+		LONG_S	v0, GDB_FR_CP0_WIRED(sp)
+		DMFC0	v0, CP0_ENTRYHI
+		LONG_S	v0, GDB_FR_CP0_ENTRYHI(sp)
+		mfc0	v0, CP0_PRID
+		LONG_S	v0, GDB_FR_CP0_PRID(sp)
+
+		.set	at
+
+/*
+ * Continue with the higher level handler
+ */
+
+		move	a0,sp
+
+		jal	handle_exception
+		 nop
+
+/*
+ * Restore all writable registers, in reverse order
+ */
+
+		.set	noat
+
+		LONG_L	v0, GDB_FR_CP0_ENTRYHI(sp)
+		LONG_L	v1, GDB_FR_CP0_WIRED(sp)
+		DMTC0	v0, CP0_ENTRYHI
+		mtc0	v1, CP0_WIRED
+		LONG_L	v0, GDB_FR_CP0_PAGEMASK(sp)
+		LONG_L	v1, GDB_FR_CP0_ENTRYLO1(sp)
+		mtc0	v0, CP0_PAGEMASK
+		DMTC0	v1, CP0_ENTRYLO1
+		LONG_L	v0, GDB_FR_CP0_ENTRYLO0(sp)
+		LONG_L	v1, GDB_FR_CP0_INDEX(sp)
+		DMTC0	v0, CP0_ENTRYLO0
+		LONG_L	v0, GDB_FR_CP0_CONTEXT(sp)
+		mtc0	v1, CP0_INDEX
+		DMTC0	v0, CP0_CONTEXT
+
+
+/*
+ * Next, the floating point registers
+ */
+		mfc0	v0, CP0_STATUS		/* check if the FPU is enabled */
+		srl	v0, v0, 16
+		andi	v0, v0, (ST0_CU1 >> 16)
+
+		beqz	v0, 3f			/* disabled, skip */
+		 nop
+
+		LDC1	$31, GDB_FR_FPR31(sp)
+		LDC1	$30, GDB_FR_FPR30(sp)
+		LDC1	$29, GDB_FR_FPR29(sp)
+		LDC1	$28, GDB_FR_FPR28(sp)
+		LDC1	$27, GDB_FR_FPR27(sp)
+		LDC1	$26, GDB_FR_FPR26(sp)
+		LDC1	$25, GDB_FR_FPR25(sp)
+		LDC1	$24, GDB_FR_FPR24(sp)
+		LDC1	$23, GDB_FR_FPR23(sp)
+		LDC1	$22, GDB_FR_FPR22(sp)
+		LDC1	$21, GDB_FR_FPR21(sp)
+		LDC1	$20, GDB_FR_FPR20(sp)
+		LDC1	$19, GDB_FR_FPR19(sp)
+		LDC1	$18, GDB_FR_FPR18(sp)
+		LDC1	$17, GDB_FR_FPR17(sp)
+		LDC1	$16, GDB_FR_FPR16(sp)
+		LDC1	$15, GDB_FR_FPR15(sp)
+		LDC1	$14, GDB_FR_FPR14(sp)
+		LDC1	$13, GDB_FR_FPR13(sp)
+		LDC1	$12, GDB_FR_FPR12(sp)
+		LDC1	$11, GDB_FR_FPR11(sp)
+		LDC1	$10, GDB_FR_FPR10(sp)
+		LDC1	$9, GDB_FR_FPR9(sp)
+		LDC1	$8, GDB_FR_FPR8(sp)
+		LDC1	$7, GDB_FR_FPR7(sp)
+		LDC1	$6, GDB_FR_FPR6(sp)
+		LDC1	$5, GDB_FR_FPR5(sp)
+		LDC1	$4, GDB_FR_FPR4(sp)
+		LDC1	$3, GDB_FR_FPR3(sp)
+		LDC1	$2, GDB_FR_FPR2(sp)
+		LDC1	$1, GDB_FR_FPR1(sp)
+		LDC1	$0, GDB_FR_FPR0(sp)
+
+/*
+ * Now the CP0 and integer registers
+ */
+
+3:
+		mfc0	t0, CP0_STATUS
+		ori	t0, 0x1f
+		xori	t0, 0x1f
+		mtc0	t0, CP0_STATUS
+
+		LONG_L	v0, GDB_FR_STATUS(sp)
+		LONG_L	v1, GDB_FR_EPC(sp)
+		mtc0	v0, CP0_STATUS
+		DMTC0	v1, CP0_EPC
+		LONG_L	v0, GDB_FR_HI(sp)
+		LONG_L	v1, GDB_FR_LO(sp)
+		mthi	v0
+		mtlo	v1
+		LONG_L	$31, GDB_FR_REG31(sp)
+		LONG_L	$30, GDB_FR_REG30(sp)
+		LONG_L	$28, GDB_FR_REG28(sp)
+		LONG_L	$27, GDB_FR_REG27(sp)
+		LONG_L	$26, GDB_FR_REG26(sp)
+		LONG_L	$25, GDB_FR_REG25(sp)
+		LONG_L	$24, GDB_FR_REG24(sp)
+		LONG_L	$23, GDB_FR_REG23(sp)
+		LONG_L	$22, GDB_FR_REG22(sp)
+		LONG_L	$21, GDB_FR_REG21(sp)
+		LONG_L	$20, GDB_FR_REG20(sp)
+		LONG_L	$19, GDB_FR_REG19(sp)
+		LONG_L	$18, GDB_FR_REG18(sp)
+		LONG_L	$17, GDB_FR_REG17(sp)
+		LONG_L	$16, GDB_FR_REG16(sp)
+		LONG_L	$15, GDB_FR_REG15(sp)
+		LONG_L	$14, GDB_FR_REG14(sp)
+		LONG_L	$13, GDB_FR_REG13(sp)
+		LONG_L	$12, GDB_FR_REG12(sp)
+		LONG_L	$11, GDB_FR_REG11(sp)
+		LONG_L	$10, GDB_FR_REG10(sp)
+		LONG_L	$9, GDB_FR_REG9(sp)
+		LONG_L	$8, GDB_FR_REG8(sp)
+		LONG_L	$7, GDB_FR_REG7(sp)
+		LONG_L	$6, GDB_FR_REG6(sp)
+		LONG_L	$5, GDB_FR_REG5(sp)
+		LONG_L	$4, GDB_FR_REG4(sp)
+		LONG_L	$3, GDB_FR_REG3(sp)
+		LONG_L	$2, GDB_FR_REG2(sp)
+		LONG_L	$1, GDB_FR_REG1(sp)
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+		LONG_L	k0, GDB_FR_EPC(sp)
+		LONG_L	$29, GDB_FR_REG29(sp)		/* Deallocate stack */
+		jr	k0
+		rfe
+#else
+		LONG_L	sp, GDB_FR_REG29(sp)		/* Deallocate stack */
+
+		.set	mips3
+		eret
+		.set	mips0
+#endif
+		.set	at
+		.set	reorder
+		END(trap_low)
+
+LEAF(kgdb_read_byte)
+4:		lb	t0, (a0)
+		sb	t0, (a1)
+		li	v0, 0
+		jr	ra
+		.section __ex_table,"a"
+		PTR	4b, kgdbfault
+		.previous
+		END(kgdb_read_byte)
+
+LEAF(kgdb_write_byte)
+5:		sb	a0, (a1)
+		li	v0, 0
+		jr	ra
+		.section __ex_table,"a"
+		PTR	5b, kgdbfault
+		.previous
+		END(kgdb_write_byte)
+
+		.type	kgdbfault@function
+		.ent	kgdbfault
+
+kgdbfault:	li	v0, -EFAULT
+		jr	ra
+		.end	kgdbfault
diff --git a/arch/mips/kernel/gdb-stub.c b/arch/mips/kernel/gdb-stub.c
new file mode 100644
index 0000000..2698893
--- /dev/null
+++ b/arch/mips/kernel/gdb-stub.c
@@ -0,0 +1,1091 @@
+/*
+ *  arch/mips/kernel/gdb-stub.c
+ *
+ *  Originally written by Glenn Engel, Lake Stevens Instrument Division
+ *
+ *  Contributed by HP Systems
+ *
+ *  Modified for SPARC by Stu Grossman, Cygnus Support.
+ *
+ *  Modified for Linux/MIPS (and MIPS in general) by Andreas Busse
+ *  Send complaints, suggestions etc. to <andy@waldorf-gmbh.de>
+ *
+ *  Copyright (C) 1995 Andreas Busse
+ *
+ *  Copyright (C) 2003 MontaVista Software Inc.
+ *  Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ */
+
+/*
+ *  To enable debugger support, two things need to happen.  One, a
+ *  call to set_debug_traps() is necessary in order to allow any breakpoints
+ *  or error conditions to be properly intercepted and reported to gdb.
+ *  Two, a breakpoint needs to be generated to begin communication.  This
+ *  is most easily accomplished by a call to breakpoint().  Breakpoint()
+ *  simulates a breakpoint by executing a BREAK instruction.
+ *
+ *
+ *    The following gdb commands are supported:
+ *
+ * command          function                               Return value
+ *
+ *    g             return the value of the CPU registers  hex data or ENN
+ *    G             set the value of the CPU registers     OK or ENN
+ *
+ *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
+ *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
+ *
+ *    c             Resume at current address              SNN   ( signal NN)
+ *    cAA..AA       Continue at address AA..AA             SNN
+ *
+ *    s             Step one instruction                   SNN
+ *    sAA..AA       Step one instruction from AA..AA       SNN
+ *
+ *    k             kill
+ *
+ *    ?             What was the last sigval ?             SNN   (signal NN)
+ *
+ *    bBB..BB	    Set baud rate to BB..BB		   OK or BNN, then sets
+ *							   baud rate
+ *
+ * All commands and responses are sent with a packet which includes a
+ * checksum.  A packet consists of
+ *
+ * $<packet info>#<checksum>.
+ *
+ * where
+ * <packet info> :: <characters representing the command or response>
+ * <checksum>    :: < two hex digits computed as modulo 256 sum of <packetinfo>>
+ *
+ * When a packet is received, it is first acknowledged with either '+' or '-'.
+ * '+' indicates a successful transfer.  '-' indicates a failed transfer.
+ *
+ * Example:
+ *
+ * Host:                  Reply:
+ * $m0,10#2a               +$00010203040506070809101112131415#42
+ *
+ *
+ *  ==============
+ *  MORE EXAMPLES:
+ *  ==============
+ *
+ *  For reference -- the following are the steps that one
+ *  company took (RidgeRun Inc) to get remote gdb debugging
+ *  going. In this scenario the host machine was a PC and the
+ *  target platform was a Galileo EVB64120A MIPS evaluation
+ *  board.
+ *
+ *  Step 1:
+ *  First download gdb-5.0.tar.gz from the internet.
+ *  and then build/install the package.
+ *
+ *  Example:
+ *    $ tar zxf gdb-5.0.tar.gz
+ *    $ cd gdb-5.0
+ *    $ ./configure --target=mips-linux-elf
+ *    $ make
+ *    $ install
+ *    $ which mips-linux-elf-gdb
+ *    /usr/local/bin/mips-linux-elf-gdb
+ *
+ *  Step 2:
+ *  Configure linux for remote debugging and build it.
+ *
+ *  Example:
+ *    $ cd ~/linux
+ *    $ make menuconfig <go to "Kernel Hacking" and turn on remote debugging>
+ *    $ make
+ *
+ *  Step 3:
+ *  Download the kernel to the remote target and start
+ *  the kernel running. It will promptly halt and wait
+ *  for the host gdb session to connect. It does this
+ *  since the "Kernel Hacking" option has defined
+ *  CONFIG_KGDB which in turn enables your calls
+ *  to:
+ *     set_debug_traps();
+ *     breakpoint();
+ *
+ *  Step 4:
+ *  Start the gdb session on the host.
+ *
+ *  Example:
+ *    $ mips-linux-elf-gdb vmlinux
+ *    (gdb) set remotebaud 115200
+ *    (gdb) target remote /dev/ttyS1
+ *    ...at this point you are connected to
+ *       the remote target and can use gdb
+ *       in the normal fasion. Setting
+ *       breakpoints, single stepping,
+ *       printing variables, etc.
+ */
+#include <linux/config.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/reboot.h>
+
+#include <asm/asm.h>
+#include <asm/cacheflush.h>
+#include <asm/mipsregs.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/gdb-stub.h>
+#include <asm/inst.h>
+
+/*
+ * external low-level support routines
+ */
+
+extern int putDebugChar(char c);    /* write a single character      */
+extern char getDebugChar(void);     /* read and return a single char */
+extern void trap_low(void);
+
+/*
+ * breakpoint and test functions
+ */
+extern void breakpoint(void);
+extern void breakinst(void);
+extern void async_breakpoint(void);
+extern void async_breakinst(void);
+extern void adel(void);
+
+/*
+ * local prototypes
+ */
+
+static void getpacket(char *buffer);
+static void putpacket(char *buffer);
+static int computeSignal(int tt);
+static int hex(unsigned char ch);
+static int hexToInt(char **ptr, int *intValue);
+static int hexToLong(char **ptr, long *longValue);
+static unsigned char *mem2hex(char *mem, char *buf, int count, int may_fault);
+void handle_exception(struct gdb_regs *regs);
+
+int kgdb_enabled;
+
+/*
+ * spin locks for smp case
+ */
+static spinlock_t kgdb_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t kgdb_cpulock[NR_CPUS] = { [0 ... NR_CPUS-1] = SPIN_LOCK_UNLOCKED};
+
+/*
+ * BUFMAX defines the maximum number of characters in inbound/outbound buffers
+ * at least NUMREGBYTES*2 are needed for register packets
+ */
+#define BUFMAX 2048
+
+static char input_buffer[BUFMAX];
+static char output_buffer[BUFMAX];
+static int initialized;	/* !0 means we've been initialized */
+static int kgdb_started;
+static const char hexchars[]="0123456789abcdef";
+
+/* Used to prevent crashes in memory access.  Note that they'll crash anyway if
+   we haven't set up fault handlers yet... */
+int kgdb_read_byte(unsigned char *address, unsigned char *dest);
+int kgdb_write_byte(unsigned char val, unsigned char *dest);
+
+/*
+ * Convert ch from a hex digit to an int
+ */
+static int hex(unsigned char ch)
+{
+	if (ch >= 'a' && ch <= 'f')
+		return ch-'a'+10;
+	if (ch >= '0' && ch <= '9')
+		return ch-'0';
+	if (ch >= 'A' && ch <= 'F')
+		return ch-'A'+10;
+	return -1;
+}
+
+/*
+ * scan for the sequence $<data>#<checksum>
+ */
+static void getpacket(char *buffer)
+{
+	unsigned char checksum;
+	unsigned char xmitcsum;
+	int i;
+	int count;
+	unsigned char ch;
+
+	do {
+		/*
+		 * wait around for the start character,
+		 * ignore all other characters
+		 */
+		while ((ch = (getDebugChar() & 0x7f)) != '$') ;
+
+		checksum = 0;
+		xmitcsum = -1;
+		count = 0;
+
+		/*
+		 * now, read until a # or end of buffer is found
+		 */
+		while (count < BUFMAX) {
+			ch = getDebugChar();
+			if (ch == '#')
+				break;
+			checksum = checksum + ch;
+			buffer[count] = ch;
+			count = count + 1;
+		}
+
+		if (count >= BUFMAX)
+			continue;
+
+		buffer[count] = 0;
+
+		if (ch == '#') {
+			xmitcsum = hex(getDebugChar() & 0x7f) << 4;
+			xmitcsum |= hex(getDebugChar() & 0x7f);
+
+			if (checksum != xmitcsum)
+				putDebugChar('-');	/* failed checksum */
+			else {
+				putDebugChar('+'); /* successful transfer */
+
+				/*
+				 * if a sequence char is present,
+				 * reply the sequence ID
+				 */
+				if (buffer[2] == ':') {
+					putDebugChar(buffer[0]);
+					putDebugChar(buffer[1]);
+
+					/*
+					 * remove sequence chars from buffer
+					 */
+					count = strlen(buffer);
+					for (i=3; i <= count; i++)
+						buffer[i-3] = buffer[i];
+				}
+			}
+		}
+	}
+	while (checksum != xmitcsum);
+}
+
+/*
+ * send the packet in buffer.
+ */
+static void putpacket(char *buffer)
+{
+	unsigned char checksum;
+	int count;
+	unsigned char ch;
+
+	/*
+	 * $<packet info>#<checksum>.
+	 */
+
+	do {
+		putDebugChar('$');
+		checksum = 0;
+		count = 0;
+
+		while ((ch = buffer[count]) != 0) {
+			if (!(putDebugChar(ch)))
+				return;
+			checksum += ch;
+			count += 1;
+		}
+
+		putDebugChar('#');
+		putDebugChar(hexchars[checksum >> 4]);
+		putDebugChar(hexchars[checksum & 0xf]);
+
+	}
+	while ((getDebugChar() & 0x7f) != '+');
+}
+
+
+/*
+ * Convert the memory pointed to by mem into hex, placing result in buf.
+ * Return a pointer to the last char put in buf (null), in case of mem fault,
+ * return 0.
+ * may_fault is non-zero if we are reading from arbitrary memory, but is currently
+ * not used.
+ */
+static unsigned char *mem2hex(char *mem, char *buf, int count, int may_fault)
+{
+	unsigned char ch;
+
+	while (count-- > 0) {
+		if (kgdb_read_byte(mem++, &ch) != 0)
+			return 0;
+		*buf++ = hexchars[ch >> 4];
+		*buf++ = hexchars[ch & 0xf];
+	}
+
+	*buf = 0;
+
+	return buf;
+}
+
+/*
+ * convert the hex array pointed to by buf into binary to be placed in mem
+ * return a pointer to the character AFTER the last byte written
+ * may_fault is non-zero if we are reading from arbitrary memory, but is currently
+ * not used.
+ */
+static char *hex2mem(char *buf, char *mem, int count, int binary, int may_fault)
+{
+	int i;
+	unsigned char ch;
+
+	for (i=0; i<count; i++)
+	{
+		if (binary) {
+			ch = *buf++;
+			if (ch == 0x7d)
+				ch = 0x20 ^ *buf++;
+		}
+		else {
+			ch = hex(*buf++) << 4;
+			ch |= hex(*buf++);
+		}
+		if (kgdb_write_byte(ch, mem++) != 0)
+			return 0;
+	}
+
+	return mem;
+}
+
+/*
+ * This table contains the mapping between SPARC hardware trap types, and
+ * signals, which are primarily what GDB understands.  It also indicates
+ * which hardware traps we need to commandeer when initializing the stub.
+ */
+static struct hard_trap_info {
+	unsigned char tt;		/* Trap type code for MIPS R3xxx and R4xxx */
+	unsigned char signo;		/* Signal that we map this trap into */
+} hard_trap_info[] = {
+	{ 6, SIGBUS },			/* instruction bus error */
+	{ 7, SIGBUS },			/* data bus error */
+	{ 9, SIGTRAP },			/* break */
+	{ 10, SIGILL },			/* reserved instruction */
+/*	{ 11, SIGILL },		*/	/* CPU unusable */
+	{ 12, SIGFPE },			/* overflow */
+	{ 13, SIGTRAP },		/* trap */
+	{ 14, SIGSEGV },		/* virtual instruction cache coherency */
+	{ 15, SIGFPE },			/* floating point exception */
+	{ 23, SIGSEGV },		/* watch */
+	{ 31, SIGSEGV },		/* virtual data cache coherency */
+	{ 0, 0}				/* Must be last */
+};
+
+/* Save the normal trap handlers for user-mode traps. */
+void *saved_vectors[32];
+
+/*
+ * Set up exception handlers for tracing and breakpoints
+ */
+void set_debug_traps(void)
+{
+	struct hard_trap_info *ht;
+	unsigned long flags;
+	unsigned char c;
+
+	local_irq_save(flags);
+	for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
+		saved_vectors[ht->tt] = set_except_vector(ht->tt, trap_low);
+
+	putDebugChar('+'); /* 'hello world' */
+	/*
+	 * In case GDB is started before us, ack any packets
+	 * (presumably "$?#xx") sitting there.
+	 */
+	while((c = getDebugChar()) != '$');
+	while((c = getDebugChar()) != '#');
+	c = getDebugChar(); /* eat first csum byte */
+	c = getDebugChar(); /* eat second csum byte */
+	putDebugChar('+'); /* ack it */
+
+	initialized = 1;
+	local_irq_restore(flags);
+}
+
+void restore_debug_traps(void)
+{
+	struct hard_trap_info *ht;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
+		set_except_vector(ht->tt, saved_vectors[ht->tt]);
+	local_irq_restore(flags);
+}
+
+/*
+ * Convert the MIPS hardware trap type code to a Unix signal number.
+ */
+static int computeSignal(int tt)
+{
+	struct hard_trap_info *ht;
+
+	for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
+		if (ht->tt == tt)
+			return ht->signo;
+
+	return SIGHUP;		/* default for things we don't know about */
+}
+
+/*
+ * While we find nice hex chars, build an int.
+ * Return number of chars processed.
+ */
+static int hexToInt(char **ptr, int *intValue)
+{
+	int numChars = 0;
+	int hexValue;
+
+	*intValue = 0;
+
+	while (**ptr) {
+		hexValue = hex(**ptr);
+		if (hexValue < 0)
+			break;
+
+		*intValue = (*intValue << 4) | hexValue;
+		numChars ++;
+
+		(*ptr)++;
+	}
+
+	return (numChars);
+}
+
+static int hexToLong(char **ptr, long *longValue)
+{
+	int numChars = 0;
+	int hexValue;
+
+	*longValue = 0;
+
+	while (**ptr) {
+		hexValue = hex(**ptr);
+		if (hexValue < 0)
+			break;
+
+		*longValue = (*longValue << 4) | hexValue;
+		numChars ++;
+
+		(*ptr)++;
+	}
+
+	return numChars;
+}
+
+
+#if 0
+/*
+ * Print registers (on target console)
+ * Used only to debug the stub...
+ */
+void show_gdbregs(struct gdb_regs * regs)
+{
+	/*
+	 * Saved main processor registers
+	 */
+	printk("$0 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+	       regs->reg0, regs->reg1, regs->reg2, regs->reg3,
+               regs->reg4, regs->reg5, regs->reg6, regs->reg7);
+	printk("$8 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+	       regs->reg8, regs->reg9, regs->reg10, regs->reg11,
+               regs->reg12, regs->reg13, regs->reg14, regs->reg15);
+	printk("$16: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+	       regs->reg16, regs->reg17, regs->reg18, regs->reg19,
+               regs->reg20, regs->reg21, regs->reg22, regs->reg23);
+	printk("$24: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+	       regs->reg24, regs->reg25, regs->reg26, regs->reg27,
+	       regs->reg28, regs->reg29, regs->reg30, regs->reg31);
+
+	/*
+	 * Saved cp0 registers
+	 */
+	printk("epc  : %08lx\nStatus: %08lx\nCause : %08lx\n",
+	       regs->cp0_epc, regs->cp0_status, regs->cp0_cause);
+}
+#endif /* dead code */
+
+/*
+ * We single-step by setting breakpoints. When an exception
+ * is handled, we need to restore the instructions hoisted
+ * when the breakpoints were set.
+ *
+ * This is where we save the original instructions.
+ */
+static struct gdb_bp_save {
+	unsigned long addr;
+	unsigned int val;
+} step_bp[2];
+
+#define BP 0x0000000d  /* break opcode */
+
+/*
+ * Set breakpoint instructions for single stepping.
+ */
+static void single_step(struct gdb_regs *regs)
+{
+	union mips_instruction insn;
+	unsigned long targ;
+	int is_branch, is_cond, i;
+
+	targ = regs->cp0_epc;
+	insn.word = *(unsigned int *)targ;
+	is_branch = is_cond = 0;
+
+	switch (insn.i_format.opcode) {
+	/*
+	 * jr and jalr are in r_format format.
+	 */
+	case spec_op:
+		switch (insn.r_format.func) {
+		case jalr_op:
+		case jr_op:
+			targ = *(&regs->reg0 + insn.r_format.rs);
+			is_branch = 1;
+			break;
+		}
+		break;
+
+	/*
+	 * This group contains:
+	 * bltz_op, bgez_op, bltzl_op, bgezl_op,
+	 * bltzal_op, bgezal_op, bltzall_op, bgezall_op.
+	 */
+	case bcond_op:
+		is_branch = is_cond = 1;
+		targ += 4 + (insn.i_format.simmediate << 2);
+		break;
+
+	/*
+	 * These are unconditional and in j_format.
+	 */
+	case jal_op:
+	case j_op:
+		is_branch = 1;
+		targ += 4;
+		targ >>= 28;
+		targ <<= 28;
+		targ |= (insn.j_format.target << 2);
+		break;
+
+	/*
+	 * These are conditional.
+	 */
+	case beq_op:
+	case beql_op:
+	case bne_op:
+	case bnel_op:
+	case blez_op:
+	case blezl_op:
+	case bgtz_op:
+	case bgtzl_op:
+	case cop0_op:
+	case cop1_op:
+	case cop2_op:
+	case cop1x_op:
+		is_branch = is_cond = 1;
+		targ += 4 + (insn.i_format.simmediate << 2);
+		break;
+	}
+
+	if (is_branch) {
+		i = 0;
+		if (is_cond && targ != (regs->cp0_epc + 8)) {
+			step_bp[i].addr = regs->cp0_epc + 8;
+			step_bp[i++].val = *(unsigned *)(regs->cp0_epc + 8);
+			*(unsigned *)(regs->cp0_epc + 8) = BP;
+		}
+		step_bp[i].addr = targ;
+		step_bp[i].val  = *(unsigned *)targ;
+		*(unsigned *)targ = BP;
+	} else {
+		step_bp[0].addr = regs->cp0_epc + 4;
+		step_bp[0].val  = *(unsigned *)(regs->cp0_epc + 4);
+		*(unsigned *)(regs->cp0_epc + 4) = BP;
+	}
+}
+
+/*
+ *  If asynchronously interrupted by gdb, then we need to set a breakpoint
+ *  at the interrupted instruction so that we wind up stopped with a
+ *  reasonable stack frame.
+ */
+static struct gdb_bp_save async_bp;
+
+/*
+ * Swap the interrupted EPC with our asynchronous breakpoint routine.
+ * This is safer than stuffing the breakpoint in-place, since no cache
+ * flushes (or resulting smp_call_functions) are required.  The
+ * assumption is that only one CPU will be handling asynchronous bp's,
+ * and only one can be active at a time.
+ */
+extern spinlock_t smp_call_lock;
+void set_async_breakpoint(unsigned long *epc)
+{
+	/* skip breaking into userland */
+	if ((*epc & 0x80000000) == 0)
+		return;
+
+	/* avoid deadlock if someone is make IPC */
+	if (spin_is_locked(&smp_call_lock))
+		return;
+
+	async_bp.addr = *epc;
+	*epc = (unsigned long)async_breakpoint;
+}
+
+void kgdb_wait(void *arg)
+{
+	unsigned flags;
+	int cpu = smp_processor_id();
+
+	local_irq_save(flags);
+
+	spin_lock(&kgdb_cpulock[cpu]);
+	spin_unlock(&kgdb_cpulock[cpu]);
+
+	local_irq_restore(flags);
+}
+
+
+/*
+ * This function does all command processing for interfacing to gdb.  It
+ * returns 1 if you should skip the instruction at the trap address, 0
+ * otherwise.
+ */
+void handle_exception (struct gdb_regs *regs)
+{
+	int trap;			/* Trap type */
+	int sigval;
+	long addr;
+	int length;
+	char *ptr;
+	unsigned long *stack;
+	int i;
+	int bflag = 0;
+
+	kgdb_started = 1;
+
+	/*
+	 * acquire the big kgdb spinlock
+	 */
+	if (!spin_trylock(&kgdb_lock)) {
+		/* 
+		 * some other CPU has the lock, we should go back to 
+		 * receive the gdb_wait IPC
+		 */
+		return;
+	}
+
+	/*
+	 * If we're in async_breakpoint(), restore the real EPC from
+	 * the breakpoint.
+	 */
+	if (regs->cp0_epc == (unsigned long)async_breakinst) {
+		regs->cp0_epc = async_bp.addr;
+		async_bp.addr = 0;
+	}
+
+	/* 
+	 * acquire the CPU spinlocks
+	 */
+	for (i = num_online_cpus()-1; i >= 0; i--)
+		if (spin_trylock(&kgdb_cpulock[i]) == 0)
+			panic("kgdb: couldn't get cpulock %d\n", i);
+
+	/*
+	 * force other cpus to enter kgdb
+	 */
+	smp_call_function(kgdb_wait, NULL, 0, 0);
+
+	/*
+	 * If we're in breakpoint() increment the PC
+	 */
+	trap = (regs->cp0_cause & 0x7c) >> 2;
+	if (trap == 9 && regs->cp0_epc == (unsigned long)breakinst)
+		regs->cp0_epc += 4;
+
+	/*
+	 * If we were single_stepping, restore the opcodes hoisted
+	 * for the breakpoint[s].
+	 */
+	if (step_bp[0].addr) {
+		*(unsigned *)step_bp[0].addr = step_bp[0].val;
+		step_bp[0].addr = 0;
+
+		if (step_bp[1].addr) {
+			*(unsigned *)step_bp[1].addr = step_bp[1].val;
+			step_bp[1].addr = 0;
+		}
+	}
+
+	stack = (long *)regs->reg29;			/* stack ptr */
+	sigval = computeSignal(trap);
+
+	/*
+	 * reply to host that an exception has occurred
+	 */
+	ptr = output_buffer;
+
+	/*
+	 * Send trap type (converted to signal)
+	 */
+	*ptr++ = 'T';
+	*ptr++ = hexchars[sigval >> 4];
+	*ptr++ = hexchars[sigval & 0xf];
+
+	/*
+	 * Send Error PC
+	 */
+	*ptr++ = hexchars[REG_EPC >> 4];
+	*ptr++ = hexchars[REG_EPC & 0xf];
+	*ptr++ = ':';
+	ptr = mem2hex((char *)&regs->cp0_epc, ptr, sizeof(long), 0);
+	*ptr++ = ';';
+
+	/*
+	 * Send frame pointer
+	 */
+	*ptr++ = hexchars[REG_FP >> 4];
+	*ptr++ = hexchars[REG_FP & 0xf];
+	*ptr++ = ':';
+	ptr = mem2hex((char *)&regs->reg30, ptr, sizeof(long), 0);
+	*ptr++ = ';';
+
+	/*
+	 * Send stack pointer
+	 */
+	*ptr++ = hexchars[REG_SP >> 4];
+	*ptr++ = hexchars[REG_SP & 0xf];
+	*ptr++ = ':';
+	ptr = mem2hex((char *)&regs->reg29, ptr, sizeof(long), 0);
+	*ptr++ = ';';
+
+	*ptr++ = 0;
+	putpacket(output_buffer);	/* send it off... */
+
+	/*
+	 * Wait for input from remote GDB
+	 */
+	while (1) {
+		output_buffer[0] = 0;
+		getpacket(input_buffer);
+
+		switch (input_buffer[0])
+		{
+		case '?':
+			output_buffer[0] = 'S';
+			output_buffer[1] = hexchars[sigval >> 4];
+			output_buffer[2] = hexchars[sigval & 0xf];
+			output_buffer[3] = 0;
+			break;
+
+		/*
+		 * Detach debugger; let CPU run
+		 */
+		case 'D':
+			putpacket(output_buffer);
+			goto finish_kgdb;
+			break;
+
+		case 'd':
+			/* toggle debug flag */
+			break;
+
+		/*
+		 * Return the value of the CPU registers
+		 */
+		case 'g':
+			ptr = output_buffer;
+			ptr = mem2hex((char *)&regs->reg0, ptr, 32*sizeof(long), 0); /* r0...r31 */
+			ptr = mem2hex((char *)&regs->cp0_status, ptr, 6*sizeof(long), 0); /* cp0 */
+			ptr = mem2hex((char *)&regs->fpr0, ptr, 32*sizeof(long), 0); /* f0...31 */
+			ptr = mem2hex((char *)&regs->cp1_fsr, ptr, 2*sizeof(long), 0); /* cp1 */
+			ptr = mem2hex((char *)&regs->frame_ptr, ptr, 2*sizeof(long), 0); /* frp */
+			ptr = mem2hex((char *)&regs->cp0_index, ptr, 16*sizeof(long), 0); /* cp0 */
+			break;
+
+		/*
+		 * set the value of the CPU registers - return OK
+		 */
+		case 'G':
+		{
+			ptr = &input_buffer[1];
+			hex2mem(ptr, (char *)&regs->reg0, 32*sizeof(long), 0, 0);
+			ptr += 32*(2*sizeof(long));
+			hex2mem(ptr, (char *)&regs->cp0_status, 6*sizeof(long), 0, 0);
+			ptr += 6*(2*sizeof(long));
+			hex2mem(ptr, (char *)&regs->fpr0, 32*sizeof(long), 0, 0);
+			ptr += 32*(2*sizeof(long));
+			hex2mem(ptr, (char *)&regs->cp1_fsr, 2*sizeof(long), 0, 0);
+			ptr += 2*(2*sizeof(long));
+			hex2mem(ptr, (char *)&regs->frame_ptr, 2*sizeof(long), 0, 0);
+			ptr += 2*(2*sizeof(long));
+			hex2mem(ptr, (char *)&regs->cp0_index, 16*sizeof(long), 0, 0);
+			strcpy(output_buffer,"OK");
+		 }
+		break;
+
+		/*
+		 * mAA..AA,LLLL  Read LLLL bytes at address AA..AA
+		 */
+		case 'm':
+			ptr = &input_buffer[1];
+
+			if (hexToLong(&ptr, &addr)
+				&& *ptr++ == ','
+				&& hexToInt(&ptr, &length)) {
+				if (mem2hex((char *)addr, output_buffer, length, 1))
+					break;
+				strcpy (output_buffer, "E03");
+			} else
+				strcpy(output_buffer,"E01");
+			break;
+
+		/*
+		 * XAA..AA,LLLL: Write LLLL escaped binary bytes at address AA.AA
+		 */
+		case 'X':
+			bflag = 1;
+			/* fall through */
+
+		/*
+		 * MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK
+		 */
+		case 'M':
+			ptr = &input_buffer[1];
+
+			if (hexToLong(&ptr, &addr)
+				&& *ptr++ == ','
+				&& hexToInt(&ptr, &length)
+				&& *ptr++ == ':') {
+				if (hex2mem(ptr, (char *)addr, length, bflag, 1))
+					strcpy(output_buffer, "OK");
+				else
+					strcpy(output_buffer, "E03");
+			}
+			else
+				strcpy(output_buffer, "E02");
+			break;
+
+		/*
+		 * cAA..AA    Continue at address AA..AA(optional)
+		 */
+		case 'c':
+			/* try to read optional parameter, pc unchanged if no parm */
+
+			ptr = &input_buffer[1];
+			if (hexToLong(&ptr, &addr))
+				regs->cp0_epc = addr;
+	  
+			goto exit_kgdb_exception;
+			break;
+
+		/*
+		 * kill the program; let us try to restart the machine
+		 * Reset the whole machine.
+		 */
+		case 'k':
+		case 'r':
+			machine_restart("kgdb restarts machine");
+			break;
+
+		/*
+		 * Step to next instruction
+		 */
+		case 's':
+			/*
+			 * There is no single step insn in the MIPS ISA, so we
+			 * use breakpoints and continue, instead.
+			 */
+			single_step(regs);
+			goto exit_kgdb_exception;
+			/* NOTREACHED */
+			break;
+
+		/*
+		 * Set baud rate (bBB)
+		 * FIXME: Needs to be written
+		 */
+		case 'b':
+		{
+#if 0
+			int baudrate;
+			extern void set_timer_3();
+
+			ptr = &input_buffer[1];
+			if (!hexToInt(&ptr, &baudrate))
+			{
+				strcpy(output_buffer,"B01");
+				break;
+			}
+
+			/* Convert baud rate to uart clock divider */
+
+			switch (baudrate)
+			{
+				case 38400:
+					baudrate = 16;
+					break;
+				case 19200:
+					baudrate = 33;
+					break;
+				case 9600:
+					baudrate = 65;
+					break;
+				default:
+					baudrate = 0;
+					strcpy(output_buffer,"B02");
+					goto x1;
+			}
+
+			if (baudrate) {
+				putpacket("OK");	/* Ack before changing speed */
+				set_timer_3(baudrate); /* Set it */
+			}
+#endif
+		}
+		break;
+
+		}			/* switch */
+
+		/*
+		 * reply to the request
+		 */
+
+		putpacket(output_buffer);
+
+	} /* while */
+
+	return;
+
+finish_kgdb:
+	restore_debug_traps();
+
+exit_kgdb_exception:
+	/* release locks so other CPUs can go */
+	for (i = num_online_cpus()-1; i >= 0; i--)
+		spin_unlock(&kgdb_cpulock[i]);
+	spin_unlock(&kgdb_lock);
+
+	__flush_cache_all();
+	return;
+}
+
+/*
+ * This function will generate a breakpoint exception.  It is used at the
+ * beginning of a program to sync up with a debugger and can be used
+ * otherwise as a quick means to stop program execution and "break" into
+ * the debugger.
+ */
+void breakpoint(void)
+{
+	if (!initialized)
+		return;
+
+	__asm__ __volatile__(
+			".globl	breakinst\n\t" 
+			".set\tnoreorder\n\t"
+			"nop\n"
+			"breakinst:\tbreak\n\t"
+			"nop\n\t"
+			".set\treorder"
+			);
+}
+
+/* Nothing but the break; don't pollute any registers */
+void async_breakpoint(void)
+{
+	__asm__ __volatile__(
+			".globl	async_breakinst\n\t" 
+			".set\tnoreorder\n\t"
+			"nop\n"
+			"async_breakinst:\tbreak\n\t"
+			"nop\n\t"
+			".set\treorder"
+			);
+}
+
+void adel(void)
+{
+	__asm__ __volatile__(
+			".globl\tadel\n\t"
+			"lui\t$8,0x8000\n\t"
+			"lw\t$9,1($8)\n\t"
+			);
+}
+
+/*
+ * malloc is needed by gdb client in "call func()", even a private one
+ * will make gdb happy
+ */
+static void *malloc(size_t size)
+{
+	return kmalloc(size, GFP_ATOMIC);
+}
+
+static void free(void *where)
+{
+	kfree(where);
+}
+
+#ifdef CONFIG_GDB_CONSOLE
+
+void gdb_putsn(const char *str, int l)
+{
+	char outbuf[18];
+
+	if (!kgdb_started)
+		return;
+
+	outbuf[0]='O';
+
+	while(l) {
+		int i = (l>8)?8:l;
+		mem2hex((char *)str, &outbuf[1], i, 0);
+		outbuf[(i*2)+1]=0;
+		putpacket(outbuf);
+		str += i;
+		l -= i;
+	}
+}
+
+static void gdb_console_write(struct console *con, const char *s, unsigned n)
+{
+	gdb_putsn(s, n);
+}
+
+static struct console gdb_console = {
+	.name	= "gdb",
+	.write	= gdb_console_write,
+	.flags	= CON_PRINTBUFFER,
+	.index	= -1
+};
+
+static int __init register_gdb_console(void)
+{
+	register_console(&gdb_console);
+
+	return 0;
+}
+
+console_initcall(register_gdb_console);
+
+#endif
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
new file mode 100644
index 0000000..a5b0a38
--- /dev/null
+++ b/arch/mips/kernel/genex.S
@@ -0,0 +1,302 @@
+/*
+ * 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) 1994 - 2000, 2001, 2003 Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ * Copyright (C) 2002 Maciej W. Rozycki
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/asm.h>
+#include <asm/cacheops.h>
+#include <asm/regdef.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+#include <asm/war.h>
+
+#define PANIC_PIC(msg)					\
+		.set push;				\
+		.set	reorder;			\
+		PTR_LA	a0,8f;				\
+		.set	noat;				\
+		PTR_LA	AT, panic;			\
+		jr	AT;				\
+9:		b	9b;				\
+		.set	pop;				\
+		TEXT(msg)
+
+	__INIT
+
+NESTED(except_vec0_generic, 0, sp)
+	PANIC_PIC("Exception vector 0 called")
+	END(except_vec0_generic)
+
+NESTED(except_vec1_generic, 0, sp)
+	PANIC_PIC("Exception vector 1 called")
+	END(except_vec1_generic)
+
+/*
+ * General exception vector for all other CPUs.
+ *
+ * Be careful when changing this, it has to be at most 128 bytes
+ * to fit into space reserved for the exception handler.
+ */
+NESTED(except_vec3_generic, 0, sp)
+	.set	push
+	.set	noat
+#if R5432_CP0_INTERRUPT_WAR
+	mfc0	k0, CP0_INDEX
+#endif
+	mfc0	k1, CP0_CAUSE
+	andi	k1, k1, 0x7c
+#ifdef CONFIG_MIPS64
+	dsll	k1, k1, 1
+#endif
+	PTR_L	k0, exception_handlers(k1)
+	jr	k0
+	.set	pop
+	END(except_vec3_generic)
+
+/*
+ * General exception handler for CPUs with virtual coherency exception.
+ *
+ * Be careful when changing this, it has to be at most 256 (as a special
+ * exception) bytes to fit into space reserved for the exception handler.
+ */
+NESTED(except_vec3_r4000, 0, sp)
+	.set	push
+	.set	mips3
+	.set	noat
+	mfc0	k1, CP0_CAUSE
+	li	k0, 31<<2
+	andi	k1, k1, 0x7c
+	.set	push
+	.set	noreorder
+	.set	nomacro
+	beq	k1, k0, handle_vced
+	 li	k0, 14<<2
+	beq	k1, k0, handle_vcei
+#ifdef CONFIG_MIPS64
+	dsll	k1, k1, 1
+#endif
+	.set	pop
+	PTR_L	k0, exception_handlers(k1)
+	jr	k0
+
+	/*
+	 * Big shit, we now may have two dirty primary cache lines for the same
+	 * physical address.  We can savely invalidate the line pointed to by
+	 * c0_badvaddr because after return from this exception handler the
+	 * load / store will be re-executed.
+	 */
+handle_vced:
+	DMFC0	k0, CP0_BADVADDR
+	li	k1, -4					# Is this ...
+	and	k0, k1					# ... really needed?
+	mtc0	zero, CP0_TAGLO
+	cache	Index_Store_Tag_D,(k0)
+	cache	Hit_Writeback_Inv_SD,(k0)
+#ifdef CONFIG_PROC_FS
+	PTR_LA	k0, vced_count
+	lw	k1, (k0)
+	addiu	k1, 1
+	sw	k1, (k0)
+#endif
+	eret
+
+handle_vcei:
+	MFC0	k0, CP0_BADVADDR
+	cache	Hit_Writeback_Inv_SD, (k0)		# also cleans pi
+#ifdef CONFIG_PROC_FS
+	PTR_LA	k0, vcei_count
+	lw	k1, (k0)
+	addiu	k1, 1
+	sw	k1, (k0)
+#endif
+	eret
+	.set	pop
+	END(except_vec3_r4000)
+
+/*
+ * Special interrupt vector for MIPS64 ISA & embedded MIPS processors.
+ * This is a dedicated interrupt exception vector which reduces the
+ * interrupt processing overhead.  The jump instruction will be replaced
+ * at the initialization time.
+ *
+ * Be careful when changing this, it has to be at most 128 bytes
+ * to fit into space reserved for the exception handler.
+ */
+NESTED(except_vec4, 0, sp)
+1:	j	1b			/* Dummy, will be replaced */
+	END(except_vec4)
+
+/*
+ * EJTAG debug exception handler.
+ * The EJTAG debug exception entry point is 0xbfc00480, which
+ * normally is in the boot PROM, so the boot PROM must do a
+ * unconditional jump to this vector.
+ */
+NESTED(except_vec_ejtag_debug, 0, sp)
+	j	ejtag_debug_handler
+	END(except_vec_ejtag_debug)
+
+	__FINIT
+
+/*
+ * EJTAG debug exception handler.
+ */
+NESTED(ejtag_debug_handler, PT_SIZE, sp)
+	.set	push
+	.set	noat
+	MTC0	k0, CP0_DESAVE
+	mfc0	k0, CP0_DEBUG
+
+	sll	k0, k0, 30	# Check for SDBBP.
+	bgez	k0, ejtag_return
+
+	PTR_LA	k0, ejtag_debug_buffer
+	LONG_S	k1, 0(k0)
+	SAVE_ALL
+	move	a0, sp
+	jal	ejtag_exception_handler
+	RESTORE_ALL
+	PTR_LA	k0, ejtag_debug_buffer
+	LONG_L	k1, 0(k0)
+
+ejtag_return:
+	MFC0	k0, CP0_DESAVE
+	.set	mips32
+	deret
+	.set pop
+	END(ejtag_debug_handler)
+
+/*
+ * This buffer is reserved for the use of the EJTAG debug
+ * handler.
+ */
+	.data
+EXPORT(ejtag_debug_buffer)
+	.fill	LONGSIZE
+	.previous
+
+	__INIT
+
+/*
+ * NMI debug exception handler for MIPS reference boards.
+ * The NMI debug exception entry point is 0xbfc00000, which
+ * normally is in the boot PROM, so the boot PROM must do a
+ * unconditional jump to this vector.
+ */
+NESTED(except_vec_nmi, 0, sp)
+	j	nmi_handler
+	END(except_vec_nmi)
+
+	__FINIT
+
+NESTED(nmi_handler, PT_SIZE, sp)
+	.set	push
+	.set	noat
+	.set	mips3
+	SAVE_ALL
+ 	move	a0, sp
+	jal	nmi_exception_handler
+	RESTORE_ALL
+	eret
+	.set	pop
+	END(nmi_handler)
+
+	.macro	__build_clear_none
+	.endm
+
+	.macro	__build_clear_sti
+	STI
+	.endm
+
+	.macro	__build_clear_cli
+	CLI
+	.endm
+
+	.macro	__build_clear_fpe
+	cfc1	a1, fcr31
+	li	a2, ~(0x3f << 12)
+	and	a2, a1
+	ctc1	a2, fcr31
+	STI
+	.endm
+
+	.macro	__build_clear_ade
+	MFC0	t0, CP0_BADVADDR
+	PTR_S	t0, PT_BVADDR(sp)
+	KMODE
+	.endm
+
+	.macro	__BUILD_silent exception
+	.endm
+
+	/* Gas tries to parse the PRINT argument as a string containing
+	   string escapes and emits bogus warnings if it believes to
+	   recognize an unknown escape code.  So make the arguments
+	   start with an n and gas will believe \n is ok ...  */
+	.macro	__BUILD_verbose	nexception
+	LONG_L	a1, PT_EPC(sp)
+#if CONFIG_MIPS32
+	PRINT("Got \nexception at %08lx\012")
+#endif	
+#if CONFIG_MIPS64
+	PRINT("Got \nexception at %016lx\012")
+#endif	
+	.endm
+
+	.macro	__BUILD_count exception
+	LONG_L	t0,exception_count_\exception
+	LONG_ADDIU t0, 1
+	LONG_S	t0,exception_count_\exception
+	.comm	exception_count\exception, 8, 8
+	.endm
+
+	.macro	__BUILD_HANDLER exception handler clear verbose ext
+	.align	5
+	NESTED(handle_\exception, PT_SIZE, sp)
+	.set	noat
+	SAVE_ALL
+	FEXPORT(handle_\exception\ext)
+	__BUILD_clear_\clear
+	.set	at
+	__BUILD_\verbose \exception
+	move	a0, sp
+	jal	do_\handler
+	j	ret_from_exception
+	END(handle_\exception)
+	.endm
+
+	.macro	BUILD_HANDLER exception handler clear verbose
+	__BUILD_HANDLER	\exception \handler \clear \verbose _int
+	.endm
+
+	BUILD_HANDLER adel ade ade silent		/* #4  */
+	BUILD_HANDLER ades ade ade silent		/* #5  */
+	BUILD_HANDLER ibe be cli silent			/* #6  */
+	BUILD_HANDLER dbe be cli silent			/* #7  */
+	BUILD_HANDLER bp bp sti silent			/* #9  */
+	BUILD_HANDLER ri ri sti silent			/* #10 */
+	BUILD_HANDLER cpu cpu sti silent		/* #11 */
+	BUILD_HANDLER ov ov sti silent			/* #12 */
+	BUILD_HANDLER tr tr sti silent			/* #13 */
+	BUILD_HANDLER fpe fpe fpe silent		/* #15 */
+	BUILD_HANDLER mdmx mdmx sti silent		/* #22 */
+	BUILD_HANDLER watch watch sti verbose		/* #23 */
+	BUILD_HANDLER mcheck mcheck cli verbose		/* #24 */
+	BUILD_HANDLER reserved reserved sti verbose	/* others */
+
+#ifdef CONFIG_MIPS64
+/* A temporary overflow handler used by check_daddi(). */
+
+	__INIT
+
+	BUILD_HANDLER  daddi_ov daddi_ov none silent	/* #12 */
+#endif
diff --git a/arch/mips/kernel/genrtc.c b/arch/mips/kernel/genrtc.c
new file mode 100644
index 0000000..288bf51
--- /dev/null
+++ b/arch/mips/kernel/genrtc.c
@@ -0,0 +1,64 @@
+/*
+ * A glue layer that provides RTC read/write to drivers/char/genrtc.c driver
+ * based on MIPS internal RTC routines.  It does take care locking
+ * issues so that we are SMP/Preemption safe.
+ *
+ * Copyright (C) 2004 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * Please read the COPYING file for all license details.
+ */
+
+#include <linux/spinlock.h>
+
+#include <asm/rtc.h>
+#include <asm/time.h>
+
+static spinlock_t mips_rtc_lock = SPIN_LOCK_UNLOCKED;
+
+unsigned int get_rtc_time(struct rtc_time *time)
+{
+	unsigned long nowtime;
+
+	spin_lock(&mips_rtc_lock);
+	nowtime = rtc_get_time();
+	to_tm(nowtime, time);
+	time->tm_year -= 1900;
+	spin_unlock(&mips_rtc_lock);
+
+	return RTC_24H;
+}
+
+int set_rtc_time(struct rtc_time *time)
+{
+	unsigned long nowtime;
+	int ret;
+
+	spin_lock(&mips_rtc_lock);
+	nowtime = mktime(time->tm_year+1900, time->tm_mon+1,
+			time->tm_mday, time->tm_hour, time->tm_min,
+			time->tm_sec);
+	ret = rtc_set_time(nowtime);
+	spin_unlock(&mips_rtc_lock);
+
+	return ret;
+}
+
+unsigned int get_rtc_ss(void)
+{
+	struct rtc_time h;
+
+	get_rtc_time(&h);
+	return h.tm_sec;
+}
+
+int get_rtc_pll(struct rtc_pll_info *pll)
+{
+	return -EINVAL;
+}
+
+int set_rtc_pll(struct rtc_pll_info *pll)
+{
+	return -EINVAL;
+}
+
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
new file mode 100644
index 0000000..a64e87d
--- /dev/null
+++ b/arch/mips/kernel/head.S
@@ -0,0 +1,221 @@
+/*
+ * 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) 1994, 1995 Waldorf Electronics
+ * Written by Ralf Baechle and Andreas Busse
+ * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003 Ralf Baechle
+ * Copyright (C) 1996 Paul M. Antoine
+ * Modified for DECStation and hence R3000 support by Paul M. Antoine
+ * Further modifications by David S. Miller and Harald Koerfgen
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/threads.h>
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/page.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+#ifdef CONFIG_SGI_IP27
+#include <asm/sn/addrs.h>
+#include <asm/sn/sn0/hubni.h>
+#include <asm/sn/klkernvars.h>
+#endif
+
+	.macro	ARC64_TWIDDLE_PC
+#if defined(CONFIG_ARC64) || defined(CONFIG_MAPPED_KERNEL)
+	/* We get launched at a XKPHYS address but the kernel is linked to
+	   run at a KSEG0 address, so jump there.  */
+	PTR_LA	t0, \@f
+	jr	t0
+\@:
+#endif
+	.endm
+
+#ifdef CONFIG_SGI_IP27
+	/*
+	 * outputs the local nasid into res.  IP27 stuff.
+	 */
+	.macro GET_NASID_ASM res
+	dli	\res, LOCAL_HUB_ADDR(NI_STATUS_REV_ID)
+	ld	\res, (\res)
+	and	\res, NSRI_NODEID_MASK
+	dsrl	\res, NSRI_NODEID_SHFT
+	.endm
+#endif /* CONFIG_SGI_IP27 */
+
+	/*
+	 * inputs are the text nasid in t1, data nasid in t2.
+	 */
+	.macro MAPPED_KERNEL_SETUP_TLB
+#ifdef CONFIG_MAPPED_KERNEL
+	/*
+	 * This needs to read the nasid - assume 0 for now.
+	 * Drop in 0xffffffffc0000000 in tlbhi, 0+VG in tlblo_0,
+	 * 0+DVG in tlblo_1.
+	 */
+	dli	t0, 0xffffffffc0000000
+	dmtc0	t0, CP0_ENTRYHI
+	li	t0, 0x1c000		# Offset of text into node memory
+	dsll	t1, NASID_SHFT		# Shift text nasid into place
+	dsll	t2, NASID_SHFT		# Same for data nasid
+	or	t1, t1, t0		# Physical load address of kernel text
+	or	t2, t2, t0		# Physical load address of kernel data
+	dsrl	t1, 12			# 4K pfn
+	dsrl	t2, 12			# 4K pfn
+	dsll	t1, 6			# Get pfn into place
+	dsll	t2, 6			# Get pfn into place
+	li	t0, ((_PAGE_GLOBAL|_PAGE_VALID| _CACHE_CACHABLE_COW) >> 6)
+	or	t0, t0, t1
+	mtc0	t0, CP0_ENTRYLO0	# physaddr, VG, cach exlwr
+	li	t0, ((_PAGE_GLOBAL|_PAGE_VALID| _PAGE_DIRTY|_CACHE_CACHABLE_COW) >> 6)
+	or	t0, t0, t2
+	mtc0	t0, CP0_ENTRYLO1	# physaddr, DVG, cach exlwr
+	li	t0, 0x1ffe000		# MAPPED_KERN_TLBMASK, TLBPGMASK_16M
+	mtc0	t0, CP0_PAGEMASK
+	li	t0, 0			# KMAP_INX
+	mtc0	t0, CP0_INDEX
+	li	t0, 1
+	mtc0	t0, CP0_WIRED
+	tlbwi
+#else
+	mtc0	zero, CP0_WIRED
+#endif
+	.endm
+
+	/*
+	 * For the moment disable interrupts, mark the kernel mode and
+	 * set ST0_KX so that the CPU does not spit fire when using
+	 * 64-bit addresses.  A full initialization of the CPU's status
+	 * register is done later in per_cpu_trap_init().
+	 */
+	.macro	setup_c0_status set clr
+	.set	push
+	mfc0	t0, CP0_STATUS
+	or	t0, ST0_CU0|\set|0x1f|\clr
+	xor	t0, 0x1f|\clr
+	mtc0	t0, CP0_STATUS
+	.set	noreorder
+	sll	zero,3				# ehb
+	.set	pop
+	.endm
+
+	.macro	setup_c0_status_pri
+#ifdef CONFIG_MIPS64
+	setup_c0_status ST0_KX 0
+#else
+	setup_c0_status 0 0
+#endif
+	.endm
+
+	.macro	setup_c0_status_sec
+#ifdef CONFIG_MIPS64
+	setup_c0_status ST0_KX ST0_BEV
+#else
+	setup_c0_status 0 ST0_BEV
+#endif
+	.endm
+
+	/*
+	 * Reserved space for exception handlers.
+	 * Necessary for machines which link their kernels at KSEG0.
+	 */
+	.fill	0x400
+
+EXPORT(stext)					# used for profiling
+EXPORT(_stext)
+
+	__INIT
+
+NESTED(kernel_entry, 16, sp)			# kernel entry point
+	setup_c0_status_pri
+
+#ifdef CONFIG_SGI_IP27
+	GET_NASID_ASM	t1
+	move	t2, t1				# text and data are here
+	MAPPED_KERNEL_SETUP_TLB
+#endif /* IP27 */
+
+	ARC64_TWIDDLE_PC
+
+	PTR_LA		t0, __bss_start		# clear .bss
+	LONG_S		zero, (t0)
+	PTR_LA		t1, __bss_stop - LONGSIZE
+1:
+	PTR_ADDIU	t0, LONGSIZE
+	LONG_S		zero, (t0)
+	bne		t0, t1, 1b
+
+	LONG_S		a0, fw_arg0		# firmware arguments
+	LONG_S		a1, fw_arg1
+	LONG_S		a2, fw_arg2
+	LONG_S		a3, fw_arg3
+
+	PTR_LA		$28, init_thread_union
+	PTR_ADDIU	sp, $28, _THREAD_SIZE - 32
+	set_saved_sp	sp, t0, t1
+	PTR_SUBU	sp, 4 * SZREG		# init stack pointer
+
+	j		start_kernel
+	END(kernel_entry)
+
+#ifdef CONFIG_SMP
+/*
+ * SMP slave cpus entry point.  Board specific code for bootstrap calls this
+ * function after setting up the stack and gp registers.
+ */
+NESTED(smp_bootstrap, 16, sp)
+	setup_c0_status_sec
+
+#ifdef CONFIG_SGI_IP27
+	GET_NASID_ASM	t1
+	dli	t0, KLDIR_OFFSET + (KLI_KERN_VARS * KLDIR_ENT_SIZE) + \
+		    KLDIR_OFF_POINTER + CAC_BASE
+	dsll	t1, NASID_SHFT
+	or	t0, t0, t1
+	ld	t0, 0(t0)			# t0 points to kern_vars struct
+	lh	t1, KV_RO_NASID_OFFSET(t0)
+	lh	t2, KV_RW_NASID_OFFSET(t0)
+	MAPPED_KERNEL_SETUP_TLB
+	ARC64_TWIDDLE_PC
+#endif /* CONFIG_SGI_IP27 */
+
+	j	start_secondary
+	END(smp_bootstrap)
+#endif /* CONFIG_SMP */
+
+	__FINIT
+
+	.comm	kernelsp,    NR_CPUS * 8, 8
+	.comm	pgd_current, NR_CPUS * 8, 8
+
+	.comm	fw_arg0, SZREG, SZREG		# firmware arguments
+	.comm	fw_arg1, SZREG, SZREG
+	.comm	fw_arg2, SZREG, SZREG
+	.comm	fw_arg3, SZREG, SZREG
+
+	.macro	page name, order=0
+	.globl	\name
+\name:	.size	\name, (_PAGE_SIZE << \order)
+	.org	. + (_PAGE_SIZE << \order)
+	.type	\name, @object
+	.endm
+
+	.data
+	.align	PAGE_SHIFT
+
+	/*
+	 * ... but on 64-bit we've got three-level pagetables with a
+	 * slightly different layout ...
+	 */
+	page	swapper_pg_dir, _PGD_ORDER
+#ifdef CONFIG_MIPS64
+	page	invalid_pmd_table, _PMD_ORDER
+#endif
+	page	invalid_pte_table, _PTE_ORDER
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
new file mode 100644
index 0000000..7eec756
--- /dev/null
+++ b/arch/mips/kernel/i8259.c
@@ -0,0 +1,331 @@
+/*
+ * 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.
+ *
+ * Code to handle x86 style IRQs plus some generic interrupt stuff.
+ *
+ * Copyright (C) 1992 Linus Torvalds
+ * Copyright (C) 1994 - 2000 Ralf Baechle
+ */
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/sysdev.h>
+
+#include <asm/i8259.h>
+#include <asm/io.h>
+
+void enable_8259A_irq(unsigned int irq);
+void disable_8259A_irq(unsigned int irq);
+
+/*
+ * This is the 'legacy' 8259A Programmable Interrupt Controller,
+ * present in the majority of PC/AT boxes.
+ * plus some generic x86 specific things if generic specifics makes
+ * any sense at all.
+ * this file should become arch/i386/kernel/irq.c when the old irq.c
+ * moves to arch independent land
+ */
+
+spinlock_t i8259A_lock = SPIN_LOCK_UNLOCKED;
+
+static void end_8259A_irq (unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)) &&
+	    irq_desc[irq].action)
+		enable_8259A_irq(irq);
+}
+
+#define shutdown_8259A_irq	disable_8259A_irq
+
+void mask_and_ack_8259A(unsigned int);
+
+static unsigned int startup_8259A_irq(unsigned int irq)
+{
+	enable_8259A_irq(irq);
+
+	return 0; /* never anything pending */
+}
+
+static struct hw_interrupt_type i8259A_irq_type = {
+	"XT-PIC",
+	startup_8259A_irq,
+	shutdown_8259A_irq,
+	enable_8259A_irq,
+	disable_8259A_irq,
+	mask_and_ack_8259A,
+	end_8259A_irq,
+	NULL
+};
+
+/*
+ * 8259A PIC functions to handle ISA devices:
+ */
+
+/*
+ * This contains the irq mask for both 8259A irq controllers,
+ */
+static unsigned int cached_irq_mask = 0xffff;
+
+#define cached_21	(cached_irq_mask)
+#define cached_A1	(cached_irq_mask >> 8)
+
+void disable_8259A_irq(unsigned int irq)
+{
+	unsigned int mask = 1 << irq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&i8259A_lock, flags);
+	cached_irq_mask |= mask;
+	if (irq & 8)
+		outb(cached_A1,0xA1);
+	else
+		outb(cached_21,0x21);
+	spin_unlock_irqrestore(&i8259A_lock, flags);
+}
+
+void enable_8259A_irq(unsigned int irq)
+{
+	unsigned int mask = ~(1 << irq);
+	unsigned long flags;
+
+	spin_lock_irqsave(&i8259A_lock, flags);
+	cached_irq_mask &= mask;
+	if (irq & 8)
+		outb(cached_A1,0xA1);
+	else
+		outb(cached_21,0x21);
+	spin_unlock_irqrestore(&i8259A_lock, flags);
+}
+
+int i8259A_irq_pending(unsigned int irq)
+{
+	unsigned int mask = 1 << irq;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&i8259A_lock, flags);
+	if (irq < 8)
+		ret = inb(0x20) & mask;
+	else
+		ret = inb(0xA0) & (mask >> 8);
+	spin_unlock_irqrestore(&i8259A_lock, flags);
+
+	return ret;
+}
+
+void make_8259A_irq(unsigned int irq)
+{
+	disable_irq_nosync(irq);
+	irq_desc[irq].handler = &i8259A_irq_type;
+	enable_irq(irq);
+}
+
+/*
+ * This function assumes to be called rarely. Switching between
+ * 8259A registers is slow.
+ * This has to be protected by the irq controller spinlock
+ * before being called.
+ */
+static inline int i8259A_irq_real(unsigned int irq)
+{
+	int value;
+	int irqmask = 1 << irq;
+
+	if (irq < 8) {
+		outb(0x0B,0x20);		/* ISR register */
+		value = inb(0x20) & irqmask;
+		outb(0x0A,0x20);		/* back to the IRR register */
+		return value;
+	}
+	outb(0x0B,0xA0);		/* ISR register */
+	value = inb(0xA0) & (irqmask >> 8);
+	outb(0x0A,0xA0);		/* back to the IRR register */
+	return value;
+}
+
+/*
+ * Careful! The 8259A is a fragile beast, it pretty
+ * much _has_ to be done exactly like this (mask it
+ * first, _then_ send the EOI, and the order of EOI
+ * to the two 8259s is important!
+ */
+void mask_and_ack_8259A(unsigned int irq)
+{
+	unsigned int irqmask = 1 << irq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&i8259A_lock, flags);
+	/*
+	 * Lightweight spurious IRQ detection. We do not want to overdo
+	 * spurious IRQ handling - it's usually a sign of hardware problems, so
+	 * we only do the checks we can do without slowing down good hardware
+	 * nnecesserily.
+	 *
+	 * Note that IRQ7 and IRQ15 (the two spurious IRQs usually resulting
+	 * rom the 8259A-1|2 PICs) occur even if the IRQ is masked in the 8259A.
+	 * Thus we can check spurious 8259A IRQs without doing the quite slow
+	 * i8259A_irq_real() call for every IRQ.  This does not cover 100% of
+	 * spurious interrupts, but should be enough to warn the user that
+	 * there is something bad going on ...
+	 */
+	if (cached_irq_mask & irqmask)
+		goto spurious_8259A_irq;
+	cached_irq_mask |= irqmask;
+
+handle_real_irq:
+	if (irq & 8) {
+		inb(0xA1);		/* DUMMY - (do we need this?) */
+		outb(cached_A1,0xA1);
+		outb(0x60+(irq&7),0xA0);/* 'Specific EOI' to slave */
+		outb(0x62,0x20);	/* 'Specific EOI' to master-IRQ2 */
+	} else {
+		inb(0x21);		/* DUMMY - (do we need this?) */
+		outb(cached_21,0x21);
+		outb(0x60+irq,0x20);	/* 'Specific EOI' to master */
+	}
+	spin_unlock_irqrestore(&i8259A_lock, flags);
+	return;
+
+spurious_8259A_irq:
+	/*
+	 * this is the slow path - should happen rarely.
+	 */
+	if (i8259A_irq_real(irq))
+		/*
+		 * oops, the IRQ _is_ in service according to the
+		 * 8259A - not spurious, go handle it.
+		 */
+		goto handle_real_irq;
+
+	{
+		static int spurious_irq_mask = 0;
+		/*
+		 * At this point we can be sure the IRQ is spurious,
+		 * lets ACK and report it. [once per IRQ]
+		 */
+		if (!(spurious_irq_mask & irqmask)) {
+			printk(KERN_DEBUG "spurious 8259A interrupt: IRQ%d.\n", irq);
+			spurious_irq_mask |= irqmask;
+		}
+		atomic_inc(&irq_err_count);
+		/*
+		 * Theoretically we do not have to handle this IRQ,
+		 * but in Linux this does not cause problems and is
+		 * simpler for us.
+		 */
+		goto handle_real_irq;
+	}
+}
+
+static int i8259A_resume(struct sys_device *dev)
+{
+	init_8259A(0);
+	return 0;
+}
+
+static struct sysdev_class i8259_sysdev_class = {
+	set_kset_name("i8259"),
+	.resume = i8259A_resume,
+};
+
+static struct sys_device device_i8259A = {
+	.id	= 0,
+	.cls	= &i8259_sysdev_class,
+};
+
+static int __init i8259A_init_sysfs(void)
+{
+	int error = sysdev_class_register(&i8259_sysdev_class);
+	if (!error)
+		error = sysdev_register(&device_i8259A);
+	return error;
+}
+
+device_initcall(i8259A_init_sysfs);
+
+void __init init_8259A(int auto_eoi)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&i8259A_lock, flags);
+
+	outb(0xff, 0x21);	/* mask all of 8259A-1 */
+	outb(0xff, 0xA1);	/* mask all of 8259A-2 */
+
+	/*
+	 * outb_p - this has to work on a wide range of PC hardware.
+	 */
+	outb_p(0x11, 0x20);	/* ICW1: select 8259A-1 init */
+	outb_p(0x00, 0x21);	/* ICW2: 8259A-1 IR0-7 mapped to 0x00-0x07 */
+	outb_p(0x04, 0x21);	/* 8259A-1 (the master) has a slave on IR2 */
+	if (auto_eoi)
+		outb_p(0x03, 0x21);	/* master does Auto EOI */
+	else
+		outb_p(0x01, 0x21);	/* master expects normal EOI */
+
+	outb_p(0x11, 0xA0);	/* ICW1: select 8259A-2 init */
+	outb_p(0x08, 0xA1);	/* ICW2: 8259A-2 IR0-7 mapped to 0x08-0x0f */
+	outb_p(0x02, 0xA1);	/* 8259A-2 is a slave on master's IR2 */
+	outb_p(0x01, 0xA1);	/* (slave's support for AEOI in flat mode
+				    is to be investigated) */
+
+	if (auto_eoi)
+		/*
+		 * in AEOI mode we just have to mask the interrupt
+		 * when acking.
+		 */
+		i8259A_irq_type.ack = disable_8259A_irq;
+	else
+		i8259A_irq_type.ack = mask_and_ack_8259A;
+
+	udelay(100);		/* wait for 8259A to initialize */
+
+	outb(cached_21, 0x21);	/* restore master IRQ mask */
+	outb(cached_A1, 0xA1);	/* restore slave IRQ mask */
+
+	spin_unlock_irqrestore(&i8259A_lock, flags);
+}
+
+/*
+ * IRQ2 is cascade interrupt to second interrupt controller
+ */
+static struct irqaction irq2 = {
+	no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL
+};
+
+static struct resource pic1_io_resource = {
+	"pic1", 0x20, 0x3f, IORESOURCE_BUSY
+};
+
+static struct resource pic2_io_resource = {
+	"pic2", 0xa0, 0xbf, IORESOURCE_BUSY
+};
+
+/*
+ * On systems with i8259-style interrupt controllers we assume for
+ * driver compatibility reasons interrupts 0 - 15 to be the i8295
+ * interrupts even if the hardware uses a different interrupt numbering.
+ */
+void __init init_i8259_irqs (void)
+{
+	int i;
+
+	request_resource(&ioport_resource, &pic1_io_resource);
+	request_resource(&ioport_resource, &pic2_io_resource);
+
+	init_8259A(0);
+
+	for (i = 0; i < 16; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = 0;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &i8259A_irq_type;
+	}
+
+	setup_irq(2, &irq2);
+}
diff --git a/arch/mips/kernel/init_task.c b/arch/mips/kernel/init_task.c
new file mode 100644
index 0000000..aeda7f5
--- /dev/null
+++ b/arch/mips/kernel/init_task.c
@@ -0,0 +1,42 @@
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init_task.h>
+#include <linux/fs.h>
+#include <linux/mqueue.h>
+
+#include <asm/thread_info.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+
+static struct fs_struct init_fs = INIT_FS;
+static struct files_struct init_files = INIT_FILES;
+static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
+struct mm_struct init_mm = INIT_MM(init_mm);
+
+EXPORT_SYMBOL(init_mm);
+
+/*
+ * Initial thread structure.
+ *
+ * We need to make sure that this is 8192-byte aligned due to the
+ * way process stacks are handled. This is done by making sure
+ * the linker maps this in the .text segment right after head.S,
+ * and making head.S ensure the proper alignment.
+ *
+ * The things we do for performance..
+ */
+union thread_union init_thread_union
+	__attribute__((__section__(".data.init_task"),
+	               __aligned__(THREAD_SIZE))) =
+		{ INIT_THREAD_INFO(init_task) };
+
+/*
+ * Initial task structure.
+ *
+ * All other task structs will be allocated on slabs in fork.c
+ */
+struct task_struct init_task = INIT_TASK(init_task);
+
+EXPORT_SYMBOL(init_task);
diff --git a/arch/mips/kernel/ioctl32.c b/arch/mips/kernel/ioctl32.c
new file mode 100644
index 0000000..519cd5d
--- /dev/null
+++ b/arch/mips/kernel/ioctl32.c
@@ -0,0 +1,58 @@
+/*
+ * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
+ *
+ * Copyright (C) 2000 Silicon Graphics, Inc.
+ * Written by Ulf Carlsson (ulfc@engr.sgi.com)
+ * Copyright (C) 2000, 2004 Ralf Baechle
+ * Copyright (C) 2002, 2003  Maciej W. Rozycki
+ */
+#define INCLUDES
+#include "compat_ioctl.c"
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/compat.h>
+#include <linux/ioctl32.h>
+#include <linux/syscalls.h>
+
+#ifdef CONFIG_SIBYTE_TBPROF
+#include <asm/sibyte/trace_prof.h>
+#endif
+
+#define A(__x) ((unsigned long)(__x))
+
+long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
+
+#define CODE
+#include "compat_ioctl.c"
+
+typedef int (* ioctl32_handler_t)(unsigned int, unsigned int, unsigned long, struct file *);
+                                                                                
+#define COMPATIBLE_IOCTL(cmd)		HANDLE_IOCTL((cmd),sys_ioctl)
+#define HANDLE_IOCTL(cmd,handler)	{ (cmd), (ioctl32_handler_t)(handler), NULL },
+#define IOCTL_TABLE_START \
+	struct ioctl_trans ioctl_start[] = {
+#define IOCTL_TABLE_END \
+	};
+
+IOCTL_TABLE_START
+
+#include <linux/compat_ioctl.h>
+#define DECLARES
+#include "compat_ioctl.c"
+
+#ifdef CONFIG_SIBYTE_TBPROF
+COMPATIBLE_IOCTL(SBPROF_ZBSTART)
+COMPATIBLE_IOCTL(SBPROF_ZBSTOP)
+COMPATIBLE_IOCTL(SBPROF_ZBWAITFULL)
+#endif /* CONFIG_SIBYTE_TBPROF */
+
+/*HANDLE_IOCTL(RTC_IRQP_READ, w_long)
+COMPATIBLE_IOCTL(RTC_IRQP_SET)
+HANDLE_IOCTL(RTC_EPOCH_READ, w_long)
+COMPATIBLE_IOCTL(RTC_EPOCH_SET)
+*/
+
+IOCTL_TABLE_END
+
+int ioctl_table_size = ARRAY_SIZE(ioctl_start);
diff --git a/arch/mips/kernel/irix5sys.S b/arch/mips/kernel/irix5sys.S
new file mode 100644
index 0000000..eeef891
--- /dev/null
+++ b/arch/mips/kernel/irix5sys.S
@@ -0,0 +1,1041 @@
+/*
+ * 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.
+ *
+ * 32-bit IRIX5 ABI system call table derived from original file 'irix5sys.h'
+ * created by David S. Miller.
+ *
+ * Copyright (C) 1996 - 2004 David S. Miller <dm@engr.sgi.com>
+ * Copyright (C) 2004 Steven J. Hill <sjhill@realitydiluted.com>
+ */
+#include <asm/asm.h>
+
+	/*
+	 * Key:
+	 *         V == Valid and should work as expected for most cases.
+	 *        HV == Half Valid, some things will work, some likely will not
+	 *        IV == InValid, certainly will not work at all yet
+	 *        ?V == ?'ably Valid, I have not done enough looking into it
+	 *        DC == Don't Care, a rats ass we couldn't give
+	 */
+
+	.macro	irix5syscalltable
+
+	sys	sys_syscall	0	/* 1000  sysindir()	       V*/
+	sys	sys_exit	1	/* 1001  exit()		       V*/
+	sys	sys_fork	0	/* 1002  fork()		       V*/
+	sys	sys_read	3	/* 1003  read()		       V*/
+	sys	sys_write	3	/* 1004  write()	       V*/
+	sys	sys_open	3	/* 1005  open()		       V*/
+	sys	sys_close	1	/* 1006  close()	       V*/
+	sys	irix_unimp	0	/* 1007  (XXX IRIX 4 wait)     V*/
+	sys	sys_creat	2	/* 1008  creat()	       V*/
+	sys	sys_link	2	/* 1009  link()		       V*/
+	sys	sys_unlink	1	/* 1010  unlink()	       V*/
+	sys	irix_exec	0	/* 1011  exec()		       V*/
+	sys	sys_chdir	1	/* 1012  chdir()	       V*/
+	sys	irix_gtime	0	/* 1013  time()		       V*/
+	sys	irix_unimp	0	/* 1014  (XXX IRIX 4 mknod)    V*/
+	sys	sys_chmod	2	/* 1015  chmod()	       V*/
+	sys	sys_chown	3	/* 1016  chown()	       V*/
+	sys	irix_brk	1	/* 1017  break()	       V*/
+	sys	irix_unimp	0	/* 1018  (XXX IRIX 4 stat)     V*/
+	sys	sys_lseek	3	/* 1019  lseek()     XXX64bit HV*/
+	sys	irix_getpid	0	/* 1020  getpid()	       V*/
+	sys	irix_mount	6	/* 1021  mount()	      IV*/
+	sys	sys_umount	1	/* 1022  umount()	       V*/
+	sys	sys_setuid	1	/* 1023  setuid()	       V*/
+	sys	irix_getuid	0	/* 1024  getuid()	       V*/
+	sys	irix_stime	1	/* 1025  stime()	       V*/
+	sys	irix_unimp	4	/* 1026  XXX ptrace()	      IV*/
+	sys	irix_alarm	1	/* 1027  alarm()	       V*/
+	sys	irix_unimp	0	/* 1028  (XXX IRIX 4 fstat)    V*/
+	sys	irix_pause	0	/* 1029  pause()	       V*/
+	sys	sys_utime	2	/* 1030  utime()	       V*/
+	sys	irix_unimp	0	/* 1031  nuthin'	       V*/
+	sys	irix_unimp	0	/* 1032  nobody home man...    V*/
+	sys	sys_access	2	/* 1033  access()	       V*/
+	sys	sys_nice	1	/* 1034  nice()		       V*/
+	sys	irix_statfs	2	/* 1035  statfs()	       V*/
+	sys	sys_sync	0	/* 1036  sync()		       V*/
+	sys	sys_kill	2	/* 1037  kill()		       V*/
+	sys	irix_fstatfs	2	/* 1038  fstatfs()	       V*/
+	sys	irix_setpgrp	1	/* 1039  setpgrp()	       V*/
+	sys	irix_syssgi	0	/* 1040  syssgi()	      HV*/
+	sys	sys_dup		1	/* 1041  dup()		       V*/
+	sys	sys_pipe	0	/* 1042  pipe()		       V*/
+	sys	irix_times	1	/* 1043  times()	       V*/
+	sys	irix_unimp	0	/* 1044  XXX profil()	      IV*/
+	sys	irix_unimp	0	/* 1045  XXX lock()	      IV*/
+	sys	sys_setgid	1	/* 1046  setgid()	       V*/
+	sys	irix_getgid	0	/* 1047  getgid()	       V*/
+	sys	irix_unimp	0	/* 1048  (XXX IRIX 4 ssig)     V*/
+	sys	irix_msgsys	6	/* 1049  sys_msgsys	       V*/
+	sys	sys_sysmips	4	/* 1050  sysmips()	      HV*/
+	sys	irix_unimp	0	/* 1051	 XXX sysacct()	      IV*/
+	sys	irix_shmsys	5	/* 1052  sys_shmsys	       V*/
+	sys	irix_semsys	0	/* 1053  sys_semsys	       V*/
+	sys	irix_ioctl	3	/* 1054  ioctl()	      HV*/
+	sys	irix_uadmin	0	/* 1055  XXX sys_uadmin()     HC*/
+	sys	irix_sysmp	0	/* 1056  sysmp()	      HV*/
+	sys	irix_utssys	4	/* 1057  sys_utssys()	      HV*/
+	sys	irix_unimp	0	/* 1058  nada enchilada	       V*/
+	sys	irix_exece	0	/* 1059  exece()	       V*/
+	sys	sys_umask	1	/* 1060  umask()	       V*/
+	sys	sys_chroot	1	/* 1061  chroot()	       V*/
+	sys	irix_fcntl	3	/* 1062  fcntl()	      ?V*/
+	sys	irix_ulimit	2	/* 1063  ulimit()	      HV*/
+	sys	irix_unimp	0	/* 1064  XXX AFS shit	      DC*/
+	sys	irix_unimp	0	/* 1065  XXX AFS shit	      DC*/
+	sys	irix_unimp	0	/* 1066  XXX AFS shit	      DC*/
+	sys	irix_unimp	0	/* 1067  XXX AFS shit	      DC*/
+	sys	irix_unimp	0	/* 1068  XXX AFS shit	      DC*/
+	sys	irix_unimp	0	/* 1069  XXX AFS shit	      DC*/
+	sys	irix_unimp	0	/* 1070  XXX AFS shit	      DC*/
+	sys	irix_unimp	0	/* 1071  XXX AFS shit	      DC*/
+	sys	irix_unimp	0	/* 1072  XXX AFS shit	      DC*/
+	sys	irix_unimp	0	/* 1073  XXX AFS shit	      DC*/
+	sys	irix_unimp	0	/* 1074  nuttin'	       V*/
+	sys	irix_unimp	0	/* 1075  XXX sys_getrlimit64()IV*/
+	sys	irix_unimp	0	/* 1076  XXX sys_setrlimit64()IV*/
+	sys	sys_nanosleep	2	/* 1077  nanosleep()	       V*/
+	sys	irix_lseek64	5	/* 1078  lseek64()	      ?V*/
+	sys	sys_rmdir	1	/* 1079  rmdir()	       V*/
+	sys	sys_mkdir	2	/* 1080  mkdir()	       V*/
+	sys	sys_getdents	3	/* 1081  getdents()	       V*/
+	sys	irix_sginap	1	/* 1082  sys_sginap()	       V*/
+	sys	irix_sgikopt	3	/* 1083  sys_sgikopt()	      DC*/
+	sys	sys_sysfs	3	/* 1084  sysfs()	      ?V*/
+	sys	irix_unimp	0	/* 1085  XXX sys_getmsg()     DC*/
+	sys	irix_unimp	0	/* 1086  XXX sys_putmsg()     DC*/
+	sys	sys_poll	3	/* 1087  poll()	               V*/
+	sys	irix_sigreturn	0	/* 1088  sigreturn()	      ?V*/
+	sys	sys_accept	3	/* 1089  accept()	       V*/
+	sys	sys_bind	3	/* 1090  bind()		       V*/
+	sys	sys_connect	3	/* 1091  connect()	       V*/
+	sys	irix_gethostid	0	/* 1092  sys_gethostid()      ?V*/
+	sys	sys_getpeername	3	/* 1093  getpeername()	       V*/
+	sys	sys_getsockname	3	/* 1094  getsockname()	       V*/
+	sys	sys_getsockopt	5	/* 1095  getsockopt()	       V*/
+	sys	sys_listen	2	/* 1096  listen()	       V*/
+	sys	sys_recv	4	/* 1097  recv()		       V*/
+	sys	sys_recvfrom	6	/* 1098  recvfrom()	       V*/
+	sys	sys_recvmsg	3	/* 1099  recvmsg()	       V*/
+	sys	sys_select	5	/* 1100  select()	       V*/
+	sys	sys_send	4	/* 1101  send()		       V*/
+	sys	sys_sendmsg	3	/* 1102  sendmsg()	       V*/
+	sys	sys_sendto	6	/* 1103  sendto()	       V*/
+	sys	irix_sethostid	1	/* 1104  sys_sethostid()      ?V*/
+	sys	sys_setsockopt	5	/* 1105  setsockopt()	       V*/
+	sys	sys_shutdown	2	/* 1106  shutdown()	      ?V*/
+	sys	irix_socket	3	/* 1107  socket()	       V*/
+	sys	sys_gethostname	2	/* 1108  sys_gethostname()    ?V*/
+	sys	sys_sethostname	2	/* 1109  sethostname()	      ?V*/
+	sys	irix_getdomainname 2	/* 1110  sys_getdomainname()  ?V*/
+	sys	sys_setdomainname 2	/* 1111  setdomainname()      ?V*/
+	sys	sys_truncate	2	/* 1112  truncate()	       V*/
+	sys	sys_ftruncate	2	/* 1113  ftruncate()	       V*/
+	sys	sys_rename	2	/* 1114  rename()	       V*/
+	sys	sys_symlink	2	/* 1115  symlink()	       V*/
+	sys	sys_readlink	3	/* 1116  readlink()	       V*/
+	sys	irix_unimp	0	/* 1117  XXX IRIX 4 lstat()   DC*/
+	sys	irix_unimp	0	/* 1118  nothin'	       V*/
+	sys	irix_unimp	0	/* 1119  XXX nfs_svc()	      DC*/
+	sys	irix_unimp	0	/* 1120  XXX nfs_getfh()      DC*/
+	sys	irix_unimp	0	/* 1121  XXX async_daemon()   DC*/
+	sys	irix_unimp	0	/* 1122  XXX exportfs()	      DC*/
+	sys	sys_setregid	2	/* 1123  setregid()	       V*/
+	sys	sys_setreuid	2	/* 1124  setreuid()	       V*/
+	sys	sys_getitimer	2	/* 1125  getitimer()	       V*/
+	sys	sys_setitimer	3	/* 1126  setitimer()	       V*/
+	sys	irix_unimp	1	/* 1127  XXX adjtime() 	      IV*/
+	sys	irix_gettimeofday 1	/* 1128  gettimeofday()	       V*/
+	sys	irix_unimp	0	/* 1129  XXX sproc()	      IV*/
+	sys	irix_prctl	0	/* 1130  prctl()	      HV*/
+	sys	irix_unimp	0	/* 1131  XXX procblk()	      IV*/
+	sys	irix_unimp	0	/* 1132  XXX sprocsp()	      IV*/
+	sys	irix_unimp	0	/* 1133  XXX sgigsc()	      IV*/
+	sys	irix_mmap32	6	/* 1134  mmap()	   XXXflags?  ?V*/
+	sys	sys_munmap	2	/* 1135  munmap()	       V*/
+	sys	sys_mprotect	3	/* 1136  mprotect()	       V*/
+	sys	sys_msync	4	/* 1137  msync()	       V*/
+	sys	irix_madvise	3	/* 1138  madvise()	      DC*/
+	sys	irix_pagelock	3	/* 1139  pagelock()	      IV*/
+	sys	irix_getpagesize 0	/* 1140  getpagesize()         V*/
+	sys	irix_quotactl	0	/* 1141  quotactl()	       V*/
+	sys	irix_unimp	0	/* 1142  nobody home man       V*/
+	sys	sys_getpgid	1	/* 1143  BSD getpgrp()	       V*/
+	sys	irix_BSDsetpgrp 2	/* 1143  BSD setpgrp()	       V*/
+	sys	sys_vhangup	0	/* 1144  vhangup()	       V*/
+	sys	sys_fsync	1	/* 1145  fsync()	       V*/
+	sys	sys_fchdir	1	/* 1146  fchdir()	       V*/
+	sys	sys_getrlimit	2	/* 1147  getrlimit()	      ?V*/
+	sys	sys_setrlimit	2	/* 1148  setrlimit()	      ?V*/
+	sys	sys_cacheflush	3	/* 1150  cacheflush()	      HV*/
+	sys	sys_cachectl	3	/* 1151  cachectl()	      HV*/
+	sys	sys_fchown	3	/* 1152  fchown()	      ?V*/
+	sys	sys_fchmod	2	/* 1153  fchmod()	      ?V*/
+	sys	irix_unimp	0	/* 1154  XXX IRIX 4 wait3()    V*/
+	sys	sys_socketpair	4	/* 1155  socketpair()	       V*/
+	sys	irix_systeminfo	3	/* 1156  systeminfo()	      IV*/
+	sys	irix_uname	1	/* 1157  uname()	      IV*/
+	sys	irix_xstat	3	/* 1158  xstat()	       V*/
+	sys	irix_lxstat	3	/* 1159  lxstat()	       V*/
+	sys	irix_fxstat	3	/* 1160  fxstat()	       V*/
+	sys	irix_xmknod	0	/* 1161  xmknod()	      ?V*/
+	sys	irix_sigaction	4	/* 1162  sigaction()	      ?V*/
+	sys	irix_sigpending	1	/* 1163  sigpending()	      ?V*/
+	sys	irix_sigprocmask 3	/* 1164  sigprocmask()	      ?V*/
+	sys	irix_sigsuspend	0	/* 1165  sigsuspend()	      ?V*/
+	sys	irix_sigpoll_sys 3	/* 1166  sigpoll_sys()	      IV*/
+	sys	irix_swapctl	2	/* 1167  swapctl()	      IV*/
+	sys	irix_getcontext	0	/* 1168  getcontext()	      HV*/
+	sys	irix_setcontext	0	/* 1169  setcontext()	      HV*/
+	sys	irix_waitsys	5	/* 1170  waitsys()	      IV*/
+	sys	irix_sigstack	2	/* 1171  sigstack()	      HV*/
+	sys	irix_sigaltstack 2	/* 1172  sigaltstack()	      HV*/
+	sys	irix_sigsendset	2	/* 1173  sigsendset()	      IV*/
+	sys	irix_statvfs	2	/* 1174  statvfs()	       V*/
+	sys	irix_fstatvfs	2	/* 1175  fstatvfs()	       V*/
+	sys	irix_unimp	0	/* 1176  XXX getpmsg()	      DC*/
+	sys	irix_unimp	0	/* 1177  XXX putpmsg()	      DC*/
+	sys	sys_lchown	3	/* 1178  lchown()	       V*/
+	sys	irix_priocntl	0	/* 1179  priocntl()	      DC*/
+	sys	irix_sigqueue	4	/* 1180  sigqueue()	      IV*/
+	sys	sys_readv	3	/* 1181  readv()	       V*/
+	sys	sys_writev	3	/* 1182  writev()	       V*/
+	sys	irix_truncate64 4	/* 1183  truncate64() XX32bit HV*/
+	sys	irix_ftruncate64 4	/* 1184  ftruncate64()XX32bit HV*/
+	sys	irix_mmap64	0	/* 1185  mmap64()     XX32bit HV*/
+	sys	irix_dmi	0	/* 1186  dmi()		      DC*/
+	sys	irix_pread	6	/* 1187  pread()	      IV*/
+	sys	irix_pwrite	6	/* 1188  pwrite()	      IV*/
+	sys	sys_fsync	1	/* 1189  fdatasync()  XXPOSIX HV*/
+	sys	irix_sgifastpath 7	/* 1190  sgifastpath() WHEEE  IV*/
+	sys	irix_unimp	0	/* 1191  XXX attr_get()	      DC*/
+	sys	irix_unimp	0	/* 1192  XXX attr_getf()      DC*/
+	sys	irix_unimp	0	/* 1193  XXX attr_set()	      DC*/
+	sys	irix_unimp	0	/* 1194  XXX attr_setf()      DC*/
+	sys	irix_unimp	0	/* 1195  XXX attr_remove()    DC*/
+	sys	irix_unimp	0	/* 1196  XXX attr_removef()   DC*/
+	sys	irix_unimp	0	/* 1197  XXX attr_list()      DC*/
+	sys	irix_unimp	0	/* 1198  XXX attr_listf()     DC*/
+	sys	irix_unimp	0	/* 1199  XXX attr_multi()     DC*/
+	sys	irix_unimp	0	/* 1200  XXX attr_multif()    DC*/
+	sys	irix_statvfs64	2	/* 1201  statvfs64()	       V*/
+	sys	irix_fstatvfs64	2	/* 1202  fstatvfs64()	       V*/
+	sys	irix_getmountid	2	/* 1203  getmountid()XXXfsids HV*/
+	sys	irix_nsproc	5	/* 1204  nsproc()	      IV*/
+	sys	irix_getdents64 3	/* 1205  getdents64()	      HV*/
+	sys	irix_unimp	0	/* 1206  XXX DFS garbage      DC*/
+	sys	irix_ngetdents	4	/* 1207  ngetdents() XXXeop   HV*/
+	sys	irix_ngetdents64 4	/* 1208  ngetdents64() XXXeop HV*/
+	sys	irix_unimp	0	/* 1209  nothin'	       V*/
+	sys	irix_unimp	0	/* 1210  XXX pidsprocsp()	*/
+	sys	irix_unimp	0	/* 1211  XXX rexec()		*/
+	sys	irix_unimp	0	/* 1212  XXX timer_create()	*/
+	sys	irix_unimp	0	/* 1213  XXX timer_delete()	*/
+	sys	irix_unimp	0	/* 1214  XXX timer_settime()	*/
+	sys	irix_unimp	0	/* 1215  XXX timer_gettime()	*/
+	sys	irix_unimp	0	/* 1216  XXX timer_setoverrun()	*/
+	sys	sys_sched_rr_get_interval 2		/* 1217  sched_rr_get_interval()V*/
+	sys	sys_sched_yield	0	/* 1218  sched_yield()	       V*/
+	sys	sys_sched_getscheduler 1 /* 1219  sched_getscheduler()  V*/
+	sys	sys_sched_setscheduler 3 /* 1220  sched_setscheduler()  V*/
+	sys	sys_sched_getparam 2	/* 1221  sched_getparam()      V*/
+	sys	sys_sched_setparam 2	/* 1222  sched_setparam()      V*/
+	sys	irix_unimp	0	/* 1223  XXX usync_cntl()	*/
+	sys	irix_unimp	0	/* 1224  XXX psema_cntl()	*/
+	sys	irix_unimp	0	/* 1225  XXX restartreturn()	*/
+
+	/* Just to pad things out nicely. */
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+	sys	irix_unimp	0
+
+	.endm
+
+	/*
+	 * Pre-compute the number of _instruction_ bytes needed to load
+	 * or store the arguments 6-8. Negative values are ignored.
+	 */
+	.macro  sys function, nargs
+	PTR	\function
+	LONG	(\nargs << 2) - (5 << 2)
+	.endm
+
+	.align	4
+EXPORT(sys_call_table_irix5)
+	irix5syscalltable
diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
new file mode 100644
index 0000000..4af20cd
--- /dev/null
+++ b/arch/mips/kernel/irixelf.c
@@ -0,0 +1,1326 @@
+/*
+ * 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.
+ *
+ * irixelf.c: Code to load IRIX ELF executables conforming to the MIPS ABI.
+ *            Based off of work by Eric Youngdale.
+ *
+ * Copyright (C) 1993 - 1994 Eric Youngdale <ericy@cais.com>
+ * Copyright (C) 1996 - 2004 David S. Miller <dm@engr.sgi.com>
+ * Copyright (C) 2004 Steven J. Hill <sjhill@realitydiluted.com>
+ */
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/stat.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/a.out.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/signal.h>
+#include <linux/binfmts.h>
+#include <linux/string.h>
+#include <linux/file.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/shm.h>
+#include <linux/personality.h>
+#include <linux/elfcore.h>
+#include <linux/smp_lock.h>
+
+#include <asm/uaccess.h>
+#include <asm/mipsregs.h>
+#include <asm/prctl.h>
+
+#define DLINFO_ITEMS 12
+
+#include <linux/elf.h>
+
+#undef DEBUG_ELF
+
+static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs);
+static int load_irix_library(struct file *);
+static int irix_core_dump(long signr, struct pt_regs * regs,
+                          struct file *file);
+
+static struct linux_binfmt irix_format = {
+	NULL, THIS_MODULE, load_irix_binary, load_irix_library,
+	irix_core_dump, PAGE_SIZE
+};
+
+#ifndef elf_addr_t
+#define elf_addr_t unsigned long
+#endif
+
+#ifdef DEBUG_ELF
+/* Debugging routines. */
+static char *get_elf_p_type(Elf32_Word p_type)
+{
+	int i = (int) p_type;
+
+	switch(i) {
+	case PT_NULL: return("PT_NULL"); break;
+	case PT_LOAD: return("PT_LOAD"); break;
+	case PT_DYNAMIC: return("PT_DYNAMIC"); break;
+	case PT_INTERP: return("PT_INTERP"); break;
+	case PT_NOTE: return("PT_NOTE"); break;
+	case PT_SHLIB: return("PT_SHLIB"); break;
+	case PT_PHDR: return("PT_PHDR"); break;
+	case PT_LOPROC: return("PT_LOPROC/REGINFO"); break;
+	case PT_HIPROC: return("PT_HIPROC"); break;
+	default: return("PT_BOGUS"); break;
+	}
+}
+
+static void print_elfhdr(struct elfhdr *ehp)
+{
+	int i;
+
+	printk("ELFHDR: e_ident<");
+	for(i = 0; i < (EI_NIDENT - 1); i++) printk("%x ", ehp->e_ident[i]);
+	printk("%x>\n", ehp->e_ident[i]);
+	printk("        e_type[%04x] e_machine[%04x] e_version[%08lx]\n",
+	       (unsigned short) ehp->e_type, (unsigned short) ehp->e_machine,
+	       (unsigned long) ehp->e_version);
+	printk("        e_entry[%08lx] e_phoff[%08lx] e_shoff[%08lx] "
+	       "e_flags[%08lx]\n",
+	       (unsigned long) ehp->e_entry, (unsigned long) ehp->e_phoff,
+	       (unsigned long) ehp->e_shoff, (unsigned long) ehp->e_flags);
+	printk("        e_ehsize[%04x] e_phentsize[%04x] e_phnum[%04x]\n",
+	       (unsigned short) ehp->e_ehsize, (unsigned short) ehp->e_phentsize,
+	       (unsigned short) ehp->e_phnum);
+	printk("        e_shentsize[%04x] e_shnum[%04x] e_shstrndx[%04x]\n",
+	       (unsigned short) ehp->e_shentsize, (unsigned short) ehp->e_shnum,
+	       (unsigned short) ehp->e_shstrndx);
+}
+
+static void print_phdr(int i, struct elf_phdr *ep)
+{
+	printk("PHDR[%d]: p_type[%s] p_offset[%08lx] p_vaddr[%08lx] "
+	       "p_paddr[%08lx]\n", i, get_elf_p_type(ep->p_type),
+	       (unsigned long) ep->p_offset, (unsigned long) ep->p_vaddr,
+	       (unsigned long) ep->p_paddr);
+	printk("         p_filesz[%08lx] p_memsz[%08lx] p_flags[%08lx] "
+	       "p_align[%08lx]\n", (unsigned long) ep->p_filesz,
+	       (unsigned long) ep->p_memsz, (unsigned long) ep->p_flags,
+	       (unsigned long) ep->p_align);
+}
+
+static void dump_phdrs(struct elf_phdr *ep, int pnum)
+{
+	int i;
+
+	for(i = 0; i < pnum; i++, ep++) {
+		if((ep->p_type == PT_LOAD) ||
+		   (ep->p_type == PT_INTERP) ||
+		   (ep->p_type == PT_PHDR))
+			print_phdr(i, ep);
+	}
+}
+#endif /* (DEBUG_ELF) */
+
+static void set_brk(unsigned long start, unsigned long end)
+{
+	start = PAGE_ALIGN(start);
+	end = PAGE_ALIGN(end);
+	if (end <= start)
+		return;
+	down_write(&current->mm->mmap_sem);
+	do_brk(start, end - start);
+	up_write(&current->mm->mmap_sem);
+}
+
+
+/* We need to explicitly zero any fractional pages
+ * after the data section (i.e. bss).  This would
+ * contain the junk from the file that should not
+ * be in memory.
+ */
+static void padzero(unsigned long elf_bss)
+{
+	unsigned long nbyte;
+
+	nbyte = elf_bss & (PAGE_SIZE-1);
+	if (nbyte) {
+		nbyte = PAGE_SIZE - nbyte;
+		clear_user((void *) elf_bss, nbyte);
+	}
+}
+
+unsigned long * create_irix_tables(char * p, int argc, int envc,
+				   struct elfhdr * exec, unsigned int load_addr,
+				   unsigned int interp_load_addr,
+				   struct pt_regs *regs, struct elf_phdr *ephdr)
+{
+	elf_addr_t *argv;
+	elf_addr_t *envp;
+	elf_addr_t *sp, *csp;
+
+#ifdef DEBUG_ELF
+	printk("create_irix_tables: p[%p] argc[%d] envc[%d] "
+	       "load_addr[%08x] interp_load_addr[%08x]\n",
+	       p, argc, envc, load_addr, interp_load_addr);
+#endif
+	sp = (elf_addr_t *) (~15UL & (unsigned long) p);
+	csp = sp;
+	csp -= exec ? DLINFO_ITEMS*2 : 2;
+	csp -= envc+1;
+	csp -= argc+1;
+	csp -= 1;		/* argc itself */
+	if ((unsigned long)csp & 15UL) {
+		sp -= (16UL - ((unsigned long)csp & 15UL)) / sizeof(*sp);
+	}
+
+	/*
+	 * Put the ELF interpreter info on the stack
+	 */
+#define NEW_AUX_ENT(nr, id, val) \
+	  __put_user ((id), sp+(nr*2)); \
+	  __put_user ((val), sp+(nr*2+1)); \
+
+	sp -= 2;
+	NEW_AUX_ENT(0, AT_NULL, 0);
+
+	if(exec) {
+		sp -= 11*2;
+
+		NEW_AUX_ENT (0, AT_PHDR, load_addr + exec->e_phoff);
+		NEW_AUX_ENT (1, AT_PHENT, sizeof (struct elf_phdr));
+		NEW_AUX_ENT (2, AT_PHNUM, exec->e_phnum);
+		NEW_AUX_ENT (3, AT_PAGESZ, ELF_EXEC_PAGESIZE);
+		NEW_AUX_ENT (4, AT_BASE, interp_load_addr);
+		NEW_AUX_ENT (5, AT_FLAGS, 0);
+		NEW_AUX_ENT (6, AT_ENTRY, (elf_addr_t) exec->e_entry);
+		NEW_AUX_ENT (7, AT_UID, (elf_addr_t) current->uid);
+		NEW_AUX_ENT (8, AT_EUID, (elf_addr_t) current->euid);
+		NEW_AUX_ENT (9, AT_GID, (elf_addr_t) current->gid);
+		NEW_AUX_ENT (10, AT_EGID, (elf_addr_t) current->egid);
+	}
+#undef NEW_AUX_ENT
+
+	sp -= envc+1;
+	envp = sp;
+	sp -= argc+1;
+	argv = sp;
+
+	__put_user((elf_addr_t)argc,--sp);
+	current->mm->arg_start = (unsigned long) p;
+	while (argc-->0) {
+		__put_user((unsigned long)p,argv++);
+		p += strlen_user(p);
+	}
+	__put_user((unsigned long) NULL, argv);
+	current->mm->arg_end = current->mm->env_start = (unsigned long) p;
+	while (envc-->0) {
+		__put_user((unsigned long)p,envp++);
+		p += strlen_user(p);
+	}
+	__put_user((unsigned long) NULL, envp);
+	current->mm->env_end = (unsigned long) p;
+	return sp;
+}
+
+
+/* This is much more generalized than the library routine read function,
+ * so we keep this separate.  Technically the library read function
+ * is only provided so that we can read a.out libraries that have
+ * an ELF header.
+ */
+static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,
+				     struct file * interpreter,
+				     unsigned int *interp_load_addr)
+{
+	struct elf_phdr *elf_phdata  =  NULL;
+	struct elf_phdr *eppnt;
+	unsigned int len;
+	unsigned int load_addr;
+	int elf_bss;
+	int retval;
+	unsigned int last_bss;
+	int error;
+	int i;
+	unsigned int k;
+
+	elf_bss = 0;
+	last_bss = 0;
+	error = load_addr = 0;
+
+#ifdef DEBUG_ELF
+	print_elfhdr(interp_elf_ex);
+#endif
+
+	/* First of all, some simple consistency checks */
+	if ((interp_elf_ex->e_type != ET_EXEC &&
+	     interp_elf_ex->e_type != ET_DYN) ||
+	     !irix_elf_check_arch(interp_elf_ex) ||
+	     !interpreter->f_op->mmap) {
+		printk("IRIX interp has bad e_type %d\n", interp_elf_ex->e_type);
+		return 0xffffffff;
+	}
+
+	/* Now read in all of the header information */
+	if(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > PAGE_SIZE) {
+	    printk("IRIX interp header bigger than a page (%d)\n",
+		   (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum));
+	    return 0xffffffff;
+	}
+
+	elf_phdata = kmalloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum,
+			     GFP_KERNEL);
+
+	if(!elf_phdata) {
+          printk("Cannot kmalloc phdata for IRIX interp.\n");
+	  return 0xffffffff;
+	}
+
+	/* If the size of this structure has changed, then punt, since
+	 * we will be doing the wrong thing.
+	 */
+	if(interp_elf_ex->e_phentsize != 32) {
+		printk("IRIX interp e_phentsize == %d != 32 ",
+		       interp_elf_ex->e_phentsize);
+		kfree(elf_phdata);
+		return 0xffffffff;
+	}
+
+	retval = kernel_read(interpreter, interp_elf_ex->e_phoff,
+			   (char *) elf_phdata,
+			   sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
+
+#ifdef DEBUG_ELF
+	dump_phdrs(elf_phdata, interp_elf_ex->e_phnum);
+#endif
+
+	eppnt = elf_phdata;
+	for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
+	  if(eppnt->p_type == PT_LOAD) {
+	    int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
+	    int elf_prot = 0;
+	    unsigned long vaddr = 0;
+	    if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
+	    if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
+	    if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
+	    elf_type |= MAP_FIXED;
+	    vaddr = eppnt->p_vaddr;
+
+#ifdef DEBUG_ELF
+	    printk("INTERP do_mmap(%p, %08lx, %08lx, %08lx, %08lx, %08lx) ",
+		   interpreter, vaddr,
+		   (unsigned long) (eppnt->p_filesz + (eppnt->p_vaddr & 0xfff)),
+		   (unsigned long) elf_prot, (unsigned long) elf_type,
+		   (unsigned long) (eppnt->p_offset & 0xfffff000));
+#endif
+	    down_write(&current->mm->mmap_sem);
+	    error = do_mmap(interpreter, vaddr,
+			    eppnt->p_filesz + (eppnt->p_vaddr & 0xfff),
+			    elf_prot, elf_type,
+			    eppnt->p_offset & 0xfffff000);
+	    up_write(&current->mm->mmap_sem);
+
+	    if(error < 0 && error > -1024) {
+		    printk("Aieee IRIX interp mmap error=%d\n", error);
+		    break;  /* Real error */
+	    }
+#ifdef DEBUG_ELF
+	    printk("error=%08lx ", (unsigned long) error);
+#endif
+	    if(!load_addr && interp_elf_ex->e_type == ET_DYN) {
+	      load_addr = error;
+#ifdef DEBUG_ELF
+              printk("load_addr = error ");
+#endif
+	    }
+
+	    /* Find the end of the file  mapping for this phdr, and keep
+	     * track of the largest address we see for this.
+	     */
+	    k = eppnt->p_vaddr + eppnt->p_filesz;
+	    if(k > elf_bss) elf_bss = k;
+
+	    /* Do the same thing for the memory mapping - between
+	     * elf_bss and last_bss is the bss section.
+	     */
+	    k = eppnt->p_memsz + eppnt->p_vaddr;
+	    if(k > last_bss) last_bss = k;
+#ifdef DEBUG_ELF
+	    printk("\n");
+#endif
+	  }
+	}
+
+	/* Now use mmap to map the library into memory. */
+	if(error < 0 && error > -1024) {
+#ifdef DEBUG_ELF
+		printk("got error %d\n", error);
+#endif
+		kfree(elf_phdata);
+		return 0xffffffff;
+	}
+
+	/* Now fill out the bss section.  First pad the last page up
+	 * to the page boundary, and then perform a mmap to make sure
+	 * that there are zero-mapped pages up to and including the
+	 * last bss page.
+	 */
+#ifdef DEBUG_ELF
+	printk("padzero(%08lx) ", (unsigned long) (elf_bss));
+#endif
+	padzero(elf_bss);
+	len = (elf_bss + 0xfff) & 0xfffff000; /* What we have mapped so far */
+
+#ifdef DEBUG_ELF
+	printk("last_bss[%08lx] len[%08lx]\n", (unsigned long) last_bss,
+	       (unsigned long) len);
+#endif
+
+	/* Map the last of the bss segment */
+	if (last_bss > len) {
+		down_write(&current->mm->mmap_sem);
+		do_brk(len, (last_bss - len));
+		up_write(&current->mm->mmap_sem);
+	}
+	kfree(elf_phdata);
+
+	*interp_load_addr = load_addr;
+	return ((unsigned int) interp_elf_ex->e_entry);
+}
+
+/* Check sanity of IRIX elf executable header. */
+static int verify_binary(struct elfhdr *ehp, struct linux_binprm *bprm)
+{
+	if (memcmp(ehp->e_ident, ELFMAG, SELFMAG) != 0)
+		return -ENOEXEC;
+
+	/* First of all, some simple consistency checks */
+	if((ehp->e_type != ET_EXEC && ehp->e_type != ET_DYN) ||
+	    !irix_elf_check_arch(ehp) || !bprm->file->f_op->mmap) {
+		return -ENOEXEC;
+	}
+
+	/* Only support MIPS ARCH2 or greater IRIX binaries for now. */
+	if(!(ehp->e_flags & EF_MIPS_ARCH) && !(ehp->e_flags & 0x04)) {
+		return -ENOEXEC;
+	}
+
+	/* XXX Don't support N32 or 64bit binaries yet because they can
+	 * XXX and do execute 64 bit instructions and expect all registers
+	 * XXX to be 64 bit as well.  We need to make the kernel save
+	 * XXX all registers as 64bits on cpu's capable of this at
+	 * XXX exception time plus frob the XTLB exception vector.
+	 */
+	if((ehp->e_flags & 0x20)) {
+		return -ENOEXEC;
+	}
+
+	return 0; /* It's ok. */
+}
+
+#define IRIX_INTERP_PREFIX "/usr/gnemul/irix"
+
+/* Look for an IRIX ELF interpreter. */
+static inline int look_for_irix_interpreter(char **name,
+					    struct file **interpreter,
+					    struct elfhdr *interp_elf_ex,
+					    struct elf_phdr *epp,
+					    struct linux_binprm *bprm, int pnum)
+{
+	int i;
+	int retval = -EINVAL;
+	struct file *file = NULL;
+
+	*name = NULL;
+	for(i = 0; i < pnum; i++, epp++) {
+		if (epp->p_type != PT_INTERP)
+			continue;
+
+		/* It is illegal to have two interpreters for one executable. */
+		if (*name != NULL)
+			goto out;
+
+		*name = kmalloc((epp->p_filesz + strlen(IRIX_INTERP_PREFIX)),
+				GFP_KERNEL);
+		if (!*name)
+			return -ENOMEM;
+
+		strcpy(*name, IRIX_INTERP_PREFIX);
+		retval = kernel_read(bprm->file, epp->p_offset, (*name + 16),
+		                     epp->p_filesz);
+		if (retval < 0)
+			goto out;
+
+		file = open_exec(*name);
+		if (IS_ERR(file)) {
+			retval = PTR_ERR(file);
+			goto out;
+		}
+		retval = kernel_read(file, 0, bprm->buf, 128);
+		if (retval < 0)
+			goto dput_and_out;
+
+		*interp_elf_ex = *(struct elfhdr *) bprm->buf;
+	}
+	*interpreter = file;
+	return 0;
+
+dput_and_out:
+	fput(file);
+out:
+	kfree(*name);
+	return retval;
+}
+
+static inline int verify_irix_interpreter(struct elfhdr *ihp)
+{
+	if (memcmp(ihp->e_ident, ELFMAG, SELFMAG) != 0)
+		return -ELIBBAD;
+	return 0;
+}
+
+#define EXEC_MAP_FLAGS (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE)
+
+static inline void map_executable(struct file *fp, struct elf_phdr *epp, int pnum,
+				  unsigned int *estack, unsigned int *laddr,
+				  unsigned int *scode, unsigned int *ebss,
+				  unsigned int *ecode, unsigned int *edata,
+				  unsigned int *ebrk)
+{
+	unsigned int tmp;
+	int i, prot;
+
+	for(i = 0; i < pnum; i++, epp++) {
+		if(epp->p_type != PT_LOAD)
+			continue;
+
+		/* Map it. */
+		prot  = (epp->p_flags & PF_R) ? PROT_READ : 0;
+		prot |= (epp->p_flags & PF_W) ? PROT_WRITE : 0;
+		prot |= (epp->p_flags & PF_X) ? PROT_EXEC : 0;
+	        down_write(&current->mm->mmap_sem);
+		(void) do_mmap(fp, (epp->p_vaddr & 0xfffff000),
+			       (epp->p_filesz + (epp->p_vaddr & 0xfff)),
+			       prot, EXEC_MAP_FLAGS,
+			       (epp->p_offset & 0xfffff000));
+	        up_write(&current->mm->mmap_sem);
+
+		/* Fixup location tracking vars. */
+		if((epp->p_vaddr & 0xfffff000) < *estack)
+			*estack = (epp->p_vaddr & 0xfffff000);
+		if(!*laddr)
+			*laddr = epp->p_vaddr - epp->p_offset;
+		if(epp->p_vaddr < *scode)
+			*scode = epp->p_vaddr;
+
+		tmp = epp->p_vaddr + epp->p_filesz;
+		if(tmp > *ebss)
+			*ebss = tmp;
+		if((epp->p_flags & PF_X) && *ecode < tmp)
+			*ecode = tmp;
+		if(*edata < tmp)
+			*edata = tmp;
+
+		tmp = epp->p_vaddr + epp->p_memsz;
+		if(tmp > *ebrk)
+			*ebrk = tmp;
+	}
+
+}
+
+static inline int map_interpreter(struct elf_phdr *epp, struct elfhdr *ihp,
+				  struct file *interp, unsigned int *iladdr,
+				  int pnum, mm_segment_t old_fs,
+				  unsigned int *eentry)
+{
+	int i;
+
+	*eentry = 0xffffffff;
+	for(i = 0; i < pnum; i++, epp++) {
+		if(epp->p_type != PT_INTERP)
+			continue;
+
+		/* We should have fielded this error elsewhere... */
+		if(*eentry != 0xffffffff)
+			return -1;
+
+		set_fs(old_fs);
+		*eentry = load_irix_interp(ihp, interp, iladdr);
+		old_fs = get_fs();
+		set_fs(get_ds());
+
+		fput(interp);
+
+		if (*eentry == 0xffffffff)
+			return -1;
+	}
+	return 0;
+}
+
+/*
+ * IRIX maps a page at 0x200000 that holds information about the
+ * process and the system, here we map the page and fill the
+ * structure
+ */
+void irix_map_prda_page (void)
+{
+	unsigned long v;
+	struct prda *pp;
+
+	down_write(&current->mm->mmap_sem);
+	v =  do_brk (PRDA_ADDRESS, PAGE_SIZE);
+	up_write(&current->mm->mmap_sem);
+
+	if (v < 0)
+		return;
+
+	pp = (struct prda *) v;
+	pp->prda_sys.t_pid  = current->pid;
+	pp->prda_sys.t_prid = read_c0_prid();
+	pp->prda_sys.t_rpid = current->pid;
+
+	/* We leave the rest set to zero */
+}
+
+
+
+/* These are the functions used to load ELF style executables and shared
+ * libraries.  There is no binary dependent code anywhere else.
+ */
+static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
+{
+	struct elfhdr elf_ex, interp_elf_ex;
+	struct file *interpreter;
+	struct elf_phdr *elf_phdata, *elf_ihdr, *elf_ephdr;
+	unsigned int load_addr, elf_bss, elf_brk;
+	unsigned int elf_entry, interp_load_addr = 0;
+	unsigned int start_code, end_code, end_data, elf_stack;
+	int retval, has_interp, has_ephdr, size, i;
+	char *elf_interpreter;
+	mm_segment_t old_fs;
+
+	load_addr = 0;
+	has_interp = has_ephdr = 0;
+	elf_ihdr = elf_ephdr = 0;
+	elf_ex = *((struct elfhdr *) bprm->buf);
+	retval = -ENOEXEC;
+
+	if (verify_binary(&elf_ex, bprm))
+		goto out;
+
+#ifdef DEBUG_ELF
+	print_elfhdr(&elf_ex);
+#endif
+
+	/* Now read in all of the header information */
+	size = elf_ex.e_phentsize * elf_ex.e_phnum;
+	if (size > 65536)
+		goto out;
+	elf_phdata = kmalloc(size, GFP_KERNEL);
+	if (elf_phdata == NULL) {
+		retval = -ENOMEM;
+		goto out;
+	}
+
+	retval = kernel_read(bprm->file, elf_ex.e_phoff, (char *)elf_phdata, size);
+
+	if (retval < 0)
+		goto out_free_ph;
+
+#ifdef DEBUG_ELF
+	dump_phdrs(elf_phdata, elf_ex.e_phnum);
+#endif
+
+	/* Set some things for later. */
+	for(i = 0; i < elf_ex.e_phnum; i++) {
+		switch(elf_phdata[i].p_type) {
+		case PT_INTERP:
+			has_interp = 1;
+			elf_ihdr = &elf_phdata[i];
+			break;
+		case PT_PHDR:
+			has_ephdr = 1;
+			elf_ephdr = &elf_phdata[i];
+			break;
+		};
+	}
+#ifdef DEBUG_ELF
+	printk("\n");
+#endif
+
+	elf_bss = 0;
+	elf_brk = 0;
+
+	elf_stack = 0xffffffff;
+	elf_interpreter = NULL;
+	start_code = 0xffffffff;
+	end_code = 0;
+	end_data = 0;
+
+	retval = look_for_irix_interpreter(&elf_interpreter,
+	                                   &interpreter,
+					   &interp_elf_ex, elf_phdata, bprm,
+					   elf_ex.e_phnum);
+	if (retval)
+		goto out_free_file;
+
+	if (elf_interpreter) {
+		retval = verify_irix_interpreter(&interp_elf_ex);
+		if(retval)
+			goto out_free_interp;
+	}
+
+	/* OK, we are done with that, now set up the arg stuff,
+	 * and then start this sucker up.
+	 */
+	retval = -E2BIG;
+	if (!bprm->sh_bang && !bprm->p)
+		goto out_free_interp;
+
+	/* Flush all traces of the currently running executable */
+	retval = flush_old_exec(bprm);
+	if (retval)
+		goto out_free_dentry;
+
+	/* OK, This is the point of no return */
+	current->mm->end_data = 0;
+	current->mm->end_code = 0;
+	current->mm->mmap = NULL;
+	current->flags &= ~PF_FORKNOEXEC;
+	elf_entry = (unsigned int) elf_ex.e_entry;
+
+	/* Do this so that we can load the interpreter, if need be.  We will
+	 * change some of these later.
+	 */
+	set_mm_counter(current->mm, rss, 0);
+	setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT);
+	current->mm->start_stack = bprm->p;
+
+	/* At this point, we assume that the image should be loaded at
+	 * fixed address, not at a variable address.
+	 */
+	old_fs = get_fs();
+	set_fs(get_ds());
+
+	map_executable(bprm->file, elf_phdata, elf_ex.e_phnum, &elf_stack,
+	               &load_addr, &start_code, &elf_bss, &end_code,
+	               &end_data, &elf_brk);
+
+	if(elf_interpreter) {
+		retval = map_interpreter(elf_phdata, &interp_elf_ex,
+					 interpreter, &interp_load_addr,
+					 elf_ex.e_phnum, old_fs, &elf_entry);
+		kfree(elf_interpreter);
+		if(retval) {
+			set_fs(old_fs);
+			printk("Unable to load IRIX ELF interpreter\n");
+			send_sig(SIGSEGV, current, 0);
+			retval = 0;
+			goto out_free_file;
+		}
+	}
+
+	set_fs(old_fs);
+
+	kfree(elf_phdata);
+	set_personality(PER_IRIX32);
+	set_binfmt(&irix_format);
+	compute_creds(bprm);
+	current->flags &= ~PF_FORKNOEXEC;
+	bprm->p = (unsigned long)
+	  create_irix_tables((char *)bprm->p, bprm->argc, bprm->envc,
+			(elf_interpreter ? &elf_ex : NULL),
+			load_addr, interp_load_addr, regs, elf_ephdr);
+	current->mm->start_brk = current->mm->brk = elf_brk;
+	current->mm->end_code = end_code;
+	current->mm->start_code = start_code;
+	current->mm->end_data = end_data;
+	current->mm->start_stack = bprm->p;
+
+	/* Calling set_brk effectively mmaps the pages that we need for the
+	 * bss and break sections.
+	 */
+	set_brk(elf_bss, elf_brk);
+
+	/*
+	 * IRIX maps a page at 0x200000 which holds some system
+	 * information.  Programs depend on this.
+	 */
+	irix_map_prda_page ();
+
+	padzero(elf_bss);
+
+#ifdef DEBUG_ELF
+	printk("(start_brk) %lx\n" , (long) current->mm->start_brk);
+	printk("(end_code) %lx\n" , (long) current->mm->end_code);
+	printk("(start_code) %lx\n" , (long) current->mm->start_code);
+	printk("(end_data) %lx\n" , (long) current->mm->end_data);
+	printk("(start_stack) %lx\n" , (long) current->mm->start_stack);
+	printk("(brk) %lx\n" , (long) current->mm->brk);
+#endif
+
+#if 0 /* XXX No fucking way dude... */
+	/* Why this, you ask???  Well SVr4 maps page 0 as read-only,
+	 * and some applications "depend" upon this behavior.
+	 * Since we do not have the power to recompile these, we
+	 * emulate the SVr4 behavior.  Sigh.
+	 */
+	down_write(&current->mm->mmap_sem);
+	(void) do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC,
+		       MAP_FIXED | MAP_PRIVATE, 0);
+	up_write(&current->mm->mmap_sem);
+#endif
+
+	start_thread(regs, elf_entry, bprm->p);
+	if (current->ptrace & PT_PTRACED)
+		send_sig(SIGTRAP, current, 0);
+	return 0;
+out:
+	return retval;
+
+out_free_dentry:
+	allow_write_access(interpreter);
+	fput(interpreter);
+out_free_interp:
+	if (elf_interpreter)
+		kfree(elf_interpreter);
+out_free_file:
+out_free_ph:
+	kfree (elf_phdata);
+	goto out;
+}
+
+/* This is really simpleminded and specialized - we are loading an
+ * a.out library that is given an ELF header.
+ */
+static int load_irix_library(struct file *file)
+{
+	struct elfhdr elf_ex;
+	struct elf_phdr *elf_phdata  =  NULL;
+	unsigned int len = 0;
+	int elf_bss = 0;
+	int retval;
+	unsigned int bss;
+	int error;
+	int i,j, k;
+
+	error = kernel_read(file, 0, (char *) &elf_ex, sizeof(elf_ex));
+	if (error != sizeof(elf_ex))
+		return -ENOEXEC;
+
+	if (memcmp(elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
+		return -ENOEXEC;
+
+	/* First of all, some simple consistency checks. */
+	if(elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
+	   !irix_elf_check_arch(&elf_ex) || !file->f_op->mmap)
+		return -ENOEXEC;
+
+	/* Now read in all of the header information. */
+	if(sizeof(struct elf_phdr) * elf_ex.e_phnum > PAGE_SIZE)
+		return -ENOEXEC;
+
+	elf_phdata = kmalloc(sizeof(struct elf_phdr) * elf_ex.e_phnum, GFP_KERNEL);
+	if (elf_phdata == NULL)
+		return -ENOMEM;
+
+	retval = kernel_read(file, elf_ex.e_phoff, (char *) elf_phdata,
+			   sizeof(struct elf_phdr) * elf_ex.e_phnum);
+
+	j = 0;
+	for(i=0; i<elf_ex.e_phnum; i++)
+		if((elf_phdata + i)->p_type == PT_LOAD) j++;
+
+	if(j != 1)  {
+		kfree(elf_phdata);
+		return -ENOEXEC;
+	}
+
+	while(elf_phdata->p_type != PT_LOAD) elf_phdata++;
+
+	/* Now use mmap to map the library into memory. */
+	down_write(&current->mm->mmap_sem);
+	error = do_mmap(file,
+			elf_phdata->p_vaddr & 0xfffff000,
+			elf_phdata->p_filesz + (elf_phdata->p_vaddr & 0xfff),
+			PROT_READ | PROT_WRITE | PROT_EXEC,
+			MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
+			elf_phdata->p_offset & 0xfffff000);
+	up_write(&current->mm->mmap_sem);
+
+	k = elf_phdata->p_vaddr + elf_phdata->p_filesz;
+	if (k > elf_bss) elf_bss = k;
+
+	if (error != (elf_phdata->p_vaddr & 0xfffff000)) {
+		kfree(elf_phdata);
+		return error;
+	}
+
+	padzero(elf_bss);
+
+	len = (elf_phdata->p_filesz + elf_phdata->p_vaddr+ 0xfff) & 0xfffff000;
+	bss = elf_phdata->p_memsz + elf_phdata->p_vaddr;
+	if (bss > len) {
+	  down_write(&current->mm->mmap_sem);
+	  do_brk(len, bss-len);
+	  up_write(&current->mm->mmap_sem);
+	}
+	kfree(elf_phdata);
+	return 0;
+}
+
+/* Called through irix_syssgi() to map an elf image given an FD,
+ * a phdr ptr USER_PHDRP in userspace, and a count CNT telling how many
+ * phdrs there are in the USER_PHDRP array.  We return the vaddr the
+ * first phdr was successfully mapped to.
+ */
+unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt)
+{
+	struct elf_phdr *hp;
+	struct file *filp;
+	int i, retval;
+
+#ifdef DEBUG_ELF
+	printk("irix_mapelf: fd[%d] user_phdrp[%p] cnt[%d]\n",
+	       fd, user_phdrp, cnt);
+#endif
+
+	/* First get the verification out of the way. */
+	hp = user_phdrp;
+	if (!access_ok(VERIFY_READ, hp, (sizeof(struct elf_phdr) * cnt))) {
+#ifdef DEBUG_ELF
+		printk("irix_mapelf: access_ok fails!\n");
+#endif
+		return -EFAULT;
+	}
+
+#ifdef DEBUG_ELF
+	dump_phdrs(user_phdrp, cnt);
+#endif
+
+	for(i = 0; i < cnt; i++, hp++)
+		if(hp->p_type != PT_LOAD) {
+			printk("irix_mapelf: One section is not PT_LOAD!\n");
+			return -ENOEXEC;
+		}
+
+	filp = fget(fd);
+	if (!filp)
+		return -EACCES;
+	if(!filp->f_op) {
+		printk("irix_mapelf: Bogon filp!\n");
+		fput(filp);
+		return -EACCES;
+	}
+
+	hp = user_phdrp;
+	for(i = 0; i < cnt; i++, hp++) {
+		int prot;
+
+		prot  = (hp->p_flags & PF_R) ? PROT_READ : 0;
+		prot |= (hp->p_flags & PF_W) ? PROT_WRITE : 0;
+		prot |= (hp->p_flags & PF_X) ? PROT_EXEC : 0;
+		down_write(&current->mm->mmap_sem);
+		retval = do_mmap(filp, (hp->p_vaddr & 0xfffff000),
+				 (hp->p_filesz + (hp->p_vaddr & 0xfff)),
+				 prot, (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
+				 (hp->p_offset & 0xfffff000));
+		up_write(&current->mm->mmap_sem);
+
+		if(retval != (hp->p_vaddr & 0xfffff000)) {
+			printk("irix_mapelf: do_mmap fails with %d!\n", retval);
+			fput(filp);
+			return retval;
+		}
+	}
+
+#ifdef DEBUG_ELF
+	printk("irix_mapelf: Success, returning %08lx\n",
+		(unsigned long) user_phdrp->p_vaddr);
+#endif
+	fput(filp);
+	return user_phdrp->p_vaddr;
+}
+
+/*
+ * ELF core dumper
+ *
+ * Modelled on fs/exec.c:aout_core_dump()
+ * Jeremy Fitzhardinge <jeremy@sw.oz.au>
+ */
+
+/* These are the only things you should do on a core-file: use only these
+ * functions to write out all the necessary info.
+ */
+static int dump_write(struct file *file, const void *addr, int nr)
+{
+	return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
+}
+
+static int dump_seek(struct file *file, off_t off)
+{
+	if (file->f_op->llseek) {
+		if (file->f_op->llseek(file, off, 0) != off)
+			return 0;
+	} else
+		file->f_pos = off;
+	return 1;
+}
+
+/* Decide whether a segment is worth dumping; default is yes to be
+ * sure (missing info is worse than too much; etc).
+ * Personally I'd include everything, and use the coredump limit...
+ *
+ * I think we should skip something. But I am not sure how. H.J.
+ */
+static inline int maydump(struct vm_area_struct *vma)
+{
+	if (!(vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)))
+		return 0;
+#if 1
+	if (vma->vm_flags & (VM_WRITE|VM_GROWSUP|VM_GROWSDOWN))
+		return 1;
+	if (vma->vm_flags & (VM_READ|VM_EXEC|VM_EXECUTABLE|VM_SHARED))
+		return 0;
+#endif
+	return 1;
+}
+
+#define roundup(x, y)  ((((x)+((y)-1))/(y))*(y))
+
+/* An ELF note in memory. */
+struct memelfnote
+{
+	const char *name;
+	int type;
+	unsigned int datasz;
+	void *data;
+};
+
+static int notesize(struct memelfnote *en)
+{
+	int sz;
+
+	sz = sizeof(struct elf_note);
+	sz += roundup(strlen(en->name), 4);
+	sz += roundup(en->datasz, 4);
+
+	return sz;
+}
+
+/* #define DEBUG */
+
+#define DUMP_WRITE(addr, nr)	\
+	if (!dump_write(file, (addr), (nr))) \
+		goto end_coredump;
+#define DUMP_SEEK(off)	\
+	if (!dump_seek(file, (off))) \
+		goto end_coredump;
+
+static int writenote(struct memelfnote *men, struct file *file)
+{
+	struct elf_note en;
+
+	en.n_namesz = strlen(men->name);
+	en.n_descsz = men->datasz;
+	en.n_type = men->type;
+
+	DUMP_WRITE(&en, sizeof(en));
+	DUMP_WRITE(men->name, en.n_namesz);
+	/* XXX - cast from long long to long to avoid need for libgcc.a */
+	DUMP_SEEK(roundup((unsigned long)file->f_pos, 4));	/* XXX */
+	DUMP_WRITE(men->data, men->datasz);
+	DUMP_SEEK(roundup((unsigned long)file->f_pos, 4));	/* XXX */
+
+	return 1;
+
+end_coredump:
+	return 0;
+}
+#undef DUMP_WRITE
+#undef DUMP_SEEK
+
+#define DUMP_WRITE(addr, nr)	\
+	if (!dump_write(file, (addr), (nr))) \
+		goto end_coredump;
+#define DUMP_SEEK(off)	\
+	if (!dump_seek(file, (off))) \
+		goto end_coredump;
+
+/* Actual dumper.
+ *
+ * This is a two-pass process; first we find the offsets of the bits,
+ * and then they are actually written out.  If we run out of core limit
+ * we just truncate.
+ */
+static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
+{
+	int has_dumped = 0;
+	mm_segment_t fs;
+	int segs;
+	int i;
+	size_t size;
+	struct vm_area_struct *vma;
+	struct elfhdr elf;
+	off_t offset = 0, dataoff;
+	int limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
+	int numnote = 4;
+	struct memelfnote notes[4];
+	struct elf_prstatus prstatus;	/* NT_PRSTATUS */
+	elf_fpregset_t fpu;		/* NT_PRFPREG */
+	struct elf_prpsinfo psinfo;	/* NT_PRPSINFO */
+
+	/* Count what's needed to dump, up to the limit of coredump size. */
+	segs = 0;
+	size = 0;
+	for(vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
+		if (maydump(vma))
+		{
+			int sz = vma->vm_end-vma->vm_start;
+
+			if (size+sz >= limit)
+				break;
+			else
+				size += sz;
+		}
+
+		segs++;
+	}
+#ifdef DEBUG
+	printk("irix_core_dump: %d segs taking %d bytes\n", segs, size);
+#endif
+
+	/* Set up header. */
+	memcpy(elf.e_ident, ELFMAG, SELFMAG);
+	elf.e_ident[EI_CLASS] = ELFCLASS32;
+	elf.e_ident[EI_DATA] = ELFDATA2LSB;
+	elf.e_ident[EI_VERSION] = EV_CURRENT;
+	elf.e_ident[EI_OSABI] = ELF_OSABI;
+	memset(elf.e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);
+
+	elf.e_type = ET_CORE;
+	elf.e_machine = ELF_ARCH;
+	elf.e_version = EV_CURRENT;
+	elf.e_entry = 0;
+	elf.e_phoff = sizeof(elf);
+	elf.e_shoff = 0;
+	elf.e_flags = 0;
+	elf.e_ehsize = sizeof(elf);
+	elf.e_phentsize = sizeof(struct elf_phdr);
+	elf.e_phnum = segs+1;		/* Include notes. */
+	elf.e_shentsize = 0;
+	elf.e_shnum = 0;
+	elf.e_shstrndx = 0;
+
+	fs = get_fs();
+	set_fs(KERNEL_DS);
+
+	has_dumped = 1;
+	current->flags |= PF_DUMPCORE;
+
+	DUMP_WRITE(&elf, sizeof(elf));
+	offset += sizeof(elf);				/* Elf header. */
+	offset += (segs+1) * sizeof(struct elf_phdr);	/* Program headers. */
+
+	/* Set up the notes in similar form to SVR4 core dumps made
+	 * with info from their /proc.
+	 */
+	memset(&psinfo, 0, sizeof(psinfo));
+	memset(&prstatus, 0, sizeof(prstatus));
+
+	notes[0].name = "CORE";
+	notes[0].type = NT_PRSTATUS;
+	notes[0].datasz = sizeof(prstatus);
+	notes[0].data = &prstatus;
+	prstatus.pr_info.si_signo = prstatus.pr_cursig = signr;
+	prstatus.pr_sigpend = current->pending.signal.sig[0];
+	prstatus.pr_sighold = current->blocked.sig[0];
+	psinfo.pr_pid = prstatus.pr_pid = current->pid;
+	psinfo.pr_ppid = prstatus.pr_ppid = current->parent->pid;
+	psinfo.pr_pgrp = prstatus.pr_pgrp = process_group(current);
+	psinfo.pr_sid = prstatus.pr_sid = current->signal->session;
+	if (current->pid == current->tgid) {
+		/*
+		 * This is the record for the group leader.  Add in the
+		 * cumulative times of previous dead threads.  This total
+		 * won't include the time of each live thread whose state
+		 * is included in the core dump.  The final total reported
+		 * to our parent process when it calls wait4 will include
+		 * those sums as well as the little bit more time it takes
+		 * this and each other thread to finish dying after the
+		 * core dump synchronization phase.
+		 */
+		jiffies_to_timeval(current->utime + current->signal->utime,
+		                   &prstatus.pr_utime);
+		jiffies_to_timeval(current->stime + current->signal->stime,
+		                   &prstatus.pr_stime);
+	} else {
+		jiffies_to_timeval(current->utime, &prstatus.pr_utime);
+		jiffies_to_timeval(current->stime, &prstatus.pr_stime);
+	}
+	jiffies_to_timeval(current->signal->cutime, &prstatus.pr_cutime);
+	jiffies_to_timeval(current->signal->cstime, &prstatus.pr_cstime);
+
+	if (sizeof(elf_gregset_t) != sizeof(struct pt_regs)) {
+		printk("sizeof(elf_gregset_t) (%d) != sizeof(struct pt_regs) "
+		       "(%d)\n", sizeof(elf_gregset_t), sizeof(struct pt_regs));
+	} else {
+		*(struct pt_regs *)&prstatus.pr_reg = *regs;
+	}
+
+	notes[1].name = "CORE";
+	notes[1].type = NT_PRPSINFO;
+	notes[1].datasz = sizeof(psinfo);
+	notes[1].data = &psinfo;
+	i = current->state ? ffz(~current->state) + 1 : 0;
+	psinfo.pr_state = i;
+	psinfo.pr_sname = (i < 0 || i > 5) ? '.' : "RSDZTD"[i];
+	psinfo.pr_zomb = psinfo.pr_sname == 'Z';
+	psinfo.pr_nice = task_nice(current);
+	psinfo.pr_flag = current->flags;
+	psinfo.pr_uid = current->uid;
+	psinfo.pr_gid = current->gid;
+	{
+		int i, len;
+
+		set_fs(fs);
+
+		len = current->mm->arg_end - current->mm->arg_start;
+		len = len >= ELF_PRARGSZ ? ELF_PRARGSZ : len;
+		copy_from_user(&psinfo.pr_psargs,
+			       (const char *)current->mm->arg_start, len);
+		for(i = 0; i < len; i++)
+			if (psinfo.pr_psargs[i] == 0)
+				psinfo.pr_psargs[i] = ' ';
+		psinfo.pr_psargs[len] = 0;
+
+		set_fs(KERNEL_DS);
+	}
+	strlcpy(psinfo.pr_fname, current->comm, sizeof(psinfo.pr_fname));
+
+	notes[2].name = "CORE";
+	notes[2].type = NT_TASKSTRUCT;
+	notes[2].datasz = sizeof(*current);
+	notes[2].data = current;
+
+	/* Try to dump the FPU. */
+	prstatus.pr_fpvalid = dump_fpu (regs, &fpu);
+	if (!prstatus.pr_fpvalid) {
+		numnote--;
+	} else {
+		notes[3].name = "CORE";
+		notes[3].type = NT_PRFPREG;
+		notes[3].datasz = sizeof(fpu);
+		notes[3].data = &fpu;
+	}
+
+	/* Write notes phdr entry. */
+	{
+		struct elf_phdr phdr;
+		int sz = 0;
+
+		for(i = 0; i < numnote; i++)
+			sz += notesize(&notes[i]);
+
+		phdr.p_type = PT_NOTE;
+		phdr.p_offset = offset;
+		phdr.p_vaddr = 0;
+		phdr.p_paddr = 0;
+		phdr.p_filesz = sz;
+		phdr.p_memsz = 0;
+		phdr.p_flags = 0;
+		phdr.p_align = 0;
+
+		offset += phdr.p_filesz;
+		DUMP_WRITE(&phdr, sizeof(phdr));
+	}
+
+	/* Page-align dumped data. */
+	dataoff = offset = roundup(offset, PAGE_SIZE);
+
+	/* Write program headers for segments dump. */
+	for(vma = current->mm->mmap, i = 0;
+		i < segs && vma != NULL; vma = vma->vm_next) {
+		struct elf_phdr phdr;
+		size_t sz;
+
+		i++;
+
+		sz = vma->vm_end - vma->vm_start;
+
+		phdr.p_type = PT_LOAD;
+		phdr.p_offset = offset;
+		phdr.p_vaddr = vma->vm_start;
+		phdr.p_paddr = 0;
+		phdr.p_filesz = maydump(vma) ? sz : 0;
+		phdr.p_memsz = sz;
+		offset += phdr.p_filesz;
+		phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
+		if (vma->vm_flags & VM_WRITE) phdr.p_flags |= PF_W;
+		if (vma->vm_flags & VM_EXEC) phdr.p_flags |= PF_X;
+		phdr.p_align = PAGE_SIZE;
+
+		DUMP_WRITE(&phdr, sizeof(phdr));
+	}
+
+	for(i = 0; i < numnote; i++)
+		if (!writenote(&notes[i], file))
+			goto end_coredump;
+
+	set_fs(fs);
+
+	DUMP_SEEK(dataoff);
+
+	for(i = 0, vma = current->mm->mmap;
+	    i < segs && vma != NULL;
+	    vma = vma->vm_next) {
+		unsigned long addr = vma->vm_start;
+		unsigned long len = vma->vm_end - vma->vm_start;
+
+		if (!maydump(vma))
+			continue;
+		i++;
+#ifdef DEBUG
+		printk("elf_core_dump: writing %08lx %lx\n", addr, len);
+#endif
+		DUMP_WRITE((void *)addr, len);
+	}
+
+	if ((off_t) file->f_pos != offset) {
+		/* Sanity check. */
+		printk("elf_core_dump: file->f_pos (%ld) != offset (%ld)\n",
+		       (off_t) file->f_pos, offset);
+	}
+
+end_coredump:
+	set_fs(fs);
+	return has_dumped;
+}
+
+static int __init init_irix_binfmt(void)
+{
+	int init_inventory(void);
+	extern asmlinkage unsigned long sys_call_table;
+	extern asmlinkage unsigned long sys_call_table_irix5;
+
+	init_inventory();
+
+	/*
+	 * Copy the IRIX5 syscall table (8000 bytes) into the main syscall
+	 * table. The IRIX5 calls are located by an offset of 8000 bytes
+	 * from the beginning of the main table.
+	 */
+	memcpy((void *) ((unsigned long) &sys_call_table + 8000),
+		&sys_call_table_irix5, 8000);
+
+	return register_binfmt(&irix_format);
+}
+
+static void __exit exit_irix_binfmt(void)
+{
+	/* Remove the IRIX ELF loaders. */
+	unregister_binfmt(&irix_format);
+}
+
+module_init(init_irix_binfmt)
+module_exit(exit_irix_binfmt)
diff --git a/arch/mips/kernel/irixinv.c b/arch/mips/kernel/irixinv.c
new file mode 100644
index 0000000..60aa98c
--- /dev/null
+++ b/arch/mips/kernel/irixinv.c
@@ -0,0 +1,77 @@
+/*
+ * Support the inventory interface for IRIX binaries
+ * This is invoked before the mm layer is working, so we do not
+ * use the linked lists for the inventory yet.
+ *
+ * Miguel de Icaza, 1997.
+ */
+#include <linux/mm.h>
+#include <asm/inventory.h>
+#include <asm/uaccess.h>
+
+#define MAX_INVENTORY 50
+int inventory_items = 0;
+
+static inventory_t inventory [MAX_INVENTORY];
+
+void add_to_inventory (int class, int type, int controller, int unit, int state)
+{
+	inventory_t *ni = &inventory [inventory_items];
+
+	if (inventory_items == MAX_INVENTORY)
+		return;
+
+	ni->inv_class      = class;
+	ni->inv_type       = type;
+	ni->inv_controller = controller;
+	ni->inv_unit       = unit;
+	ni->inv_state      = state;
+	ni->inv_next       = ni;
+	inventory_items++;
+}
+
+int dump_inventory_to_user (void *userbuf, int size)
+{
+	inventory_t *inv  = &inventory [0];
+	inventory_t *user = userbuf;
+	int v;
+
+	if (!access_ok(VERIFY_WRITE, userbuf, size))
+		return -EFAULT;
+
+	for (v = 0; v < inventory_items; v++){
+		inv = &inventory [v];
+		copy_to_user (user, inv, sizeof (inventory_t));
+		user++;
+	}
+	return inventory_items * sizeof (inventory_t);
+}
+
+int __init init_inventory(void)
+{
+	/*
+	 * gross hack while we put the right bits all over the kernel
+	 * most likely this will not let just anyone run the X server
+	 * until we put the right values all over the place
+	 */
+	add_to_inventory (10, 3, 0, 0, 16400);
+	add_to_inventory (1, 1, 150, -1, 12);
+	add_to_inventory (1, 3, 0, 0, 8976);
+	add_to_inventory (1, 2, 0, 0, 8976);
+	add_to_inventory (4, 8, 0, 0, 2);
+	add_to_inventory (5, 5, 0, 0, 1);
+	add_to_inventory (3, 3, 0, 0, 32768);
+	add_to_inventory (3, 4, 0, 0, 32768);
+	add_to_inventory (3, 8, 0, 0, 524288);
+	add_to_inventory (3, 9, 0, 0, 64);
+	add_to_inventory (3, 1, 0, 0, 67108864);
+	add_to_inventory (12, 3, 0, 0, 16);
+	add_to_inventory (8, 7, 17, 0, 16777472);
+	add_to_inventory (8, 0, 0, 0, 1);
+	add_to_inventory (2, 1, 0, 13, 2);
+	add_to_inventory (2, 2, 0, 2, 0);
+	add_to_inventory (2, 2, 0, 1, 0);
+	add_to_inventory (7, 14, 0, 0, 6);
+
+	return 0;
+}
diff --git a/arch/mips/kernel/irixioctl.c b/arch/mips/kernel/irixioctl.c
new file mode 100644
index 0000000..4cd3d38
--- /dev/null
+++ b/arch/mips/kernel/irixioctl.c
@@ -0,0 +1,261 @@
+/*
+ * irixioctl.c: A fucking mess...
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/sockios.h>
+#include <linux/syscalls.h>
+#include <linux/tty.h>
+#include <linux/file.h>
+
+#include <asm/uaccess.h>
+#include <asm/ioctl.h>
+#include <asm/ioctls.h>
+
+#undef DEBUG_IOCTLS
+#undef DEBUG_MISSING_IOCTL
+
+struct irix_termios {
+	tcflag_t c_iflag, c_oflag, c_cflag, c_lflag;
+	cc_t c_cc[NCCS];
+};
+
+extern void start_tty(struct tty_struct *tty);
+static struct tty_struct *get_tty(int fd)
+{
+	struct file *filp;
+	struct tty_struct *ttyp = NULL;
+
+	spin_lock(&current->files->file_lock);
+	filp = fcheck(fd);
+	if(filp && filp->private_data) {
+		ttyp = (struct tty_struct *) filp->private_data;
+
+		if(ttyp->magic != TTY_MAGIC)
+			ttyp =NULL;
+	}
+	spin_unlock(&current->files->file_lock);
+	return ttyp;
+}
+
+static struct tty_struct *get_real_tty(struct tty_struct *tp)
+{
+	if (tp->driver->type == TTY_DRIVER_TYPE_PTY &&
+	   tp->driver->subtype == PTY_TYPE_MASTER)
+		return tp->link;
+	else
+		return tp;
+}
+
+asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg)
+{
+	struct tty_struct *tp, *rtp;
+	mm_segment_t old_fs;
+	int error = 0;
+
+#ifdef DEBUG_IOCTLS
+	printk("[%s:%d] irix_ioctl(%d, ", current->comm, current->pid, fd);
+#endif
+	switch(cmd) {
+	case 0x00005401:
+#ifdef DEBUG_IOCTLS
+		printk("TCGETA, %08lx) ", arg);
+#endif
+		error = sys_ioctl(fd, TCGETA, arg);
+		break;
+
+	case 0x0000540d: {
+		struct termios kt;
+		struct irix_termios *it = (struct irix_termios *) arg;
+
+#ifdef DEBUG_IOCTLS
+		printk("TCGETS, %08lx) ", arg);
+#endif
+		if(!access_ok(VERIFY_WRITE, it, sizeof(*it))) {
+			error = -EFAULT;
+			break;
+		}
+		old_fs = get_fs(); set_fs(get_ds());
+		error = sys_ioctl(fd, TCGETS, (unsigned long) &kt);
+		set_fs(old_fs);
+		if (error)
+			break;
+		__put_user(kt.c_iflag, &it->c_iflag);
+		__put_user(kt.c_oflag, &it->c_oflag);
+		__put_user(kt.c_cflag, &it->c_cflag);
+		__put_user(kt.c_lflag, &it->c_lflag);
+		for(error = 0; error < NCCS; error++)
+			__put_user(kt.c_cc[error], &it->c_cc[error]);
+		error = 0;
+		break;
+	}
+
+	case 0x0000540e: {
+		struct termios kt;
+		struct irix_termios *it = (struct irix_termios *) arg;
+
+#ifdef DEBUG_IOCTLS
+		printk("TCSETS, %08lx) ", arg);
+#endif
+		if (!access_ok(VERIFY_READ, it, sizeof(*it))) {
+			error = -EFAULT;
+			break;
+		}
+		old_fs = get_fs(); set_fs(get_ds());
+		error = sys_ioctl(fd, TCGETS, (unsigned long) &kt);
+		set_fs(old_fs);
+		if(error)
+			break;
+		__get_user(kt.c_iflag, &it->c_iflag);
+		__get_user(kt.c_oflag, &it->c_oflag);
+		__get_user(kt.c_cflag, &it->c_cflag);
+		__get_user(kt.c_lflag, &it->c_lflag);
+		for(error = 0; error < NCCS; error++)
+			__get_user(kt.c_cc[error], &it->c_cc[error]);
+		old_fs = get_fs(); set_fs(get_ds());
+		error = sys_ioctl(fd, TCSETS, (unsigned long) &kt);
+		set_fs(old_fs);
+		break;
+	}
+
+	case 0x0000540f:
+#ifdef DEBUG_IOCTLS
+		printk("TCSETSW, %08lx) ", arg);
+#endif
+		error = sys_ioctl(fd, TCSETSW, arg);
+		break;
+
+	case 0x00005471:
+#ifdef DEBUG_IOCTLS
+		printk("TIOCNOTTY, %08lx) ", arg);
+#endif
+		error = sys_ioctl(fd, TIOCNOTTY, arg);
+		break;
+
+	case 0x00007416:
+#ifdef DEBUG_IOCTLS
+		printk("TIOCGSID, %08lx) ", arg);
+#endif
+		tp = get_tty(fd);
+		if(!tp) {
+			error = -EINVAL;
+			break;
+		}
+		rtp = get_real_tty(tp);
+#ifdef DEBUG_IOCTLS
+		printk("rtp->session=%d ", rtp->session);
+#endif
+		error = put_user(rtp->session, (unsigned long *) arg);
+		break;
+
+	case 0x746e:
+		/* TIOCSTART, same effect as hitting ^Q */
+#ifdef DEBUG_IOCTLS
+		printk("TIOCSTART, %08lx) ", arg);
+#endif
+		tp = get_tty(fd);
+		if(!tp) {
+			error = -EINVAL;
+			break;
+		}
+		rtp = get_real_tty(tp);
+		start_tty(rtp);
+		break;
+
+	case 0x20006968:
+#ifdef DEBUG_IOCTLS
+		printk("SIOCGETLABEL, %08lx) ", arg);
+#endif
+		error = -ENOPKG;
+		break;
+
+	case 0x40047477:
+#ifdef DEBUG_IOCTLS
+		printk("TIOCGPGRP, %08lx) ", arg);
+#endif
+		error = sys_ioctl(fd, TIOCGPGRP, arg);
+#ifdef DEBUG_IOCTLS
+		printk("arg=%d ", *(int *)arg);
+#endif
+		break;
+
+	case 0x40087468:
+#ifdef DEBUG_IOCTLS
+		printk("TIOCGWINSZ, %08lx) ", arg);
+#endif
+		error = sys_ioctl(fd, TIOCGWINSZ, arg);
+		break;
+
+	case 0x8004667e:
+#ifdef DEBUG_IOCTLS
+		printk("FIONBIO, %08lx) arg=%d ", arg, *(int *)arg);
+#endif
+		error = sys_ioctl(fd, FIONBIO, arg);
+		break;
+
+	case 0x80047476:
+#ifdef DEBUG_IOCTLS
+		printk("TIOCSPGRP, %08lx) arg=%d ", arg, *(int *)arg);
+#endif
+		error = sys_ioctl(fd, TIOCSPGRP, arg);
+		break;
+
+	case 0x8020690c:
+#ifdef DEBUG_IOCTLS
+		printk("SIOCSIFADDR, %08lx) arg=%d ", arg, *(int *)arg);
+#endif
+		error = sys_ioctl(fd, SIOCSIFADDR, arg);
+		break;
+
+	case 0x80206910:
+#ifdef DEBUG_IOCTLS
+		printk("SIOCSIFFLAGS, %08lx) arg=%d ", arg, *(int *)arg);
+#endif
+		error = sys_ioctl(fd, SIOCSIFFLAGS, arg);
+		break;
+
+	case 0xc0206911:
+#ifdef DEBUG_IOCTLS
+		printk("SIOCGIFFLAGS, %08lx) arg=%d ", arg, *(int *)arg);
+#endif
+		error = sys_ioctl(fd, SIOCGIFFLAGS, arg);
+		break;
+
+	case 0xc020691b:
+#ifdef DEBUG_IOCTLS
+		printk("SIOCGIFMETRIC, %08lx) arg=%d ", arg, *(int *)arg);
+#endif
+		error = sys_ioctl(fd, SIOCGIFMETRIC, arg);
+		break;
+
+	default: {
+#ifdef DEBUG_MISSING_IOCTL
+		char *msg = "Unimplemented IOCTL cmd tell linux@engr.sgi.com\n";
+
+#ifdef DEBUG_IOCTLS
+		printk("UNIMP_IOCTL, %08lx)\n", arg);
+#endif
+		old_fs = get_fs(); set_fs(get_ds());
+		sys_write(2, msg, strlen(msg));
+		set_fs(old_fs);
+		printk("[%s:%d] Does unimplemented IRIX ioctl cmd %08lx\n",
+		       current->comm, current->pid, cmd);
+		do_exit(255);
+#else
+		error = sys_ioctl (fd, cmd, arg);
+#endif
+	}
+
+	};
+#ifdef DEBUG_IOCTLS
+	printk("error=%d\n", error);
+#endif
+	return error;
+}
diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
new file mode 100644
index 0000000..3f956f8
--- /dev/null
+++ b/arch/mips/kernel/irixsig.c
@@ -0,0 +1,853 @@
+/*
+ * irixsig.c: WHEEE, IRIX signals!  YOW, am I compatible or what?!?!
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997 - 2000 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 2000 Silicon Graphics, Inc.
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/time.h>
+#include <linux/ptrace.h>
+
+#include <asm/ptrace.h>
+#include <asm/uaccess.h>
+
+#undef DEBUG_SIG
+
+#define _S(nr) (1<<((nr)-1))
+
+#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
+
+typedef struct {
+	unsigned long sig[4];
+} irix_sigset_t;
+
+struct sigctx_irix5 {
+	u32 rmask, cp0_status;
+	u64 pc;
+	u64 regs[32];
+	u64 fpregs[32];
+	u32 usedfp, fpcsr, fpeir, sstk_flags;
+	u64 hi, lo;
+	u64 cp0_cause, cp0_badvaddr, _unused0;
+	irix_sigset_t sigset;
+	u64 weird_fpu_thing;
+	u64 _unused1[31];
+};
+
+#ifdef DEBUG_SIG
+/* Debugging */
+static inline void dump_irix5_sigctx(struct sigctx_irix5 *c)
+{
+	int i;
+
+	printk("misc: rmask[%08lx] status[%08lx] pc[%08lx]\n",
+	       (unsigned long) c->rmask,
+	       (unsigned long) c->cp0_status,
+	       (unsigned long) c->pc);
+	printk("regs: ");
+	for(i = 0; i < 16; i++)
+		printk("[%d]<%08lx> ", i, (unsigned long) c->regs[i]);
+	printk("\nregs: ");
+	for(i = 16; i < 32; i++)
+		printk("[%d]<%08lx> ", i, (unsigned long) c->regs[i]);
+	printk("\nfpregs: ");
+	for(i = 0; i < 16; i++)
+		printk("[%d]<%08lx> ", i, (unsigned long) c->fpregs[i]);
+	printk("\nfpregs: ");
+	for(i = 16; i < 32; i++)
+		printk("[%d]<%08lx> ", i, (unsigned long) c->fpregs[i]);
+	printk("misc: usedfp[%d] fpcsr[%08lx] fpeir[%08lx] stk_flgs[%08lx]\n",
+	       (int) c->usedfp, (unsigned long) c->fpcsr,
+	       (unsigned long) c->fpeir, (unsigned long) c->sstk_flags);
+	printk("misc: hi[%08lx] lo[%08lx] cause[%08lx] badvaddr[%08lx]\n",
+	       (unsigned long) c->hi, (unsigned long) c->lo,
+	       (unsigned long) c->cp0_cause, (unsigned long) c->cp0_badvaddr);
+	printk("misc: sigset<0>[%08lx] sigset<1>[%08lx] sigset<2>[%08lx] "
+	       "sigset<3>[%08lx]\n", (unsigned long) c->sigset.sig[0],
+	       (unsigned long) c->sigset.sig[1],
+	       (unsigned long) c->sigset.sig[2],
+	       (unsigned long) c->sigset.sig[3]);
+}
+#endif
+
+static void setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs,
+			     int signr, sigset_t *oldmask)
+{
+	unsigned long sp;
+	struct sigctx_irix5 *ctx;
+	int i;
+
+	sp = regs->regs[29];
+	sp -= sizeof(struct sigctx_irix5);
+	sp &= ~(0xf);
+	ctx = (struct sigctx_irix5 *) sp;
+	if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx)))
+		goto segv_and_exit;
+
+	__put_user(0, &ctx->weird_fpu_thing);
+	__put_user(~(0x00000001), &ctx->rmask);
+	__put_user(0, &ctx->regs[0]);
+	for(i = 1; i < 32; i++)
+		__put_user((u64) regs->regs[i], &ctx->regs[i]);
+
+	__put_user((u64) regs->hi, &ctx->hi);
+	__put_user((u64) regs->lo, &ctx->lo);
+	__put_user((u64) regs->cp0_epc, &ctx->pc);
+	__put_user(!!used_math(), &ctx->usedfp);
+	__put_user((u64) regs->cp0_cause, &ctx->cp0_cause);
+	__put_user((u64) regs->cp0_badvaddr, &ctx->cp0_badvaddr);
+
+	__put_user(0, &ctx->sstk_flags); /* XXX sigstack unimp... todo... */
+
+	__copy_to_user(&ctx->sigset, oldmask, sizeof(irix_sigset_t));
+
+#ifdef DEBUG_SIG
+	dump_irix5_sigctx(ctx);
+#endif
+
+	regs->regs[4] = (unsigned long) signr;
+	regs->regs[5] = 0; /* XXX sigcode XXX */
+	regs->regs[6] = regs->regs[29] = sp;
+	regs->regs[7] = (unsigned long) ka->sa.sa_handler;
+	regs->regs[25] = regs->cp0_epc = (unsigned long) ka->sa_restorer;
+
+	return;
+
+segv_and_exit:
+	force_sigsegv(signr, current);
+}
+
+static void inline
+setup_irix_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
+               int signr, sigset_t *oldmask, siginfo_t *info)
+{
+	printk("Aiee: setup_tr_frame wants to be written");
+	do_exit(SIGSEGV);
+}
+
+static inline void handle_signal(unsigned long sig, siginfo_t *info,
+	struct k_sigaction *ka, sigset_t *oldset, struct pt_regs * regs)
+{
+	switch(regs->regs[0]) {
+	case ERESTARTNOHAND:
+		regs->regs[2] = EINTR;
+		break;
+	case ERESTARTSYS:
+		if(!(ka->sa.sa_flags & SA_RESTART)) {
+			regs->regs[2] = EINTR;
+			break;
+		}
+	/* fallthrough */
+	case ERESTARTNOINTR:		/* Userland will reload $v0.  */
+		regs->cp0_epc -= 8;
+	}
+
+	regs->regs[0] = 0;		/* Don't deal with this again.  */
+
+	if (ka->sa.sa_flags & SA_SIGINFO)
+		setup_irix_rt_frame(ka, regs, sig, oldset, info);
+	else
+		setup_irix_frame(ka, regs, sig, oldset);
+
+	if (!(ka->sa.sa_flags & SA_NODEFER)) {
+		spin_lock_irq(&current->sighand->siglock);
+		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+		sigaddset(&current->blocked,sig);
+		recalc_sigpending();
+		spin_unlock_irq(&current->sighand->siglock);
+	}
+}
+
+asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs)
+{
+	struct k_sigaction ka;
+	siginfo_t info;
+	int signr;
+
+	/*
+	 * We want the common case to go fast, which is why we may in certain
+	 * cases get here from kernel mode. Just return without doing anything
+	 * if so.
+	 */
+	if (!user_mode(regs))
+		return 1;
+
+	if (try_to_freeze(0))
+		goto no_signal;
+
+	if (!oldset)
+		oldset = &current->blocked;
+
+	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+	if (signr > 0) {
+		handle_signal(signr, &info, &ka, oldset, regs);
+		return 1;
+	}
+
+no_signal:
+	/*
+	 * Who's code doesn't conform to the restartable syscall convention
+	 * dies here!!!  The li instruction, a single machine instruction,
+	 * must directly be followed by the syscall instruction.
+	 */
+	if (regs->regs[0]) {
+		if (regs->regs[2] == ERESTARTNOHAND ||
+		    regs->regs[2] == ERESTARTSYS ||
+		    regs->regs[2] == ERESTARTNOINTR) {
+			regs->cp0_epc -= 8;
+		}
+	}
+	return 0;
+}
+
+asmlinkage void
+irix_sigreturn(struct pt_regs *regs)
+{
+	struct sigctx_irix5 *context, *magic;
+	unsigned long umask, mask;
+	u64 *fregs;
+	int sig, i, base = 0;
+	sigset_t blocked;
+
+	/* Always make any pending restarted system calls return -EINTR */
+	current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
+	if (regs->regs[2] == 1000)
+		base = 1;
+
+	context = (struct sigctx_irix5 *) regs->regs[base + 4];
+	magic = (struct sigctx_irix5 *) regs->regs[base + 5];
+	sig = (int) regs->regs[base + 6];
+#ifdef DEBUG_SIG
+	printk("[%s:%d] IRIX sigreturn(scp[%p],ucp[%p],sig[%d])\n",
+	       current->comm, current->pid, context, magic, sig);
+#endif
+	if (!context)
+		context = magic;
+	if (!access_ok(VERIFY_READ, context, sizeof(struct sigctx_irix5)))
+		goto badframe;
+
+#ifdef DEBUG_SIG
+	dump_irix5_sigctx(context);
+#endif
+
+	__get_user(regs->cp0_epc, &context->pc);
+	umask = context->rmask; mask = 2;
+	for (i = 1; i < 32; i++, mask <<= 1) {
+		if(umask & mask)
+			__get_user(regs->regs[i], &context->regs[i]);
+	}
+	__get_user(regs->hi, &context->hi);
+	__get_user(regs->lo, &context->lo);
+
+	if ((umask & 1) && context->usedfp) {
+		fregs = (u64 *) &current->thread.fpu;
+		for(i = 0; i < 32; i++)
+			fregs[i] = (u64) context->fpregs[i];
+		__get_user(current->thread.fpu.hard.fcr31, &context->fpcsr);
+	}
+
+	/* XXX do sigstack crapola here... XXX */
+
+	if (__copy_from_user(&blocked, &context->sigset, sizeof(blocked)))
+		goto badframe;
+
+	sigdelsetmask(&blocked, ~_BLOCKABLE);
+	spin_lock_irq(&current->sighand->siglock);
+	current->blocked = blocked;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	/*
+	 * Don't let your children do this ...
+	 */
+	if (current_thread_info()->flags & TIF_SYSCALL_TRACE)
+		do_syscall_trace(regs, 1);
+	__asm__ __volatile__(
+		"move\t$29,%0\n\t"
+		"j\tsyscall_exit"
+		:/* no outputs */
+		:"r" (&regs));
+		/* Unreached */
+
+badframe:
+	force_sig(SIGSEGV, current);
+}
+
+struct sigact_irix5 {
+	int flags;
+	void (*handler)(int);
+	u32 sigset[4];
+	int _unused0[2];
+};
+
+#ifdef DEBUG_SIG
+static inline void dump_sigact_irix5(struct sigact_irix5 *p)
+{
+	printk("<f[%d] hndlr[%08lx] msk[%08lx]>", p->flags,
+	       (unsigned long) p->handler,
+	       (unsigned long) p->sigset[0]);
+}
+#endif
+
+asmlinkage int
+irix_sigaction(int sig, const struct sigaction *act,
+	      struct sigaction *oact, void *trampoline)
+{
+	struct k_sigaction new_ka, old_ka;
+	int ret;
+
+#ifdef DEBUG_SIG
+	printk(" (%d,%s,%s,%08lx) ", sig, (!new ? "0" : "NEW"),
+	       (!old ? "0" : "OLD"), trampoline);
+	if(new) {
+		dump_sigact_irix5(new); printk(" ");
+	}
+#endif
+	if (act) {
+		sigset_t mask;
+		if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
+		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+		    __get_user(new_ka.sa.sa_flags, &act->sa_flags))
+			return -EFAULT;
+
+		__copy_from_user(&mask, &act->sa_mask, sizeof(sigset_t));
+
+		/*
+		 * Hmmm... methinks IRIX libc always passes a valid trampoline
+		 * value for all invocations of sigaction.  Will have to
+		 * investigate.  POSIX POSIX, die die die...
+		 */
+		new_ka.sa_restorer = trampoline;
+	}
+
+/* XXX Implement SIG_SETMASK32 for IRIX compatibility */
+	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+	if (!ret && oact) {
+		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
+		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+		    __put_user(old_ka.sa.sa_flags, &oact->sa_flags))
+			return -EFAULT;
+		__copy_to_user(&old_ka.sa.sa_mask, &oact->sa_mask,
+		               sizeof(sigset_t));
+	}
+
+	return ret;
+}
+
+asmlinkage int irix_sigpending(irix_sigset_t *set)
+{
+	return do_sigpending(set, sizeof(*set));
+}
+
+asmlinkage int irix_sigprocmask(int how, irix_sigset_t *new, irix_sigset_t *old)
+{
+	sigset_t oldbits, newbits;
+
+	if (new) {
+		if (!access_ok(VERIFY_READ, new, sizeof(*new)))
+			return -EFAULT;
+		__copy_from_user(&newbits, new, sizeof(unsigned long)*4);
+		sigdelsetmask(&newbits, ~_BLOCKABLE);
+
+		spin_lock_irq(&current->sighand->siglock);
+		oldbits = current->blocked;
+
+		switch(how) {
+		case 1:
+			sigorsets(&newbits, &oldbits, &newbits);
+			break;
+
+		case 2:
+			sigandsets(&newbits, &oldbits, &newbits);
+			break;
+
+		case 3:
+			break;
+
+		case 256:
+			siginitset(&newbits, newbits.sig[0]);
+			break;
+
+		default:
+			return -EINVAL;
+		}
+		recalc_sigpending();
+		spin_unlock_irq(&current->sighand->siglock);
+	}
+	if(old) {
+		if (!access_ok(VERIFY_WRITE, old, sizeof(*old)))
+			return -EFAULT;
+		__copy_to_user(old, &current->blocked, sizeof(unsigned long)*4);
+	}
+
+	return 0;
+}
+
+asmlinkage int irix_sigsuspend(struct pt_regs *regs)
+{
+	sigset_t *uset, saveset, newset;
+
+	uset = (sigset_t *) regs->regs[4];
+	if (copy_from_user(&newset, uset, sizeof(sigset_t)))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sighand->siglock);
+	saveset = current->blocked;
+	current->blocked = newset;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	regs->regs[2] = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_irix_signal(&saveset, regs))
+			return -EINTR;
+	}
+}
+
+/* hate hate hate... */
+struct irix5_siginfo {
+	int sig, code, error;
+	union {
+		char unused[128 - (3 * 4)]; /* Safety net. */
+		struct {
+			int pid;
+			union {
+				int uid;
+				struct {
+					int utime, status, stime;
+				} child;
+			} procdata;
+		} procinfo;
+
+		unsigned long fault_addr;
+
+		struct {
+			int fd;
+			long band;
+		} fileinfo;
+
+		unsigned long sigval;
+	} stuff;
+};
+
+static inline unsigned long timespectojiffies(struct timespec *value)
+{
+	unsigned long sec = (unsigned) value->tv_sec;
+	long nsec = value->tv_nsec;
+
+	if (sec > (LONG_MAX / HZ))
+		return LONG_MAX;
+	nsec += 1000000000L / HZ - 1;
+	nsec /= 1000000000L / HZ;
+	return HZ * sec + nsec;
+}
+
+asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info,
+				struct timespec *tp)
+{
+	long expire = MAX_SCHEDULE_TIMEOUT;
+	sigset_t kset;
+	int i, sig, error, timeo = 0;
+
+#ifdef DEBUG_SIG
+	printk("[%s:%d] irix_sigpoll_sys(%p,%p,%p)\n",
+	       current->comm, current->pid, set, info, tp);
+#endif
+
+	/* Must always specify the signal set. */
+	if (!set)
+		return -EINVAL;
+
+	if (!access_ok(VERIFY_READ, set, sizeof(kset))) {
+		error = -EFAULT;
+		goto out;
+	}
+
+	__copy_from_user(&kset, set, sizeof(set));
+	if (error)
+		goto out;
+
+	if (info && clear_user(info, sizeof(*info))) {
+		error = -EFAULT;
+		goto out;
+	}
+
+	if (tp) {
+		if (!access_ok(VERIFY_READ, tp, sizeof(*tp)))
+			return -EFAULT;
+		if (!tp->tv_sec && !tp->tv_nsec) {
+			error = -EINVAL;
+			goto out;
+		}
+		expire = timespectojiffies(tp)+(tp->tv_sec||tp->tv_nsec);
+	}
+
+	while(1) {
+		long tmp = 0;
+
+		current->state = TASK_INTERRUPTIBLE;
+		expire = schedule_timeout(expire);
+
+		for (i=0; i<=4; i++)
+			tmp |= (current->pending.signal.sig[i] & kset.sig[i]);
+
+		if (tmp)
+			break;
+		if (!expire) {
+			timeo = 1;
+			break;
+		}
+		if (signal_pending(current))
+			return -EINTR;
+	}
+	if (timeo)
+		return -EAGAIN;
+
+	for(sig = 1; i <= 65 /* IRIX_NSIG */; sig++) {
+		if (sigismember (&kset, sig))
+			continue;
+		if (sigismember (&current->pending.signal, sig)) {
+			/* XXX need more than this... */
+			if (info)
+				info->sig = sig;
+			error = 0;
+			goto out;
+		}
+	}
+
+	/* Should not get here, but do something sane if we do. */
+	error = -EINTR;
+
+out:
+	return error;
+}
+
+/* This is here because of irix5_siginfo definition. */
+#define IRIX_P_PID    0
+#define IRIX_P_PGID   2
+#define IRIX_P_ALL    7
+
+extern int getrusage(struct task_struct *, int, struct rusage __user *);
+
+#define W_EXITED     1
+#define W_TRAPPED    2
+#define W_STOPPED    4
+#define W_CONT       8
+#define W_NOHANG    64
+
+#define W_MASK      (W_EXITED | W_TRAPPED | W_STOPPED | W_CONT | W_NOHANG)
+
+asmlinkage int irix_waitsys(int type, int pid, struct irix5_siginfo *info,
+			    int options, struct rusage *ru)
+{
+	int flag, retval;
+	DECLARE_WAITQUEUE(wait, current);
+	struct task_struct *tsk;
+	struct task_struct *p;
+	struct list_head *_p;
+
+	if (!info) {
+		retval = -EINVAL;
+		goto out;
+	}
+	if (!access_ok(VERIFY_WRITE, info, sizeof(*info))) {
+		retval = -EFAULT;
+		goto out;
+	}
+	if (ru) {
+		if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru))) {
+			retval = -EFAULT;
+			goto out;
+		}
+	}
+	if (options & ~(W_MASK)) {
+		retval = -EINVAL;
+		goto out;
+	}
+	if (type != IRIX_P_PID && type != IRIX_P_PGID && type != IRIX_P_ALL) {
+		retval = -EINVAL;
+		goto out;
+	}
+	add_wait_queue(&current->signal->wait_chldexit, &wait);
+repeat:
+	flag = 0;
+	current->state = TASK_INTERRUPTIBLE;
+	read_lock(&tasklist_lock);
+	tsk = current;
+	list_for_each(_p,&tsk->children) {
+		p = list_entry(_p,struct task_struct,sibling);
+		if ((type == IRIX_P_PID) && p->pid != pid)
+			continue;
+		if ((type == IRIX_P_PGID) && process_group(p) != pid)
+			continue;
+		if ((p->exit_signal != SIGCHLD))
+			continue;
+		flag = 1;
+		switch (p->state) {
+		case TASK_STOPPED:
+			if (!p->exit_code)
+				continue;
+			if (!(options & (W_TRAPPED|W_STOPPED)) &&
+			    !(p->ptrace & PT_PTRACED))
+				continue;
+			read_unlock(&tasklist_lock);
+
+			/* move to end of parent's list to avoid starvation */
+			write_lock_irq(&tasklist_lock);
+			remove_parent(p);
+			add_parent(p, p->parent);
+			write_unlock_irq(&tasklist_lock);
+			retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
+			if (!retval && ru) {
+				retval |= __put_user(SIGCHLD, &info->sig);
+				retval |= __put_user(0, &info->code);
+				retval |= __put_user(p->pid, &info->stuff.procinfo.pid);
+				retval |= __put_user((p->exit_code >> 8) & 0xff,
+				           &info->stuff.procinfo.procdata.child.status);
+				retval |= __put_user(p->utime, &info->stuff.procinfo.procdata.child.utime);
+				retval |= __put_user(p->stime, &info->stuff.procinfo.procdata.child.stime);
+			}
+			if (!retval) {
+				p->exit_code = 0;
+			}
+			goto end_waitsys;
+
+		case EXIT_ZOMBIE:
+			current->signal->cutime += p->utime + p->signal->cutime;
+			current->signal->cstime += p->stime + p->signal->cstime;
+			if (ru != NULL)
+				getrusage(p, RUSAGE_BOTH, ru);
+			__put_user(SIGCHLD, &info->sig);
+			__put_user(1, &info->code);      /* CLD_EXITED */
+			__put_user(p->pid, &info->stuff.procinfo.pid);
+			__put_user((p->exit_code >> 8) & 0xff,
+			           &info->stuff.procinfo.procdata.child.status);
+			__put_user(p->utime,
+			           &info->stuff.procinfo.procdata.child.utime);
+			__put_user(p->stime,
+			           &info->stuff.procinfo.procdata.child.stime);
+			retval = 0;
+			if (p->real_parent != p->parent) {
+				write_lock_irq(&tasklist_lock);
+				remove_parent(p);
+				p->parent = p->real_parent;
+				add_parent(p, p->parent);
+				do_notify_parent(p, SIGCHLD);
+				write_unlock_irq(&tasklist_lock);
+			} else
+				release_task(p);
+			goto end_waitsys;
+		default:
+			continue;
+		}
+		tsk = next_thread(tsk);
+	}
+	read_unlock(&tasklist_lock);
+	if (flag) {
+		retval = 0;
+		if (options & W_NOHANG)
+			goto end_waitsys;
+		retval = -ERESTARTSYS;
+		if (signal_pending(current))
+			goto end_waitsys;
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		goto repeat;
+	}
+	retval = -ECHILD;
+end_waitsys:
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&current->signal->wait_chldexit, &wait);
+
+out:
+	return retval;
+}
+
+struct irix5_context {
+	u32 flags;
+	u32 link;
+	u32 sigmask[4];
+	struct { u32 sp, size, flags; } stack;
+	int regs[36];
+	u32 fpregs[32];
+	u32 fpcsr;
+	u32 _unused0;
+	u32 _unused1[47];
+	u32 weird_graphics_thing;
+};
+
+asmlinkage int irix_getcontext(struct pt_regs *regs)
+{
+	int i, base = 0;
+	struct irix5_context *ctx;
+	unsigned long flags;
+
+	if (regs->regs[2] == 1000)
+		base = 1;
+	ctx = (struct irix5_context *) regs->regs[base + 4];
+
+#ifdef DEBUG_SIG
+	printk("[%s:%d] irix_getcontext(%p)\n",
+	       current->comm, current->pid, ctx);
+#endif
+
+	if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx)))
+		return -EFAULT;
+
+	__put_user(current->thread.irix_oldctx, &ctx->link);
+
+	__copy_to_user(&ctx->sigmask, &current->blocked, sizeof(irix_sigset_t));
+
+	/* XXX Do sigstack stuff someday... */
+	__put_user(0, &ctx->stack.sp);
+	__put_user(0, &ctx->stack.size);
+	__put_user(0, &ctx->stack.flags);
+
+	__put_user(0, &ctx->weird_graphics_thing);
+	__put_user(0, &ctx->regs[0]);
+	for (i = 1; i < 32; i++)
+		__put_user(regs->regs[i], &ctx->regs[i]);
+	__put_user(regs->lo, &ctx->regs[32]);
+	__put_user(regs->hi, &ctx->regs[33]);
+	__put_user(regs->cp0_cause, &ctx->regs[34]);
+	__put_user(regs->cp0_epc, &ctx->regs[35]);
+
+	flags = 0x0f;
+	if (!used_math()) {
+		flags &= ~(0x08);
+	} else {
+		/* XXX wheee... */
+		printk("Wheee, no code for saving IRIX FPU context yet.\n");
+	}
+	__put_user(flags, &ctx->flags);
+
+	return 0;
+}
+
+asmlinkage unsigned long irix_setcontext(struct pt_regs *regs)
+{
+	int error, base = 0;
+	struct irix5_context *ctx;
+
+	if(regs->regs[2] == 1000)
+		base = 1;
+	ctx = (struct irix5_context *) regs->regs[base + 4];
+
+#ifdef DEBUG_SIG
+	printk("[%s:%d] irix_setcontext(%p)\n",
+	       current->comm, current->pid, ctx);
+#endif
+
+	if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx))) {
+		error = -EFAULT;
+		goto out;
+	}
+
+	if (ctx->flags & 0x02) {
+		/* XXX sigstack garbage, todo... */
+		printk("Wheee, cannot do sigstack stuff in setcontext\n");
+	}
+
+	if (ctx->flags & 0x04) {
+		int i;
+
+		/* XXX extra control block stuff... todo... */
+		for(i = 1; i < 32; i++)
+			regs->regs[i] = ctx->regs[i];
+		regs->lo = ctx->regs[32];
+		regs->hi = ctx->regs[33];
+		regs->cp0_epc = ctx->regs[35];
+	}
+
+	if (ctx->flags & 0x08) {
+		/* XXX fpu context, blah... */
+		printk("Wheee, cannot restore FPU context yet...\n");
+	}
+	current->thread.irix_oldctx = ctx->link;
+	error = regs->regs[2];
+
+out:
+	return error;
+}
+
+struct irix_sigstack { unsigned long sp; int status; };
+
+asmlinkage int irix_sigstack(struct irix_sigstack *new, struct irix_sigstack *old)
+{
+	int error = -EFAULT;
+
+#ifdef DEBUG_SIG
+	printk("[%s:%d] irix_sigstack(%p,%p)\n",
+	       current->comm, current->pid, new, old);
+#endif
+	if(new) {
+		if (!access_ok(VERIFY_READ, new, sizeof(*new)))
+			goto out;
+	}
+
+	if(old) {
+		if (!access_ok(VERIFY_WRITE, old, sizeof(*old)))
+			goto out;
+	}
+	error = 0;
+
+out:
+	return error;
+}
+
+struct irix_sigaltstack { unsigned long sp; int size; int status; };
+
+asmlinkage int irix_sigaltstack(struct irix_sigaltstack *new,
+				struct irix_sigaltstack *old)
+{
+	int error = -EFAULT;
+
+#ifdef DEBUG_SIG
+	printk("[%s:%d] irix_sigaltstack(%p,%p)\n",
+	       current->comm, current->pid, new, old);
+#endif
+	if (new) {
+		if (!access_ok(VERIFY_READ, new, sizeof(*new)))
+			goto out;
+	}
+
+	if (old) {
+		if (!access_ok(VERIFY_WRITE, old, sizeof(*old)))
+			goto out;
+	}
+	error = 0;
+
+out:
+	error = 0;
+
+	return error;
+}
+
+struct irix_procset {
+	int cmd, ltype, lid, rtype, rid;
+};
+
+asmlinkage int irix_sigsendset(struct irix_procset *pset, int sig)
+{
+	if (!access_ok(VERIFY_READ, pset, sizeof(*pset)))
+		return -EFAULT;
+
+#ifdef DEBUG_SIG
+	printk("[%s:%d] irix_sigsendset([%d,%d,%d,%d,%d],%d)\n",
+	       current->comm, current->pid,
+	       pset->cmd, pset->ltype, pset->lid, pset->rtype, pset->rid,
+	       sig);
+#endif
+	return -EINVAL;
+}
diff --git a/arch/mips/kernel/irq-msc01.c b/arch/mips/kernel/irq-msc01.c
new file mode 100644
index 0000000..43c00ac
--- /dev/null
+++ b/arch/mips/kernel/irq-msc01.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2004 MIPS Inc
+ * Author: chris@mips.com
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <asm/ptrace.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/msc01_ic.h>
+
+static unsigned long _icctrl_msc;
+#define MSC01_IC_REG_BASE	_icctrl_msc
+
+#define MSCIC_WRITE(reg, data)	do { *(volatile u32 *)(reg) = data; } while (0)
+#define MSCIC_READ(reg, data)	do { data = *(volatile u32 *)(reg); } while (0)
+
+static unsigned int irq_base;
+
+/* mask off an interrupt */
+static inline void mask_msc_irq(unsigned int irq)
+{
+	if (irq < (irq_base + 32))
+		MSCIC_WRITE(MSC01_IC_DISL, 1<<(irq - irq_base));
+	else
+		MSCIC_WRITE(MSC01_IC_DISH, 1<<(irq - irq_base - 32));
+}
+
+/* unmask an interrupt */
+static inline void unmask_msc_irq(unsigned int irq)
+{
+	if (irq < (irq_base + 32))
+		MSCIC_WRITE(MSC01_IC_ENAL, 1<<(irq - irq_base));
+	else
+		MSCIC_WRITE(MSC01_IC_ENAH, 1<<(irq - irq_base - 32));
+}
+
+/*
+ * Enables the IRQ on SOC-it
+ */
+static void enable_msc_irq(unsigned int irq)
+{
+	unmask_msc_irq(irq);
+}
+
+/*
+ * Initialize the IRQ on SOC-it
+ */
+static unsigned int startup_msc_irq(unsigned int irq)
+{
+	unmask_msc_irq(irq);
+	return 0;
+}
+
+/*
+ * Disables the IRQ on SOC-it
+ */
+static void disable_msc_irq(unsigned int irq)
+{
+	mask_msc_irq(irq);
+}
+
+/*
+ * Masks and ACKs an IRQ
+ */
+static void level_mask_and_ack_msc_irq(unsigned int irq)
+{
+	mask_msc_irq(irq);
+	if (!cpu_has_ei)
+		MSCIC_WRITE(MSC01_IC_EOI, 0);
+}
+
+/*
+ * Masks and ACKs an IRQ
+ */
+static void edge_mask_and_ack_msc_irq(unsigned int irq)
+{
+	mask_msc_irq(irq);
+	if (!cpu_has_ei)
+		MSCIC_WRITE(MSC01_IC_EOI, 0);
+	else {
+		u32 r;
+		MSCIC_READ(MSC01_IC_SUP+irq*8, r);
+		MSCIC_WRITE(MSC01_IC_SUP+irq*8, r | ~MSC01_IC_SUP_EDGE_BIT);
+		MSCIC_WRITE(MSC01_IC_SUP+irq*8, r);
+	}
+}
+
+/*
+ * End IRQ processing
+ */
+static void end_msc_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		unmask_msc_irq(irq);
+}
+
+/*
+ * Interrupt handler for interrupts coming from SOC-it.
+ */
+void ll_msc_irq(struct pt_regs *regs)
+{
+ 	unsigned int irq;
+
+	/* read the interrupt vector register */
+	MSCIC_READ(MSC01_IC_VEC, irq);
+	if (irq < 64)
+		do_IRQ(irq + irq_base, regs);
+	else {
+		/* Ignore spurious interrupt */
+	}
+}
+
+void
+msc_bind_eic_interrupt (unsigned int irq, unsigned int set)
+{
+	MSCIC_WRITE(MSC01_IC_RAMW,
+		    (irq<<MSC01_IC_RAMW_ADDR_SHF) | (set<<MSC01_IC_RAMW_DATA_SHF));
+}
+
+#define shutdown_msc_irq	disable_msc_irq
+
+struct hw_interrupt_type msc_levelirq_type = {
+	"SOC-it-Level",
+	startup_msc_irq,
+	shutdown_msc_irq,
+	enable_msc_irq,
+	disable_msc_irq,
+	level_mask_and_ack_msc_irq,
+	end_msc_irq,
+	NULL
+};
+
+struct hw_interrupt_type msc_edgeirq_type = {
+	"SOC-it-Edge",
+	startup_msc_irq,
+	shutdown_msc_irq,
+	enable_msc_irq,
+	disable_msc_irq,
+	edge_mask_and_ack_msc_irq,
+	end_msc_irq,
+	NULL
+};
+
+
+void __init init_msc_irqs(unsigned int base, msc_irqmap_t *imp, int nirq)
+{
+	extern void (*board_bind_eic_interrupt)(unsigned int irq, unsigned int regset);
+
+	_icctrl_msc = (unsigned long) ioremap (MIPS_MSC01_IC_REG_BASE, 0x40000);
+
+	/* Reset interrupt controller - initialises all registers to 0 */
+	MSCIC_WRITE(MSC01_IC_RST, MSC01_IC_RST_RST_BIT);
+
+	board_bind_eic_interrupt = &msc_bind_eic_interrupt;
+
+	for (; nirq >= 0; nirq--, imp++) {
+		int n = imp->im_irq;
+
+		switch (imp->im_type) {
+		case MSC01_IRQ_EDGE:
+			irq_desc[base+n].handler = &msc_edgeirq_type;
+			if (cpu_has_ei)
+				MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT);
+			else
+				MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT | imp->im_lvl);
+			break;
+		case MSC01_IRQ_LEVEL:
+			irq_desc[base+n].handler = &msc_levelirq_type;
+			if (cpu_has_ei)
+				MSCIC_WRITE(MSC01_IC_SUP+n*8, 0);
+			else
+				MSCIC_WRITE(MSC01_IC_SUP+n*8, imp->im_lvl);
+		}
+	}
+
+	irq_base = base;
+
+	MSCIC_WRITE(MSC01_IC_GENA, MSC01_IC_GENA_GENA_BIT);	/* Enable interrupt generation */
+
+}
diff --git a/arch/mips/kernel/irq-mv6434x.c b/arch/mips/kernel/irq-mv6434x.c
new file mode 100644
index 0000000..088bbbc
--- /dev/null
+++ b/arch/mips/kernel/irq-mv6434x.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2002 Momentum Computer
+ * Author: mdharm@momenco.com
+ * Copyright (C) 2004 Ralf Baechle <ralf@linux-mips.org>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <asm/ptrace.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <linux/mv643xx.h>
+
+static unsigned int irq_base;
+
+static inline int ls1bit32(unsigned int x)
+{
+        int b = 31, s;
+
+        s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s;
+        s =  8; if (x <<  8 == 0) s = 0; b -= s; x <<= s;
+        s =  4; if (x <<  4 == 0) s = 0; b -= s; x <<= s;
+        s =  2; if (x <<  2 == 0) s = 0; b -= s; x <<= s;
+        s =  1; if (x <<  1 == 0) s = 0; b -= s;
+
+        return b;
+}
+
+/* mask off an interrupt -- 1 is enable, 0 is disable */
+static inline void mask_mv64340_irq(unsigned int irq)
+{
+	uint32_t value;
+
+	if (irq < (irq_base + 32)) {
+		value = MV_READ(MV64340_INTERRUPT0_MASK_0_LOW);
+		value &= ~(1 << (irq - irq_base));
+		MV_WRITE(MV64340_INTERRUPT0_MASK_0_LOW, value);
+	} else {
+		value = MV_READ(MV64340_INTERRUPT0_MASK_0_HIGH);
+		value &= ~(1 << (irq - irq_base - 32));
+		MV_WRITE(MV64340_INTERRUPT0_MASK_0_HIGH, value);
+	}
+}
+
+/* unmask an interrupt -- 1 is enable, 0 is disable */
+static inline void unmask_mv64340_irq(unsigned int irq)
+{
+	uint32_t value;
+
+	if (irq < (irq_base + 32)) {
+		value = MV_READ(MV64340_INTERRUPT0_MASK_0_LOW);
+		value |= 1 << (irq - irq_base);
+		MV_WRITE(MV64340_INTERRUPT0_MASK_0_LOW, value);
+	} else {
+		value = MV_READ(MV64340_INTERRUPT0_MASK_0_HIGH);
+		value |= 1 << (irq - irq_base - 32);
+		MV_WRITE(MV64340_INTERRUPT0_MASK_0_HIGH, value);
+	}
+}
+
+/*
+ * Enables the IRQ on Marvell Chip
+ */
+static void enable_mv64340_irq(unsigned int irq)
+{
+	unmask_mv64340_irq(irq);
+}
+
+/*
+ * Initialize the IRQ on Marvell Chip
+ */
+static unsigned int startup_mv64340_irq(unsigned int irq)
+{
+	unmask_mv64340_irq(irq);
+	return 0;
+}
+
+/*
+ * Disables the IRQ on Marvell Chip
+ */
+static void disable_mv64340_irq(unsigned int irq)
+{
+	mask_mv64340_irq(irq);
+}
+
+/*
+ * Masks and ACKs an IRQ
+ */
+static void mask_and_ack_mv64340_irq(unsigned int irq)
+{
+	mask_mv64340_irq(irq);
+}
+
+/*
+ * End IRQ processing
+ */
+static void end_mv64340_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		unmask_mv64340_irq(irq);
+}
+
+/*
+ * Interrupt handler for interrupts coming from the Marvell chip.
+ * It could be built in ethernet ports etc...
+ */
+void ll_mv64340_irq(struct pt_regs *regs)
+{
+	unsigned int irq_src_low, irq_src_high;
+ 	unsigned int irq_mask_low, irq_mask_high;
+
+	/* read the interrupt status registers */
+	irq_mask_low = MV_READ(MV64340_INTERRUPT0_MASK_0_LOW);
+	irq_mask_high = MV_READ(MV64340_INTERRUPT0_MASK_0_HIGH);
+	irq_src_low = MV_READ(MV64340_MAIN_INTERRUPT_CAUSE_LOW);
+	irq_src_high = MV_READ(MV64340_MAIN_INTERRUPT_CAUSE_HIGH);
+
+	/* mask for just the interrupts we want */
+	irq_src_low &= irq_mask_low;
+	irq_src_high &= irq_mask_high;
+
+	if (irq_src_low)
+		do_IRQ(ls1bit32(irq_src_low) + irq_base, regs);
+	else
+		do_IRQ(ls1bit32(irq_src_high) + irq_base + 32, regs);
+}
+
+#define shutdown_mv64340_irq	disable_mv64340_irq
+
+struct hw_interrupt_type mv64340_irq_type = {
+	"MV-64340",
+	startup_mv64340_irq,
+	shutdown_mv64340_irq,
+	enable_mv64340_irq,
+	disable_mv64340_irq,
+	mask_and_ack_mv64340_irq,
+	end_mv64340_irq,
+	NULL
+};
+
+void __init mv64340_irq_init(unsigned int base)
+{
+	int i;
+
+	/* Reset irq handlers pointers to NULL */
+	for (i = base; i < base + 64; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = 0;
+		irq_desc[i].depth = 2;
+		irq_desc[i].handler = &mv64340_irq_type;
+	}
+
+	irq_base = base;
+}
diff --git a/arch/mips/kernel/irq-rm7000.c b/arch/mips/kernel/irq-rm7000.c
new file mode 100644
index 0000000..f5d779f
--- /dev/null
+++ b/arch/mips/kernel/irq-rm7000.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2003 Ralf Baechle
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Handler for RM7000 extended interrupts.  These are a non-standard
+ * feature so we handle them separately from standard interrupts.
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+static int irq_base;
+
+static inline void unmask_rm7k_irq(unsigned int irq)
+{
+	set_c0_intcontrol(0x100 << (irq - irq_base));
+}
+
+static inline void mask_rm7k_irq(unsigned int irq)
+{
+	clear_c0_intcontrol(0x100 << (irq - irq_base));
+}
+
+static inline void rm7k_cpu_irq_enable(unsigned int irq)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	unmask_rm7k_irq(irq);
+	local_irq_restore(flags);
+}
+
+static void rm7k_cpu_irq_disable(unsigned int irq)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	mask_rm7k_irq(irq);
+	local_irq_restore(flags);
+}
+
+static unsigned int rm7k_cpu_irq_startup(unsigned int irq)
+{
+	rm7k_cpu_irq_enable(irq);
+
+	return 0;
+}
+
+#define	rm7k_cpu_irq_shutdown	rm7k_cpu_irq_disable
+
+/*
+ * While we ack the interrupt interrupts are disabled and thus we don't need
+ * to deal with concurrency issues.  Same for rm7k_cpu_irq_end.
+ */
+static void rm7k_cpu_irq_ack(unsigned int irq)
+{
+	mask_rm7k_irq(irq);
+}
+
+static void rm7k_cpu_irq_end(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		unmask_rm7k_irq(irq);
+}
+
+static hw_irq_controller rm7k_irq_controller = {
+	"RM7000",
+	rm7k_cpu_irq_startup,
+	rm7k_cpu_irq_shutdown,
+	rm7k_cpu_irq_enable,
+	rm7k_cpu_irq_disable,
+	rm7k_cpu_irq_ack,
+	rm7k_cpu_irq_end,
+};
+
+void __init rm7k_cpu_irq_init(int base)
+{
+	int i;
+
+	clear_c0_intcontrol(0x00000f00);		/* Mask all */
+
+	for (i = base; i < base + 4; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &rm7k_irq_controller;
+	}
+
+	irq_base = base;
+}
diff --git a/arch/mips/kernel/irq-rm9000.c b/arch/mips/kernel/irq-rm9000.c
new file mode 100644
index 0000000..bdd1302
--- /dev/null
+++ b/arch/mips/kernel/irq-rm9000.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2003 Ralf Baechle
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Handler for RM9000 extended interrupts.  These are a non-standard
+ * feature so we handle them separately from standard interrupts.
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+static int irq_base;
+
+static inline void unmask_rm9k_irq(unsigned int irq)
+{
+	set_c0_intcontrol(0x1000 << (irq - irq_base));
+}
+
+static inline void mask_rm9k_irq(unsigned int irq)
+{
+	clear_c0_intcontrol(0x1000 << (irq - irq_base));
+}
+
+static inline void rm9k_cpu_irq_enable(unsigned int irq)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	unmask_rm9k_irq(irq);
+	local_irq_restore(flags);
+}
+
+static void rm9k_cpu_irq_disable(unsigned int irq)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	mask_rm9k_irq(irq);
+	local_irq_restore(flags);
+}
+
+static unsigned int rm9k_cpu_irq_startup(unsigned int irq)
+{
+	rm9k_cpu_irq_enable(irq);
+
+	return 0;
+}
+
+#define	rm9k_cpu_irq_shutdown	rm9k_cpu_irq_disable
+
+/*
+ * Performance counter interrupts are global on all processors.
+ */
+static void local_rm9k_perfcounter_irq_startup(void *args)
+{
+	unsigned int irq = (unsigned int) args;
+
+	rm9k_cpu_irq_enable(irq);
+}
+
+static unsigned int rm9k_perfcounter_irq_startup(unsigned int irq)
+{
+	on_each_cpu(local_rm9k_perfcounter_irq_startup, (void *) irq, 0, 1);
+
+	return 0;
+}
+
+static void local_rm9k_perfcounter_irq_shutdown(void *args)
+{
+	unsigned int irq = (unsigned int) args;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	mask_rm9k_irq(irq);
+	local_irq_restore(flags);
+}
+
+static void rm9k_perfcounter_irq_shutdown(unsigned int irq)
+{
+	on_each_cpu(local_rm9k_perfcounter_irq_shutdown, (void *) irq, 0, 1);
+}
+
+
+/*
+ * While we ack the interrupt interrupts are disabled and thus we don't need
+ * to deal with concurrency issues.  Same for rm9k_cpu_irq_end.
+ */
+static void rm9k_cpu_irq_ack(unsigned int irq)
+{
+	mask_rm9k_irq(irq);
+}
+
+static void rm9k_cpu_irq_end(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		unmask_rm9k_irq(irq);
+}
+
+static hw_irq_controller rm9k_irq_controller = {
+	"RM9000",
+	rm9k_cpu_irq_startup,
+	rm9k_cpu_irq_shutdown,
+	rm9k_cpu_irq_enable,
+	rm9k_cpu_irq_disable,
+	rm9k_cpu_irq_ack,
+	rm9k_cpu_irq_end,
+};
+
+static hw_irq_controller rm9k_perfcounter_irq = {
+	"RM9000",
+	rm9k_perfcounter_irq_startup,
+	rm9k_perfcounter_irq_shutdown,
+	rm9k_cpu_irq_enable,
+	rm9k_cpu_irq_disable,
+	rm9k_cpu_irq_ack,
+	rm9k_cpu_irq_end,
+};
+
+unsigned int rm9000_perfcount_irq;
+
+EXPORT_SYMBOL(rm9000_perfcount_irq);
+
+void __init rm9k_cpu_irq_init(int base)
+{
+	int i;
+
+	clear_c0_intcontrol(0x0000f000);		/* Mask all */
+
+	for (i = base; i < base + 4; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &rm9k_irq_controller;
+	}
+
+	rm9000_perfcount_irq = base + 1;
+	irq_desc[rm9000_perfcount_irq].handler = &rm9k_perfcounter_irq;
+
+	irq_base = base;
+}
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
new file mode 100644
index 0000000..441157a
--- /dev/null
+++ b/arch/mips/kernel/irq.c
@@ -0,0 +1,140 @@
+/*
+ * 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.
+ *
+ * Code to handle x86 style IRQs plus some generic interrupt stuff.
+ *
+ * Copyright (C) 1992 Linus Torvalds
+ * Copyright (C) 1994 - 2000 Ralf Baechle
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/random.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <linux/kallsyms.h>
+
+#include <asm/atomic.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+/*
+ * 'what should we do if we get a hw irq event on an illegal vector'.
+ * each architecture has to answer this themselves.
+ */
+void ack_bad_irq(unsigned int irq)
+{
+	printk("unexpected IRQ # %d\n", irq);
+}
+
+atomic_t irq_err_count;
+
+#undef do_IRQ
+
+/*
+ * do_IRQ handles all normal device IRQ's (the special
+ * SMP cross-CPU interrupts have their own specific
+ * handlers).
+ */
+asmlinkage unsigned int do_IRQ(unsigned int irq, struct pt_regs *regs)
+{
+	irq_enter();
+
+	__do_IRQ(irq, regs);
+
+	irq_exit();
+
+	return 1;
+}
+
+/*
+ * Generic, controller-independent functions:
+ */
+
+int show_interrupts(struct seq_file *p, void *v)
+{
+	int i = *(loff_t *) v, j;
+	struct irqaction * action;
+	unsigned long flags;
+
+	if (i == 0) {
+		seq_printf(p, "           ");
+		for (j=0; j<NR_CPUS; j++)
+			if (cpu_online(j))
+				seq_printf(p, "CPU%d       ",j);
+		seq_putc(p, '\n');
+	}
+
+	if (i < NR_IRQS) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		action = irq_desc[i].action;
+		if (!action) 
+			goto skip;
+		seq_printf(p, "%3d: ",i);
+#ifndef CONFIG_SMP
+		seq_printf(p, "%10u ", kstat_irqs(i));
+#else
+		for (j = 0; j < NR_CPUS; j++)
+			if (cpu_online(j))
+				seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+#endif
+		seq_printf(p, " %14s", irq_desc[i].handler->typename);
+		seq_printf(p, "  %s", action->name);
+
+		for (action=action->next; action; action = action->next)
+			seq_printf(p, ", %s", action->name);
+
+		seq_putc(p, '\n');
+skip:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+	} else if (i == NR_IRQS) {
+		seq_putc(p, '\n');
+		seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
+	}
+	return 0;
+}
+
+#ifdef CONFIG_KGDB
+extern void breakpoint(void);
+extern void set_debug_traps(void);
+
+static int kgdb_flag = 1;
+static int __init nokgdb(char *str)
+{
+	kgdb_flag = 0;
+	return 1;
+}
+__setup("nokgdb", nokgdb);
+#endif
+
+void __init init_IRQ(void)
+{
+	int i;
+
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc[i].status  = IRQ_DISABLED;
+		irq_desc[i].action  = NULL;
+		irq_desc[i].depth   = 1;
+		irq_desc[i].handler = &no_irq_type;
+		spin_lock_init(&irq_desc[i].lock);
+	}
+
+	arch_init_irq();
+
+#ifdef CONFIG_KGDB
+	if (kgdb_flag) {
+		printk("Wait for gdb client connection ...\n");
+		set_debug_traps();
+		breakpoint();
+	}
+#endif
+}
diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c
new file mode 100644
index 0000000..2b936cf
--- /dev/null
+++ b/arch/mips/kernel/irq_cpu.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * Copyright (C) 2001 Ralf Baechle
+ *
+ * This file define the irq handler for MIPS CPU interrupts.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+/*
+ * Almost all MIPS CPUs define 8 interrupt sources.  They are typically
+ * level triggered (i.e., cannot be cleared from CPU; must be cleared from
+ * device).  The first two are software interrupts which we don't really
+ * use or support.  The last one is usually the CPU timer interrupt if
+ * counter register is present or, for CPUs with an external FPU, by
+ * convention it's the FPU exception interrupt.
+ *
+ * Don't even think about using this on SMP.  You have been warned.
+ *
+ * This file exports one global function:
+ *	void mips_cpu_irq_init(int irq_base);
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+static int mips_cpu_irq_base;
+
+static inline void unmask_mips_irq(unsigned int irq)
+{
+	clear_c0_cause(0x100 << (irq - mips_cpu_irq_base));
+	set_c0_status(0x100 << (irq - mips_cpu_irq_base));
+}
+
+static inline void mask_mips_irq(unsigned int irq)
+{
+	clear_c0_status(0x100 << (irq - mips_cpu_irq_base));
+}
+
+static inline void mips_cpu_irq_enable(unsigned int irq)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	unmask_mips_irq(irq);
+	local_irq_restore(flags);
+}
+
+static void mips_cpu_irq_disable(unsigned int irq)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	mask_mips_irq(irq);
+	local_irq_restore(flags);
+}
+
+static unsigned int mips_cpu_irq_startup(unsigned int irq)
+{
+	mips_cpu_irq_enable(irq);
+
+	return 0;
+}
+
+#define	mips_cpu_irq_shutdown	mips_cpu_irq_disable
+
+/*
+ * While we ack the interrupt interrupts are disabled and thus we don't need
+ * to deal with concurrency issues.  Same for mips_cpu_irq_end.
+ */
+static void mips_cpu_irq_ack(unsigned int irq)
+{
+	/* Only necessary for soft interrupts */
+	clear_c0_cause(0x100 << (irq - mips_cpu_irq_base));
+
+	mask_mips_irq(irq);
+}
+
+static void mips_cpu_irq_end(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		unmask_mips_irq(irq);
+}
+
+static hw_irq_controller mips_cpu_irq_controller = {
+	"MIPS",
+	mips_cpu_irq_startup,
+	mips_cpu_irq_shutdown,
+	mips_cpu_irq_enable,
+	mips_cpu_irq_disable,
+	mips_cpu_irq_ack,
+	mips_cpu_irq_end,
+	NULL			/* no affinity stuff for UP */
+};
+
+
+void __init mips_cpu_irq_init(int irq_base)
+{
+	int i;
+
+	for (i = irq_base; i < irq_base + 8; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &mips_cpu_irq_controller;
+	}
+
+	mips_cpu_irq_base = irq_base;
+}
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
new file mode 100644
index 0000000..993abc8
--- /dev/null
+++ b/arch/mips/kernel/linux32.c
@@ -0,0 +1,1469 @@
+/*
+ * Conversion between 32-bit and 64-bit native system calls.
+ *
+ * Copyright (C) 2000 Silicon Graphics, Inc.
+ * Written by Ulf Carlsson (ulfc@engr.sgi.com)
+ * sys32_execve from ia64/ia32 code, Feb 2000, Kanoj Sarcar (kanoj@sgi.com)
+ */
+#include <linux/config.h>
+#include <linux/compiler.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/file.h>
+#include <linux/smp_lock.h>
+#include <linux/highuid.h>
+#include <linux/dirent.h>
+#include <linux/resource.h>
+#include <linux/highmem.h>
+#include <linux/time.h>
+#include <linux/times.h>
+#include <linux/poll.h>
+#include <linux/slab.h>
+#include <linux/skbuff.h>
+#include <linux/filter.h>
+#include <linux/shm.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/icmpv6.h>
+#include <linux/syscalls.h>
+#include <linux/sysctl.h>
+#include <linux/utime.h>
+#include <linux/utsname.h>
+#include <linux/personality.h>
+#include <linux/timex.h>
+#include <linux/dnotify.h>
+#include <linux/module.h>
+#include <linux/binfmts.h>
+#include <linux/security.h>
+#include <linux/compat.h>
+#include <linux/vfs.h>
+
+#include <net/sock.h>
+#include <net/scm.h>
+
+#include <asm/ipc.h>
+#include <asm/sim.h>
+#include <asm/uaccess.h>
+#include <asm/mmu_context.h>
+#include <asm/mman.h>
+
+/* Use this to get at 32-bit user passed pointers. */
+/* A() macro should be used for places where you e.g.
+   have some internal variable u32 and just want to get
+   rid of a compiler warning. AA() has to be used in
+   places where you want to convert a function argument
+   to 32bit pointer or when you e.g. access pt_regs
+   structure and want to consider 32bit registers only.
+ */
+#define A(__x) ((unsigned long)(__x))
+#define AA(__x) ((unsigned long)((int)__x))
+
+#ifdef __MIPSEB__
+#define merge_64(r1,r2)	((((r1) & 0xffffffffUL) << 32) + ((r2) & 0xffffffffUL))
+#endif
+#ifdef __MIPSEL__
+#define merge_64(r1,r2)	((((r2) & 0xffffffffUL) << 32) + ((r1) & 0xffffffffUL))
+#endif
+
+/*
+ * Revalidate the inode. This is required for proper NFS attribute caching.
+ */
+
+int cp_compat_stat(struct kstat *stat, struct compat_stat *statbuf)
+{
+	struct compat_stat tmp;
+
+	if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev))
+		return -EOVERFLOW;
+
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.st_dev = new_encode_dev(stat->dev);
+	tmp.st_ino = stat->ino;
+	tmp.st_mode = stat->mode;
+	tmp.st_nlink = stat->nlink;
+	SET_UID(tmp.st_uid, stat->uid);
+	SET_GID(tmp.st_gid, stat->gid);
+	tmp.st_rdev = new_encode_dev(stat->rdev);
+	tmp.st_size = stat->size;
+	tmp.st_atime = stat->atime.tv_sec;
+	tmp.st_mtime = stat->mtime.tv_sec;
+	tmp.st_ctime = stat->ctime.tv_sec;
+#ifdef STAT_HAVE_NSEC
+	tmp.st_atime_nsec = stat->atime.tv_nsec;
+	tmp.st_mtime_nsec = stat->mtime.tv_nsec;
+	tmp.st_ctime_nsec = stat->ctime.tv_nsec;
+#endif
+	tmp.st_blocks = stat->blocks;
+	tmp.st_blksize = stat->blksize;
+	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
+}
+
+asmlinkage unsigned long
+sys32_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
+         unsigned long flags, unsigned long fd, unsigned long pgoff)
+{
+	struct file * file = NULL;
+	unsigned long error;
+
+	error = -EINVAL;
+	if (!(flags & MAP_ANONYMOUS)) {
+		error = -EBADF;
+		file = fget(fd);
+		if (!file)
+			goto out;
+	}
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+	down_write(&current->mm->mmap_sem);
+	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+	up_write(&current->mm->mmap_sem);
+	if (file)
+		fput(file);
+
+out:
+	return error;
+}
+
+
+asmlinkage int sys_truncate64(const char *path, unsigned int high,
+			      unsigned int low)
+{
+	if ((int)high < 0)
+		return -EINVAL;
+	return sys_truncate(path, ((long) high << 32) | low);
+}
+
+asmlinkage int sys_ftruncate64(unsigned int fd, unsigned int high,
+			       unsigned int low)
+{
+	if ((int)high < 0)
+		return -EINVAL;
+	return sys_ftruncate(fd, ((long) high << 32) | low);
+}
+
+/*
+ * sys_execve() executes a new program.
+ */
+asmlinkage int sys32_execve(nabi_no_regargs struct pt_regs regs)
+{
+	int error;
+	char * filename;
+
+	filename = getname(compat_ptr(regs.regs[4]));
+	error = PTR_ERR(filename);
+	if (IS_ERR(filename))
+		goto out;
+	error = compat_do_execve(filename, compat_ptr(regs.regs[5]),
+				 compat_ptr(regs.regs[6]), &regs);
+	putname(filename);
+
+out:
+	return error;
+}
+
+struct dirent32 {
+	unsigned int	d_ino;
+	unsigned int	d_off;
+	unsigned short	d_reclen;
+	char		d_name[NAME_MAX + 1];
+};
+
+static void
+xlate_dirent(void *dirent64, void *dirent32, long n)
+{
+	long off;
+	struct dirent *dirp;
+	struct dirent32 *dirp32;
+
+	off = 0;
+	while (off < n) {
+		dirp = (struct dirent *)(dirent64 + off);
+		dirp32 = (struct dirent32 *)(dirent32 + off);
+		off += dirp->d_reclen;
+		dirp32->d_ino = dirp->d_ino;
+		dirp32->d_off = (unsigned int)dirp->d_off;
+		dirp32->d_reclen = dirp->d_reclen;
+		strncpy(dirp32->d_name, dirp->d_name, dirp->d_reclen - ((3 * 4) + 2));
+	}
+	return;
+}
+
+asmlinkage long
+sys32_getdents(unsigned int fd, void * dirent32, unsigned int count)
+{
+	long n;
+	void *dirent64;
+
+	dirent64 = (void *)((unsigned long)(dirent32 + (sizeof(long) - 1)) & ~(sizeof(long) - 1));
+	if ((n = sys_getdents(fd, dirent64, count - (dirent64 - dirent32))) < 0)
+		return(n);
+	xlate_dirent(dirent64, dirent32, n);
+	return(n);
+}
+
+asmlinkage int old_readdir(unsigned int fd, void * dirent, unsigned int count);
+
+asmlinkage int
+sys32_readdir(unsigned int fd, void * dirent32, unsigned int count)
+{
+	int n;
+	struct dirent dirent64;
+
+	if ((n = old_readdir(fd, &dirent64, count)) < 0)
+		return(n);
+	xlate_dirent(&dirent64, dirent32, dirent64.d_reclen);
+	return(n);
+}
+
+struct rusage32 {
+        struct compat_timeval ru_utime;
+        struct compat_timeval ru_stime;
+        int    ru_maxrss;
+        int    ru_ixrss;
+        int    ru_idrss;
+        int    ru_isrss;
+        int    ru_minflt;
+        int    ru_majflt;
+        int    ru_nswap;
+        int    ru_inblock;
+        int    ru_oublock;
+        int    ru_msgsnd;
+        int    ru_msgrcv;
+        int    ru_nsignals;
+        int    ru_nvcsw;
+        int    ru_nivcsw;
+};
+
+static int
+put_rusage (struct rusage32 *ru, struct rusage *r)
+{
+	int err;
+
+	if (!access_ok(VERIFY_WRITE, ru, sizeof *ru))
+		return -EFAULT;
+
+	err = __put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec);
+	err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec);
+	err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec);
+	err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec);
+	err |= __put_user (r->ru_maxrss, &ru->ru_maxrss);
+	err |= __put_user (r->ru_ixrss, &ru->ru_ixrss);
+	err |= __put_user (r->ru_idrss, &ru->ru_idrss);
+	err |= __put_user (r->ru_isrss, &ru->ru_isrss);
+	err |= __put_user (r->ru_minflt, &ru->ru_minflt);
+	err |= __put_user (r->ru_majflt, &ru->ru_majflt);
+	err |= __put_user (r->ru_nswap, &ru->ru_nswap);
+	err |= __put_user (r->ru_inblock, &ru->ru_inblock);
+	err |= __put_user (r->ru_oublock, &ru->ru_oublock);
+	err |= __put_user (r->ru_msgsnd, &ru->ru_msgsnd);
+	err |= __put_user (r->ru_msgrcv, &ru->ru_msgrcv);
+	err |= __put_user (r->ru_nsignals, &ru->ru_nsignals);
+	err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw);
+	err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw);
+
+	return err;
+}
+
+asmlinkage int
+sys32_wait4(compat_pid_t pid, unsigned int * stat_addr, int options,
+	    struct rusage32 * ru)
+{
+	if (!ru)
+		return sys_wait4(pid, stat_addr, options, NULL);
+	else {
+		struct rusage r;
+		int ret;
+		unsigned int status;
+		mm_segment_t old_fs = get_fs();
+
+		set_fs(KERNEL_DS);
+		ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
+		set_fs(old_fs);
+		if (put_rusage (ru, &r)) return -EFAULT;
+		if (stat_addr && put_user (status, stat_addr))
+			return -EFAULT;
+		return ret;
+	}
+}
+
+asmlinkage int
+sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr, int options)
+{
+	return sys32_wait4(pid, stat_addr, options, NULL);
+}
+
+struct sysinfo32 {
+        s32 uptime;
+        u32 loads[3];
+        u32 totalram;
+        u32 freeram;
+        u32 sharedram;
+        u32 bufferram;
+        u32 totalswap;
+        u32 freeswap;
+        u16 procs;
+	u32 totalhigh;
+	u32 freehigh;
+	u32 mem_unit;
+	char _f[8];
+};
+
+asmlinkage int sys32_sysinfo(struct sysinfo32 *info)
+{
+	struct sysinfo s;
+	int ret, err;
+	mm_segment_t old_fs = get_fs ();
+	
+	set_fs (KERNEL_DS);
+	ret = sys_sysinfo(&s);
+	set_fs (old_fs);
+	err = put_user (s.uptime, &info->uptime);
+	err |= __put_user (s.loads[0], &info->loads[0]);
+	err |= __put_user (s.loads[1], &info->loads[1]);
+	err |= __put_user (s.loads[2], &info->loads[2]);
+	err |= __put_user (s.totalram, &info->totalram);
+	err |= __put_user (s.freeram, &info->freeram);
+	err |= __put_user (s.sharedram, &info->sharedram);
+	err |= __put_user (s.bufferram, &info->bufferram);
+	err |= __put_user (s.totalswap, &info->totalswap);
+	err |= __put_user (s.freeswap, &info->freeswap);
+	err |= __put_user (s.procs, &info->procs);
+	err |= __put_user (s.totalhigh, &info->totalhigh);
+	err |= __put_user (s.freehigh, &info->freehigh);
+	err |= __put_user (s.mem_unit, &info->mem_unit);
+	if (err)
+		return -EFAULT;
+	return ret;
+}
+
+#define RLIM_INFINITY32	0x7fffffff
+#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
+
+struct rlimit32 {
+	int	rlim_cur;
+	int	rlim_max;
+};
+
+#ifdef __MIPSEB__
+asmlinkage long sys32_truncate64(const char * path, unsigned long __dummy,
+	int length_hi, int length_lo)
+#endif
+#ifdef __MIPSEL__
+asmlinkage long sys32_truncate64(const char * path, unsigned long __dummy,
+	int length_lo, int length_hi)
+#endif
+{
+	loff_t length;
+
+	length = ((unsigned long) length_hi << 32) | (unsigned int) length_lo;
+
+	return sys_truncate(path, length);
+}
+
+#ifdef __MIPSEB__
+asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy,
+	int length_hi, int length_lo)
+#endif
+#ifdef __MIPSEL__
+asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy,
+	int length_lo, int length_hi)
+#endif
+{
+	loff_t length;
+
+	length = ((unsigned long) length_hi << 32) | (unsigned int) length_lo;
+
+	return sys_ftruncate(fd, length);
+}
+
+static inline long
+get_tv32(struct timeval *o, struct compat_timeval *i)
+{
+	return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
+		(__get_user(o->tv_sec, &i->tv_sec) |
+		 __get_user(o->tv_usec, &i->tv_usec)));
+}
+
+static inline long
+put_tv32(struct compat_timeval *o, struct timeval *i)
+{
+	return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
+		(__put_user(i->tv_sec, &o->tv_sec) |
+		 __put_user(i->tv_usec, &o->tv_usec)));
+}
+
+extern struct timezone sys_tz;
+
+asmlinkage int
+sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz)
+{
+	if (tv) {
+		struct timeval ktv;
+		do_gettimeofday(&ktv);
+		if (put_tv32(tv, &ktv))
+			return -EFAULT;
+	}
+	if (tz) {
+		if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
+			return -EFAULT;
+	}
+	return 0;
+}
+
+static inline long get_ts32(struct timespec *o, struct compat_timeval *i)
+{
+	long usec;
+
+	if (!access_ok(VERIFY_READ, i, sizeof(*i)))
+		return -EFAULT;
+	if (__get_user(o->tv_sec, &i->tv_sec))
+		return -EFAULT;
+	if (__get_user(usec, &i->tv_usec))
+		return -EFAULT;
+	o->tv_nsec = usec * 1000;
+		return 0;
+}
+
+asmlinkage int
+sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz)
+{
+	struct timespec kts;
+	struct timezone ktz;
+
+ 	if (tv) {
+		if (get_ts32(&kts, tv))
+			return -EFAULT;
+	}
+	if (tz) {
+		if (copy_from_user(&ktz, tz, sizeof(ktz)))
+			return -EFAULT;
+	}
+
+	return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
+}
+
+asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high,
+			    unsigned int offset_low, loff_t * result,
+			    unsigned int origin)
+{
+	return sys_llseek(fd, offset_high, offset_low, result, origin);
+}
+
+/* From the Single Unix Spec: pread & pwrite act like lseek to pos + op +
+   lseek back to original location.  They fail just like lseek does on
+   non-seekable files.  */
+
+asmlinkage ssize_t sys32_pread(unsigned int fd, char * buf,
+			       size_t count, u32 unused, u64 a4, u64 a5)
+{
+	ssize_t ret;
+	struct file * file;
+	ssize_t (*read)(struct file *, char *, size_t, loff_t *);
+	loff_t pos;
+
+	ret = -EBADF;
+	file = fget(fd);
+	if (!file)
+		goto bad_file;
+	if (!(file->f_mode & FMODE_READ))
+		goto out;
+	pos = merge_64(a4, a5);
+	ret = rw_verify_area(READ, file, &pos, count);
+	if (ret)
+		goto out;
+	ret = -EINVAL;
+	if (!file->f_op || !(read = file->f_op->read))
+		goto out;
+	if (pos < 0)
+		goto out;
+	ret = -ESPIPE;
+	if (!(file->f_mode & FMODE_PREAD))
+		goto out;
+	ret = read(file, buf, count, &pos);
+	if (ret > 0)
+		dnotify_parent(file->f_dentry, DN_ACCESS);
+out:
+	fput(file);
+bad_file:
+	return ret;
+}
+
+asmlinkage ssize_t sys32_pwrite(unsigned int fd, const char * buf,
+			        size_t count, u32 unused, u64 a4, u64 a5)
+{
+	ssize_t ret;
+	struct file * file;
+	ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
+	loff_t pos;
+
+	ret = -EBADF;
+	file = fget(fd);
+	if (!file)
+		goto bad_file;
+	if (!(file->f_mode & FMODE_WRITE))
+		goto out;
+	pos = merge_64(a4, a5);
+	ret = rw_verify_area(WRITE, file, &pos, count);
+	if (ret)
+		goto out;
+	ret = -EINVAL;
+	if (!file->f_op || !(write = file->f_op->write))
+		goto out;
+	if (pos < 0)
+		goto out;
+
+	ret = -ESPIPE;
+	if (!(file->f_mode & FMODE_PWRITE))
+		goto out;
+
+	ret = write(file, buf, count, &pos);
+	if (ret > 0)
+		dnotify_parent(file->f_dentry, DN_MODIFY);
+out:
+	fput(file);
+bad_file:
+	return ret;
+}
+
+asmlinkage int sys32_sched_rr_get_interval(compat_pid_t pid,
+	struct compat_timespec *interval)
+{
+	struct timespec t;
+	int ret;
+	mm_segment_t old_fs = get_fs ();
+
+	set_fs (KERNEL_DS);
+	ret = sys_sched_rr_get_interval(pid, &t);
+	set_fs (old_fs);
+	if (put_user (t.tv_sec, &interval->tv_sec) ||
+	    __put_user (t.tv_nsec, &interval->tv_nsec))
+		return -EFAULT;
+	return ret;
+}
+
+struct msgbuf32 { s32 mtype; char mtext[1]; };
+
+struct ipc_perm32
+{
+	key_t    	  key;
+        compat_uid_t  uid;
+        compat_gid_t  gid;
+        compat_uid_t  cuid;
+        compat_gid_t  cgid;
+        compat_mode_t	mode;
+        unsigned short  seq;
+};
+
+struct ipc64_perm32 {
+	key_t key;
+	compat_uid_t uid;
+	compat_gid_t gid;
+	compat_uid_t cuid;
+	compat_gid_t cgid;
+	compat_mode_t	mode; 
+	unsigned short	seq;
+	unsigned short __pad1;
+	unsigned int __unused1;
+	unsigned int __unused2;
+};
+
+struct semid_ds32 {
+        struct ipc_perm32 sem_perm;               /* permissions .. see ipc.h */
+        compat_time_t   sem_otime;              /* last semop time */
+        compat_time_t   sem_ctime;              /* last change time */
+        u32 sem_base;              /* ptr to first semaphore in array */
+        u32 sem_pending;          /* pending operations to be processed */
+        u32 sem_pending_last;    /* last pending operation */
+        u32 undo;                  /* undo requests on this array */
+        unsigned short  sem_nsems;              /* no. of semaphores in array */
+};
+
+struct semid64_ds32 {
+	struct ipc64_perm32	sem_perm;
+	compat_time_t	sem_otime;
+	compat_time_t	sem_ctime;
+	unsigned int		sem_nsems;
+	unsigned int		__unused1;
+	unsigned int		__unused2;
+};
+
+struct msqid_ds32
+{
+        struct ipc_perm32 msg_perm;
+        u32 msg_first;
+        u32 msg_last;
+        compat_time_t   msg_stime;
+        compat_time_t   msg_rtime;
+        compat_time_t   msg_ctime;
+        u32 wwait;
+        u32 rwait;
+        unsigned short msg_cbytes;
+        unsigned short msg_qnum;
+        unsigned short msg_qbytes;
+        compat_ipc_pid_t msg_lspid;
+        compat_ipc_pid_t msg_lrpid;
+};
+
+struct msqid64_ds32 {
+	struct ipc64_perm32 msg_perm;
+	compat_time_t msg_stime;
+	unsigned int __unused1;
+	compat_time_t msg_rtime;
+	unsigned int __unused2;
+	compat_time_t msg_ctime;
+	unsigned int __unused3;
+	unsigned int msg_cbytes;
+	unsigned int msg_qnum;
+	unsigned int msg_qbytes;
+	compat_pid_t msg_lspid;
+	compat_pid_t msg_lrpid;
+	unsigned int __unused4;
+	unsigned int __unused5;
+};
+
+struct shmid_ds32 {
+        struct ipc_perm32       shm_perm;
+        int                     shm_segsz;
+        compat_time_t		shm_atime;
+        compat_time_t		shm_dtime;
+        compat_time_t		shm_ctime;
+        compat_ipc_pid_t    shm_cpid;
+        compat_ipc_pid_t    shm_lpid;
+        unsigned short          shm_nattch;
+};
+
+struct shmid64_ds32 {
+	struct ipc64_perm32	shm_perm;
+	compat_size_t		shm_segsz;
+	compat_time_t		shm_atime;
+	compat_time_t		shm_dtime;
+	compat_time_t shm_ctime;
+	compat_pid_t shm_cpid;
+	compat_pid_t shm_lpid;
+	unsigned int shm_nattch;
+	unsigned int __unused1;
+	unsigned int __unused2;
+};
+
+struct ipc_kludge32 {
+	u32 msgp;
+	s32 msgtyp;
+};
+
+static int
+do_sys32_semctl(int first, int second, int third, void *uptr)
+{
+	union semun fourth;
+	u32 pad;
+	int err, err2;
+	struct semid64_ds s;
+	mm_segment_t old_fs;
+
+	if (!uptr)
+		return -EINVAL;
+	err = -EFAULT;
+	if (get_user (pad, (u32 *)uptr))
+		return err;
+	if ((third & ~IPC_64) == SETVAL)
+		fourth.val = (int)pad;
+	else
+		fourth.__pad = (void *)A(pad);
+	switch (third & ~IPC_64) {
+	case IPC_INFO:
+	case IPC_RMID:
+	case IPC_SET:
+	case SEM_INFO:
+	case GETVAL:
+	case GETPID:
+	case GETNCNT:
+	case GETZCNT:
+	case GETALL:
+	case SETVAL:
+	case SETALL:
+		err = sys_semctl (first, second, third, fourth);
+		break;
+
+	case IPC_STAT:
+	case SEM_STAT:
+		fourth.__pad = &s;
+		old_fs = get_fs();
+		set_fs(KERNEL_DS);
+		err = sys_semctl(first, second, third | IPC_64, fourth);
+		set_fs(old_fs);
+
+		if (third & IPC_64) {
+			struct semid64_ds32 *usp64 = (struct semid64_ds32 *) A(pad);
+
+			if (!access_ok(VERIFY_WRITE, usp64, sizeof(*usp64))) {
+				err = -EFAULT;
+				break;
+			}
+			err2 = __put_user(s.sem_perm.key, &usp64->sem_perm.key);
+			err2 |= __put_user(s.sem_perm.uid, &usp64->sem_perm.uid);
+			err2 |= __put_user(s.sem_perm.gid, &usp64->sem_perm.gid);
+			err2 |= __put_user(s.sem_perm.cuid, &usp64->sem_perm.cuid);
+			err2 |= __put_user(s.sem_perm.cgid, &usp64->sem_perm.cgid);
+			err2 |= __put_user(s.sem_perm.mode, &usp64->sem_perm.mode);
+			err2 |= __put_user(s.sem_perm.seq, &usp64->sem_perm.seq);
+			err2 |= __put_user(s.sem_otime, &usp64->sem_otime);
+			err2 |= __put_user(s.sem_ctime, &usp64->sem_ctime);
+			err2 |= __put_user(s.sem_nsems, &usp64->sem_nsems);
+		} else {
+			struct semid_ds32 *usp32 = (struct semid_ds32 *) A(pad);
+
+			if (!access_ok(VERIFY_WRITE, usp32, sizeof(*usp32))) {
+				err = -EFAULT;
+				break;
+			}
+			err2 = __put_user(s.sem_perm.key, &usp32->sem_perm.key);
+			err2 |= __put_user(s.sem_perm.uid, &usp32->sem_perm.uid);
+			err2 |= __put_user(s.sem_perm.gid, &usp32->sem_perm.gid);
+			err2 |= __put_user(s.sem_perm.cuid, &usp32->sem_perm.cuid);
+			err2 |= __put_user(s.sem_perm.cgid, &usp32->sem_perm.cgid);
+			err2 |= __put_user(s.sem_perm.mode, &usp32->sem_perm.mode);
+			err2 |= __put_user(s.sem_perm.seq, &usp32->sem_perm.seq);
+			err2 |= __put_user(s.sem_otime, &usp32->sem_otime);
+			err2 |= __put_user(s.sem_ctime, &usp32->sem_ctime);
+			err2 |= __put_user(s.sem_nsems, &usp32->sem_nsems);
+		}
+		if (err2)
+			err = -EFAULT;
+		break;
+
+	default:
+		err = - EINVAL;
+		break;
+	}
+
+	return err;
+}
+
+static int
+do_sys32_msgsnd (int first, int second, int third, void *uptr)
+{
+	struct msgbuf32 *up = (struct msgbuf32 *)uptr;
+	struct msgbuf *p;
+	mm_segment_t old_fs;
+	int err;
+
+	if (second < 0)
+		return -EINVAL;
+	p = kmalloc (second + sizeof (struct msgbuf)
+				    + 4, GFP_USER);
+	if (!p)
+		return -ENOMEM;
+	err = get_user (p->mtype, &up->mtype);
+	if (err)
+		goto out;
+	err |= __copy_from_user (p->mtext, &up->mtext, second);
+	if (err)
+		goto out;
+	old_fs = get_fs ();
+	set_fs (KERNEL_DS);
+	err = sys_msgsnd (first, p, second, third);
+	set_fs (old_fs);
+out:
+	kfree (p);
+
+	return err;
+}
+
+static int
+do_sys32_msgrcv (int first, int second, int msgtyp, int third,
+		 int version, void *uptr)
+{
+	struct msgbuf32 *up;
+	struct msgbuf *p;
+	mm_segment_t old_fs;
+	int err;
+
+	if (!version) {
+		struct ipc_kludge32 *uipck = (struct ipc_kludge32 *)uptr;
+		struct ipc_kludge32 ipck;
+
+		err = -EINVAL;
+		if (!uptr)
+			goto out;
+		err = -EFAULT;
+		if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge32)))
+			goto out;
+		uptr = (void *)AA(ipck.msgp);
+		msgtyp = ipck.msgtyp;
+	}
+
+	if (second < 0)
+		return -EINVAL;
+	err = -ENOMEM;
+	p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
+	if (!p)
+		goto out;
+	old_fs = get_fs ();
+	set_fs (KERNEL_DS);
+	err = sys_msgrcv (first, p, second + 4, msgtyp, third);
+	set_fs (old_fs);
+	if (err < 0)
+		goto free_then_out;
+	up = (struct msgbuf32 *)uptr;
+	if (put_user (p->mtype, &up->mtype) ||
+	    __copy_to_user (&up->mtext, p->mtext, err))
+		err = -EFAULT;
+free_then_out:
+	kfree (p);
+out:
+	return err;
+}
+
+static int
+do_sys32_msgctl (int first, int second, void *uptr)
+{
+	int err = -EINVAL, err2;
+	struct msqid64_ds m;
+	struct msqid_ds32 *up32 = (struct msqid_ds32 *)uptr;
+	struct msqid64_ds32 *up64 = (struct msqid64_ds32 *)uptr;
+	mm_segment_t old_fs;
+
+	switch (second & ~IPC_64) {
+	case IPC_INFO:
+	case IPC_RMID:
+	case MSG_INFO:
+		err = sys_msgctl (first, second, (struct msqid_ds *)uptr);
+		break;
+
+	case IPC_SET:
+		if (second & IPC_64) {
+			if (!access_ok(VERIFY_READ, up64, sizeof(*up64))) {
+				err = -EFAULT;
+				break;
+			}
+			err = __get_user(m.msg_perm.uid, &up64->msg_perm.uid);
+			err |= __get_user(m.msg_perm.gid, &up64->msg_perm.gid);
+			err |= __get_user(m.msg_perm.mode, &up64->msg_perm.mode);
+			err |= __get_user(m.msg_qbytes, &up64->msg_qbytes);
+		} else {
+			if (!access_ok(VERIFY_READ, up32, sizeof(*up32))) {
+				err = -EFAULT;
+				break;
+			}
+			err = __get_user(m.msg_perm.uid, &up32->msg_perm.uid);
+			err |= __get_user(m.msg_perm.gid, &up32->msg_perm.gid);
+			err |= __get_user(m.msg_perm.mode, &up32->msg_perm.mode);
+			err |= __get_user(m.msg_qbytes, &up32->msg_qbytes);
+		}
+		if (err)
+			break;
+		old_fs = get_fs();
+		set_fs(KERNEL_DS);
+		err = sys_msgctl(first, second | IPC_64, (struct msqid_ds *)&m);
+		set_fs(old_fs);
+		break;
+
+	case IPC_STAT:
+	case MSG_STAT:
+		old_fs = get_fs();
+		set_fs(KERNEL_DS);
+		err = sys_msgctl(first, second | IPC_64, (struct msqid_ds *)&m);
+		set_fs(old_fs);
+		if (second & IPC_64) {
+			if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) {
+				err = -EFAULT;
+				break;
+			}
+			err2 = __put_user(m.msg_perm.key, &up64->msg_perm.key);
+			err2 |= __put_user(m.msg_perm.uid, &up64->msg_perm.uid);
+			err2 |= __put_user(m.msg_perm.gid, &up64->msg_perm.gid);
+			err2 |= __put_user(m.msg_perm.cuid, &up64->msg_perm.cuid);
+			err2 |= __put_user(m.msg_perm.cgid, &up64->msg_perm.cgid);
+			err2 |= __put_user(m.msg_perm.mode, &up64->msg_perm.mode);
+			err2 |= __put_user(m.msg_perm.seq, &up64->msg_perm.seq);
+			err2 |= __put_user(m.msg_stime, &up64->msg_stime);
+			err2 |= __put_user(m.msg_rtime, &up64->msg_rtime);
+			err2 |= __put_user(m.msg_ctime, &up64->msg_ctime);
+			err2 |= __put_user(m.msg_cbytes, &up64->msg_cbytes);
+			err2 |= __put_user(m.msg_qnum, &up64->msg_qnum);
+			err2 |= __put_user(m.msg_qbytes, &up64->msg_qbytes);
+			err2 |= __put_user(m.msg_lspid, &up64->msg_lspid);
+			err2 |= __put_user(m.msg_lrpid, &up64->msg_lrpid);
+			if (err2)
+				err = -EFAULT;
+		} else {
+			if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) {
+				err = -EFAULT;
+				break;
+			}
+			err2 = __put_user(m.msg_perm.key, &up32->msg_perm.key);
+			err2 |= __put_user(m.msg_perm.uid, &up32->msg_perm.uid);
+			err2 |= __put_user(m.msg_perm.gid, &up32->msg_perm.gid);
+			err2 |= __put_user(m.msg_perm.cuid, &up32->msg_perm.cuid);
+			err2 |= __put_user(m.msg_perm.cgid, &up32->msg_perm.cgid);
+			err2 |= __put_user(m.msg_perm.mode, &up32->msg_perm.mode);
+			err2 |= __put_user(m.msg_perm.seq, &up32->msg_perm.seq);
+			err2 |= __put_user(m.msg_stime, &up32->msg_stime);
+			err2 |= __put_user(m.msg_rtime, &up32->msg_rtime);
+			err2 |= __put_user(m.msg_ctime, &up32->msg_ctime);
+			err2 |= __put_user(m.msg_cbytes, &up32->msg_cbytes);
+			err2 |= __put_user(m.msg_qnum, &up32->msg_qnum);
+			err2 |= __put_user(m.msg_qbytes, &up32->msg_qbytes);
+			err2 |= __put_user(m.msg_lspid, &up32->msg_lspid);
+			err2 |= __put_user(m.msg_lrpid, &up32->msg_lrpid);
+			if (err2)
+				err = -EFAULT;
+		}
+		break;
+	}
+
+	return err;
+}
+
+static int
+do_sys32_shmat (int first, int second, int third, int version, void *uptr)
+{
+	unsigned long raddr;
+	u32 *uaddr = (u32 *)A((u32)third);
+	int err = -EINVAL;
+
+	if (version == 1)
+		return err;
+	err = do_shmat (first, uptr, second, &raddr);
+	if (err)
+		return err;
+	err = put_user (raddr, uaddr);
+	return err;
+}
+
+struct shm_info32 {
+	int used_ids;
+	u32 shm_tot, shm_rss, shm_swp;
+	u32 swap_attempts, swap_successes;
+};
+
+static int
+do_sys32_shmctl (int first, int second, void *uptr)
+{
+	struct shmid64_ds32 *up64 = (struct shmid64_ds32 *)uptr;
+	struct shmid_ds32 *up32 = (struct shmid_ds32 *)uptr;
+	struct shm_info32 *uip = (struct shm_info32 *)uptr;
+	int err = -EFAULT, err2;
+	struct shmid64_ds s64;
+	mm_segment_t old_fs;
+	struct shm_info si;
+	struct shmid_ds s;
+
+	switch (second & ~IPC_64) {
+	case IPC_INFO:
+		second = IPC_INFO; /* So that we don't have to translate it */
+	case IPC_RMID:
+	case SHM_LOCK:
+	case SHM_UNLOCK:
+		err = sys_shmctl(first, second, (struct shmid_ds *)uptr);
+		break;
+	case IPC_SET:
+		if (second & IPC_64) {
+			err = get_user(s.shm_perm.uid, &up64->shm_perm.uid);
+			err |= get_user(s.shm_perm.gid, &up64->shm_perm.gid);
+			err |= get_user(s.shm_perm.mode, &up64->shm_perm.mode);
+		} else {
+			err = get_user(s.shm_perm.uid, &up32->shm_perm.uid);
+			err |= get_user(s.shm_perm.gid, &up32->shm_perm.gid);
+			err |= get_user(s.shm_perm.mode, &up32->shm_perm.mode);
+		}
+		if (err)
+			break;
+		old_fs = get_fs();
+		set_fs(KERNEL_DS);
+		err = sys_shmctl(first, second & ~IPC_64, &s);
+		set_fs(old_fs);
+		break;
+
+	case IPC_STAT:
+	case SHM_STAT:
+		old_fs = get_fs();
+		set_fs(KERNEL_DS);
+		err = sys_shmctl(first, second | IPC_64, (void *) &s64);
+		set_fs(old_fs);
+		if (err < 0)
+			break;
+		if (second & IPC_64) {
+			if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) {
+				err = -EFAULT;
+				break;
+			}
+			err2 = __put_user(s64.shm_perm.key, &up64->shm_perm.key);
+			err2 |= __put_user(s64.shm_perm.uid, &up64->shm_perm.uid);
+			err2 |= __put_user(s64.shm_perm.gid, &up64->shm_perm.gid);
+			err2 |= __put_user(s64.shm_perm.cuid, &up64->shm_perm.cuid);
+			err2 |= __put_user(s64.shm_perm.cgid, &up64->shm_perm.cgid);
+			err2 |= __put_user(s64.shm_perm.mode, &up64->shm_perm.mode);
+			err2 |= __put_user(s64.shm_perm.seq, &up64->shm_perm.seq);
+			err2 |= __put_user(s64.shm_atime, &up64->shm_atime);
+			err2 |= __put_user(s64.shm_dtime, &up64->shm_dtime);
+			err2 |= __put_user(s64.shm_ctime, &up64->shm_ctime);
+			err2 |= __put_user(s64.shm_segsz, &up64->shm_segsz);
+			err2 |= __put_user(s64.shm_nattch, &up64->shm_nattch);
+			err2 |= __put_user(s64.shm_cpid, &up64->shm_cpid);
+			err2 |= __put_user(s64.shm_lpid, &up64->shm_lpid);
+		} else {
+			if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) {
+				err = -EFAULT;
+				break;
+			}
+			err2 = __put_user(s64.shm_perm.key, &up32->shm_perm.key);
+			err2 |= __put_user(s64.shm_perm.uid, &up32->shm_perm.uid);
+			err2 |= __put_user(s64.shm_perm.gid, &up32->shm_perm.gid);
+			err2 |= __put_user(s64.shm_perm.cuid, &up32->shm_perm.cuid);
+			err2 |= __put_user(s64.shm_perm.cgid, &up32->shm_perm.cgid);
+			err2 |= __put_user(s64.shm_perm.mode, &up32->shm_perm.mode);
+			err2 |= __put_user(s64.shm_perm.seq, &up32->shm_perm.seq);
+			err2 |= __put_user(s64.shm_atime, &up32->shm_atime);
+			err2 |= __put_user(s64.shm_dtime, &up32->shm_dtime);
+			err2 |= __put_user(s64.shm_ctime, &up32->shm_ctime);
+			err2 |= __put_user(s64.shm_segsz, &up32->shm_segsz);
+			err2 |= __put_user(s64.shm_nattch, &up32->shm_nattch);
+			err2 |= __put_user(s64.shm_cpid, &up32->shm_cpid);
+			err2 |= __put_user(s64.shm_lpid, &up32->shm_lpid);
+		}
+		if (err2)
+			err = -EFAULT;
+		break;
+
+	case SHM_INFO:
+		old_fs = get_fs();
+		set_fs(KERNEL_DS);
+		err = sys_shmctl(first, second, (void *)&si);
+		set_fs(old_fs);
+		if (err < 0)
+			break;
+		err2 = put_user(si.used_ids, &uip->used_ids);
+		err2 |= __put_user(si.shm_tot, &uip->shm_tot);
+		err2 |= __put_user(si.shm_rss, &uip->shm_rss);
+		err2 |= __put_user(si.shm_swp, &uip->shm_swp);
+		err2 |= __put_user(si.swap_attempts, &uip->swap_attempts);
+		err2 |= __put_user (si.swap_successes, &uip->swap_successes);
+		if (err2)
+			err = -EFAULT;
+		break;
+
+	default:
+		err = -EINVAL;
+		break;
+	}
+
+	return err;
+}
+
+static int sys32_semtimedop(int semid, struct sembuf *tsems, int nsems,
+                            const struct compat_timespec *timeout32)
+{
+	struct compat_timespec t32;
+	struct timespec *t64 = compat_alloc_user_space(sizeof(*t64));
+
+	if (copy_from_user(&t32, timeout32, sizeof(t32)))
+		return -EFAULT;
+
+	if (put_user(t32.tv_sec, &t64->tv_sec) ||
+	    put_user(t32.tv_nsec, &t64->tv_nsec))
+		return -EFAULT;
+
+	return sys_semtimedop(semid, tsems, nsems, t64);
+}
+
+asmlinkage long
+sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
+{
+	int version, err;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	switch (call) {
+	case SEMOP:
+		/* struct sembuf is the same on 32 and 64bit :)) */
+		err = sys_semtimedop (first, (struct sembuf *)AA(ptr), second,
+		                      NULL);
+		break;
+	case SEMTIMEDOP:
+		err = sys32_semtimedop (first, (struct sembuf *)AA(ptr), second,
+		                      (const struct compat_timespec __user *)AA(fifth));
+		break;
+	case SEMGET:
+		err = sys_semget (first, second, third);
+		break;
+	case SEMCTL:
+		err = do_sys32_semctl (first, second, third,
+				       (void *)AA(ptr));
+		break;
+
+	case MSGSND:
+		err = do_sys32_msgsnd (first, second, third,
+				       (void *)AA(ptr));
+		break;
+	case MSGRCV:
+		err = do_sys32_msgrcv (first, second, fifth, third,
+				       version, (void *)AA(ptr));
+		break;
+	case MSGGET:
+		err = sys_msgget ((key_t) first, second);
+		break;
+	case MSGCTL:
+		err = do_sys32_msgctl (first, second, (void *)AA(ptr));
+		break;
+
+	case SHMAT:
+		err = do_sys32_shmat (first, second, third,
+				      version, (void *)AA(ptr));
+		break;
+	case SHMDT:
+		err = sys_shmdt ((char *)A(ptr));
+		break;
+	case SHMGET:
+		err = sys_shmget (first, (unsigned)second, third);
+		break;
+	case SHMCTL:
+		err = do_sys32_shmctl (first, second, (void *)AA(ptr));
+		break;
+	default:
+		err = -EINVAL;
+		break;
+	}
+
+	return err;
+}
+
+asmlinkage long sys32_shmat(int shmid, char __user *shmaddr,
+			  int shmflg, int32_t *addr)
+{
+	unsigned long raddr;
+	int err;
+
+	err = do_shmat(shmid, shmaddr, shmflg, &raddr);
+	if (err)
+		return err;
+
+	return put_user(raddr, addr);
+}
+
+struct sysctl_args32
+{
+	compat_caddr_t name;
+	int nlen;
+	compat_caddr_t oldval;
+	compat_caddr_t oldlenp;
+	compat_caddr_t newval;
+	compat_size_t newlen;
+	unsigned int __unused[4];
+};
+
+#ifdef CONFIG_SYSCTL
+
+asmlinkage long sys32_sysctl(struct sysctl_args32 *args)
+{
+	struct sysctl_args32 tmp;
+	int error;
+	size_t oldlen, *oldlenp = NULL;
+	unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7;
+
+	if (copy_from_user(&tmp, args, sizeof(tmp)))
+		return -EFAULT;
+
+	if (tmp.oldval && tmp.oldlenp) {
+		/* Duh, this is ugly and might not work if sysctl_args
+		   is in read-only memory, but do_sysctl does indirectly
+		   a lot of uaccess in both directions and we'd have to
+		   basically copy the whole sysctl.c here, and
+		   glibc's __sysctl uses rw memory for the structure
+		   anyway.  */
+		if (get_user(oldlen, (u32 *)A(tmp.oldlenp)) ||
+		    put_user(oldlen, (size_t *)addr))
+			return -EFAULT;
+		oldlenp = (size_t *)addr;
+	}
+
+	lock_kernel();
+	error = do_sysctl((int *)A(tmp.name), tmp.nlen, (void *)A(tmp.oldval),
+			  oldlenp, (void *)A(tmp.newval), tmp.newlen);
+	unlock_kernel();
+	if (oldlenp) {
+		if (!error) {
+			if (get_user(oldlen, (size_t *)addr) ||
+			    put_user(oldlen, (u32 *)A(tmp.oldlenp)))
+				error = -EFAULT;
+		}
+		copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
+	}
+	return error;
+}
+
+#endif /* CONFIG_SYSCTL */
+
+asmlinkage long sys32_newuname(struct new_utsname * name)
+{
+	int ret = 0;
+
+	down_read(&uts_sem);
+	if (copy_to_user(name,&system_utsname,sizeof *name))
+		ret = -EFAULT;
+	up_read(&uts_sem);
+
+	if (current->personality == PER_LINUX32 && !ret)
+		if (copy_to_user(name->machine, "mips\0\0\0", 8))
+			ret = -EFAULT;
+
+	return ret;
+}
+
+asmlinkage int sys32_personality(unsigned long personality)
+{
+	int ret;
+	if (current->personality == PER_LINUX32 && personality == PER_LINUX)
+		personality = PER_LINUX32;
+	ret = sys_personality(personality);
+	if (ret == PER_LINUX32)
+		ret = PER_LINUX;
+	return ret;
+}
+
+/* ustat compatibility */
+struct ustat32 {
+	compat_daddr_t	f_tfree;
+	compat_ino_t	f_tinode;
+	char		f_fname[6];
+	char		f_fpack[6];
+};
+
+extern asmlinkage long sys_ustat(dev_t dev, struct ustat * ubuf);
+
+asmlinkage int sys32_ustat(dev_t dev, struct ustat32 * ubuf32)
+{
+	int err;
+        struct ustat tmp;
+	struct ustat32 tmp32;
+	mm_segment_t old_fs = get_fs();
+
+	set_fs(KERNEL_DS);
+	err = sys_ustat(dev, &tmp);
+	set_fs (old_fs);
+
+	if (err)
+		goto out;
+
+        memset(&tmp32,0,sizeof(struct ustat32));
+        tmp32.f_tfree = tmp.f_tfree;
+        tmp32.f_tinode = tmp.f_tinode;
+
+        err = copy_to_user(ubuf32,&tmp32,sizeof(struct ustat32)) ? -EFAULT : 0;
+
+out:
+	return err;
+}
+
+/* Handle adjtimex compatibility. */
+
+struct timex32 {
+	u32 modes;
+	s32 offset, freq, maxerror, esterror;
+	s32 status, constant, precision, tolerance;
+	struct compat_timeval time;
+	s32 tick;
+	s32 ppsfreq, jitter, shift, stabil;
+	s32 jitcnt, calcnt, errcnt, stbcnt;
+	s32  :32; s32  :32; s32  :32; s32  :32;
+	s32  :32; s32  :32; s32  :32; s32  :32;
+	s32  :32; s32  :32; s32  :32; s32  :32;
+};
+
+extern int do_adjtimex(struct timex *);
+
+asmlinkage int sys32_adjtimex(struct timex32 *utp)
+{
+	struct timex txc;
+	int ret;
+
+	memset(&txc, 0, sizeof(struct timex));
+
+	if (get_user(txc.modes, &utp->modes) ||
+	   __get_user(txc.offset, &utp->offset) ||
+	   __get_user(txc.freq, &utp->freq) ||
+	   __get_user(txc.maxerror, &utp->maxerror) ||
+	   __get_user(txc.esterror, &utp->esterror) ||
+	   __get_user(txc.status, &utp->status) ||
+	   __get_user(txc.constant, &utp->constant) ||
+	   __get_user(txc.precision, &utp->precision) ||
+	   __get_user(txc.tolerance, &utp->tolerance) ||
+	   __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
+	   __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
+	   __get_user(txc.tick, &utp->tick) ||
+	   __get_user(txc.ppsfreq, &utp->ppsfreq) ||
+	   __get_user(txc.jitter, &utp->jitter) ||
+	   __get_user(txc.shift, &utp->shift) ||
+	   __get_user(txc.stabil, &utp->stabil) ||
+	   __get_user(txc.jitcnt, &utp->jitcnt) ||
+	   __get_user(txc.calcnt, &utp->calcnt) ||
+	   __get_user(txc.errcnt, &utp->errcnt) ||
+	   __get_user(txc.stbcnt, &utp->stbcnt))
+		return -EFAULT;
+
+	ret = do_adjtimex(&txc);
+
+	if (put_user(txc.modes, &utp->modes) ||
+	   __put_user(txc.offset, &utp->offset) ||
+	   __put_user(txc.freq, &utp->freq) ||
+	   __put_user(txc.maxerror, &utp->maxerror) ||
+	   __put_user(txc.esterror, &utp->esterror) ||
+	   __put_user(txc.status, &utp->status) ||
+	   __put_user(txc.constant, &utp->constant) ||
+	   __put_user(txc.precision, &utp->precision) ||
+	   __put_user(txc.tolerance, &utp->tolerance) ||
+	   __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
+	   __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
+	   __put_user(txc.tick, &utp->tick) ||
+	   __put_user(txc.ppsfreq, &utp->ppsfreq) ||
+	   __put_user(txc.jitter, &utp->jitter) ||
+	   __put_user(txc.shift, &utp->shift) ||
+	   __put_user(txc.stabil, &utp->stabil) ||
+	   __put_user(txc.jitcnt, &utp->jitcnt) ||
+	   __put_user(txc.calcnt, &utp->calcnt) ||
+	   __put_user(txc.errcnt, &utp->errcnt) ||
+	   __put_user(txc.stbcnt, &utp->stbcnt))
+		ret = -EFAULT;
+
+	return ret;
+}
+
+asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset,
+	s32 count)
+{
+	mm_segment_t old_fs = get_fs();
+	int ret;
+	off_t of;
+	
+	if (offset && get_user(of, offset))
+		return -EFAULT;
+		
+	set_fs(KERNEL_DS);
+	ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
+	set_fs(old_fs);
+	
+	if (offset && put_user(of, offset))
+		return -EFAULT;
+		
+	return ret;
+}
+
+asmlinkage ssize_t sys32_readahead(int fd, u32 pad0, u64 a2, u64 a3,
+                                   size_t count)
+{
+	return sys_readahead(fd, merge_64(a2, a3), count);
+}
+
+/* Argument list sizes for sys_socketcall */
+#define AL(x) ((x) * sizeof(unsigned int))
+static unsigned char socketcall_nargs[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
+				AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
+				AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};
+#undef AL
+
+/*
+ *	System call vectors. 
+ *
+ *	Argument checking cleaned up. Saved 20% in size.
+ *  This function doesn't need to set the kernel lock because
+ *  it is set by the callees. 
+ */
+
+asmlinkage long sys32_socketcall(int call, unsigned int *args32)
+{
+	unsigned int a[6];
+	unsigned int a0,a1;
+	int err;
+
+	extern asmlinkage long sys_socket(int family, int type, int protocol);
+	extern asmlinkage long sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen);
+	extern asmlinkage long sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen);
+	extern asmlinkage long sys_listen(int fd, int backlog);
+	extern asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int __user *upeer_addrlen);
+	extern asmlinkage long sys_getsockname(int fd, struct sockaddr __user *usockaddr, int __user *usockaddr_len);
+	extern asmlinkage long sys_getpeername(int fd, struct sockaddr __user *usockaddr, int __user *usockaddr_len);
+	extern asmlinkage long sys_socketpair(int family, int type, int protocol, int __user *usockvec);
+	extern asmlinkage long sys_send(int fd, void __user * buff, size_t len, unsigned flags);
+	extern asmlinkage long sys_sendto(int fd, void __user * buff, size_t len, unsigned flags,
+					  struct sockaddr __user *addr, int addr_len);
+	extern asmlinkage long sys_recv(int fd, void __user * ubuf, size_t size, unsigned flags);
+	extern asmlinkage long sys_recvfrom(int fd, void __user * ubuf, size_t size, unsigned flags,
+					    struct sockaddr __user *addr, int __user *addr_len);
+	extern asmlinkage long sys_shutdown(int fd, int how);
+	extern asmlinkage long sys_setsockopt(int fd, int level, int optname, char __user *optval, int optlen);
+	extern asmlinkage long sys_getsockopt(int fd, int level, int optname, char __user *optval, int *optlen);
+	extern asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags);
+	extern asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned int flags);
+
+
+	if(call<1||call>SYS_RECVMSG)
+		return -EINVAL;
+
+	/* copy_from_user should be SMP safe. */
+	if (copy_from_user(a, args32, socketcall_nargs[call]))
+		return -EFAULT;
+		
+	a0=a[0];
+	a1=a[1];
+	
+	switch(call) 
+	{
+		case SYS_SOCKET:
+			err = sys_socket(a0,a1,a[2]);
+			break;
+		case SYS_BIND:
+			err = sys_bind(a0,(struct sockaddr __user *)A(a1), a[2]);
+			break;
+		case SYS_CONNECT:
+			err = sys_connect(a0, (struct sockaddr __user *)A(a1), a[2]);
+			break;
+		case SYS_LISTEN:
+			err = sys_listen(a0,a1);
+			break;
+		case SYS_ACCEPT:
+			err = sys_accept(a0,(struct sockaddr __user *)A(a1), (int __user *)A(a[2]));
+			break;
+		case SYS_GETSOCKNAME:
+			err = sys_getsockname(a0,(struct sockaddr __user *)A(a1), (int __user *)A(a[2]));
+			break;
+		case SYS_GETPEERNAME:
+			err = sys_getpeername(a0, (struct sockaddr __user *)A(a1), (int __user *)A(a[2]));
+			break;
+		case SYS_SOCKETPAIR:
+			err = sys_socketpair(a0,a1, a[2], (int __user *)A(a[3]));
+			break;
+		case SYS_SEND:
+			err = sys_send(a0, (void __user *)A(a1), a[2], a[3]);
+			break;
+		case SYS_SENDTO:
+			err = sys_sendto(a0,(void __user *)A(a1), a[2], a[3],
+					 (struct sockaddr __user *)A(a[4]), a[5]);
+			break;
+		case SYS_RECV:
+			err = sys_recv(a0, (void __user *)A(a1), a[2], a[3]);
+			break;
+		case SYS_RECVFROM:
+			err = sys_recvfrom(a0, (void __user *)A(a1), a[2], a[3],
+					   (struct sockaddr __user *)A(a[4]), (int __user *)A(a[5]));
+			break;
+		case SYS_SHUTDOWN:
+			err = sys_shutdown(a0,a1);
+			break;
+		case SYS_SETSOCKOPT:
+			err = sys_setsockopt(a0, a1, a[2], (char __user *)A(a[3]), a[4]);
+			break;
+		case SYS_GETSOCKOPT:
+			err = sys_getsockopt(a0, a1, a[2], (char __user *)A(a[3]), (int __user *)A(a[4]));
+			break;
+		case SYS_SENDMSG:
+			err = sys_sendmsg(a0, (struct msghdr __user *) A(a1), a[2]);
+			break;
+		case SYS_RECVMSG:
+			err = sys_recvmsg(a0, (struct msghdr __user *) A(a1), a[2]);
+			break;
+		default:
+			err = -EINVAL;
+			break;
+	}
+	return err;
+}
diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c
new file mode 100644
index 0000000..eed29fc
--- /dev/null
+++ b/arch/mips/kernel/mips_ksyms.c
@@ -0,0 +1,67 @@
+/*
+ * Export MIPS-specific functions needed for loadable modules.
+ *
+ * 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) 1996, 97, 98, 99, 2000, 01, 03, 04, 05 by Ralf Baechle
+ * Copyright (C) 1999, 2000, 01 Silicon Graphics, Inc.
+ */
+#include <linux/config.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <asm/checksum.h>
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+
+extern void *__bzero(void *__s, size_t __count);
+extern long __strncpy_from_user_nocheck_asm(char *__to,
+                                            const char *__from, long __len);
+extern long __strncpy_from_user_asm(char *__to, const char *__from,
+                                    long __len);
+extern long __strlen_user_nocheck_asm(const char *s);
+extern long __strlen_user_asm(const char *s);
+extern long __strnlen_user_nocheck_asm(const char *s);
+extern long __strnlen_user_asm(const char *s);
+
+/*
+ * String functions
+ */
+EXPORT_SYMBOL(memchr);
+EXPORT_SYMBOL(memcmp);
+EXPORT_SYMBOL(memset);
+EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(memmove);
+EXPORT_SYMBOL(strcat);
+EXPORT_SYMBOL(strchr);
+#ifdef CONFIG_MIPS64
+EXPORT_SYMBOL(strncmp);
+#endif
+EXPORT_SYMBOL(strlen);
+EXPORT_SYMBOL(strpbrk);
+EXPORT_SYMBOL(strncat);
+EXPORT_SYMBOL(strnlen);
+EXPORT_SYMBOL(strrchr);
+EXPORT_SYMBOL(strstr);
+
+EXPORT_SYMBOL(kernel_thread);
+
+/*
+ * Userspace access stuff.
+ */
+EXPORT_SYMBOL(__copy_user);
+EXPORT_SYMBOL(__bzero);
+EXPORT_SYMBOL(__strncpy_from_user_nocheck_asm);
+EXPORT_SYMBOL(__strncpy_from_user_asm);
+EXPORT_SYMBOL(__strlen_user_nocheck_asm);
+EXPORT_SYMBOL(__strlen_user_asm);
+EXPORT_SYMBOL(__strnlen_user_nocheck_asm);
+EXPORT_SYMBOL(__strnlen_user_asm);
+
+EXPORT_SYMBOL(csum_partial);
+
+EXPORT_SYMBOL(invalid_pte_table);
+#ifdef CONFIG_GENERIC_IRQ_PROBE
+EXPORT_SYMBOL(probe_irq_mask);
+#endif
diff --git a/arch/mips/kernel/module-elf32.c b/arch/mips/kernel/module-elf32.c
new file mode 100644
index 0000000..ffd216d
--- /dev/null
+++ b/arch/mips/kernel/module-elf32.c
@@ -0,0 +1,250 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  Copyright (C) 2001 Rusty Russell.
+ *  Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org)
+ */
+
+#undef DEBUG
+
+#include <linux/moduleloader.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+struct mips_hi16 {
+	struct mips_hi16 *next;
+	Elf32_Addr *addr;
+	Elf32_Addr value;
+};
+
+static struct mips_hi16 *mips_hi16_list;
+
+void *module_alloc(unsigned long size)
+{
+	if (size == 0)
+		return NULL;
+	return vmalloc(size);
+}
+
+
+/* Free memory returned from module_alloc */
+void module_free(struct module *mod, void *module_region)
+{
+	vfree(module_region);
+	/* FIXME: If module_region == mod->init_region, trim exception
+           table entries. */
+}
+
+int module_frob_arch_sections(Elf_Ehdr *hdr,
+			      Elf_Shdr *sechdrs,
+			      char *secstrings,
+			      struct module *mod)
+{
+	return 0;
+}
+
+static int apply_r_mips_none(struct module *me, uint32_t *location,
+	Elf32_Addr v)
+{
+	return 0;
+}
+
+static int apply_r_mips_32(struct module *me, uint32_t *location,
+	Elf32_Addr v)
+{
+	*location += v;
+
+	return 0;
+}
+
+static int apply_r_mips_26(struct module *me, uint32_t *location,
+	Elf32_Addr v)
+{
+	if (v % 4) {
+		printk(KERN_ERR "module %s: dangerous relocation\n", me->name);
+		return -ENOEXEC;
+	}
+
+	if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
+		printk(KERN_ERR
+		       "module %s: relocation overflow\n",
+		       me->name);
+		return -ENOEXEC;
+	}
+
+	*location = (*location & ~0x03ffffff) |
+	            ((*location + (v >> 2)) & 0x03ffffff);
+
+	return 0;
+}
+
+static int apply_r_mips_hi16(struct module *me, uint32_t *location,
+	Elf32_Addr v)
+{
+	struct mips_hi16 *n;
+
+	/*
+	 * We cannot relocate this one now because we don't know the value of
+	 * the carry we need to add.  Save the information, and let LO16 do the
+	 * actual relocation.
+	 */
+	n = kmalloc(sizeof *n, GFP_KERNEL);
+	if (!n)
+		return -ENOMEM;
+
+	n->addr = location;
+	n->value = v;
+	n->next = mips_hi16_list;
+	mips_hi16_list = n;
+
+	return 0;
+}
+
+static int apply_r_mips_lo16(struct module *me, uint32_t *location,
+	Elf32_Addr v)
+{
+	unsigned long insnlo = *location;
+	Elf32_Addr val, vallo;
+
+	/* Sign extend the addend we extract from the lo insn.  */
+	vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
+
+	if (mips_hi16_list != NULL) {
+		struct mips_hi16 *l;
+
+		l = mips_hi16_list;
+		while (l != NULL) {
+			struct mips_hi16 *next;
+			unsigned long insn;
+
+			/*
+			 * The value for the HI16 had best be the same.
+			 */
+			if (v != l->value)
+				goto out_danger;
+
+			/*
+			 * Do the HI16 relocation.  Note that we actually don't
+			 * need to know anything about the LO16 itself, except
+			 * where to find the low 16 bits of the addend needed
+			 * by the LO16.
+			 */
+			insn = *l->addr;
+			val = ((insn & 0xffff) << 16) + vallo;
+			val += v;
+
+			/*
+			 * Account for the sign extension that will happen in
+			 * the low bits.
+			 */
+			val = ((val >> 16) + ((val & 0x8000) != 0)) & 0xffff;
+
+			insn = (insn & ~0xffff) | val;
+			*l->addr = insn;
+
+			next = l->next;
+			kfree(l);
+			l = next;
+		}
+
+		mips_hi16_list = NULL;
+	}
+
+	/*
+	 * Ok, we're done with the HI16 relocs.  Now deal with the LO16.
+	 */
+	val = v + vallo;
+	insnlo = (insnlo & ~0xffff) | (val & 0xffff);
+	*location = insnlo;
+
+	return 0;
+
+out_danger:
+	printk(KERN_ERR "module %s: dangerous " "relocation\n", me->name);
+
+	return -ENOEXEC;
+}
+
+static int (*reloc_handlers[]) (struct module *me, uint32_t *location,
+	Elf32_Addr v) = {
+	[R_MIPS_NONE]	= apply_r_mips_none,
+	[R_MIPS_32]	= apply_r_mips_32,
+	[R_MIPS_26]	= apply_r_mips_26,
+	[R_MIPS_HI16]	= apply_r_mips_hi16,
+	[R_MIPS_LO16]	= apply_r_mips_lo16
+};
+
+int apply_relocate(Elf32_Shdr *sechdrs,
+		   const char *strtab,
+		   unsigned int symindex,
+		   unsigned int relsec,
+		   struct module *me)
+{
+	Elf32_Rel *rel = (void *) sechdrs[relsec].sh_addr;
+	Elf32_Sym *sym;
+	uint32_t *location;
+	unsigned int i;
+	Elf32_Addr v;
+	int res;
+
+	pr_debug("Applying relocate section %u to %u\n", relsec,
+	       sechdrs[relsec].sh_info);
+
+	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+		Elf32_Word r_info = rel[i].r_info;
+
+		/* This is where to make the change */
+		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+			+ rel[i].r_offset;
+		/* This is the symbol it is referring to */
+		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
+			+ ELF32_R_SYM(r_info);
+		if (!sym->st_value) {
+			printk(KERN_WARNING "%s: Unknown symbol %s\n",
+			       me->name, strtab + sym->st_name);
+			return -ENOENT;
+		}
+
+		v = sym->st_value;
+
+		res = reloc_handlers[ELF32_R_TYPE(r_info)](me, location, v);
+		if (res)
+			return res;
+	}
+
+	return 0;
+}
+
+int apply_relocate_add(Elf32_Shdr *sechdrs,
+		       const char *strtab,
+		       unsigned int symindex,
+		       unsigned int relsec,
+		       struct module *me)
+{
+	/*
+	 * Current binutils always generate .rela relocations.  Keep smiling
+	 * if it's empty, abort otherwise.
+	 */
+	if (!sechdrs[relsec].sh_size)
+		return 0;
+
+	printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n",
+	       me->name);
+	return -ENOEXEC;
+}
diff --git a/arch/mips/kernel/module-elf64.c b/arch/mips/kernel/module-elf64.c
new file mode 100644
index 0000000..e804792
--- /dev/null
+++ b/arch/mips/kernel/module-elf64.c
@@ -0,0 +1,274 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  Copyright (C) 2001 Rusty Russell.
+ *  Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org)
+ */
+
+#undef DEBUG
+
+#include <linux/moduleloader.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+struct mips_hi16 {
+	struct mips_hi16 *next;
+	Elf32_Addr *addr;
+	Elf64_Addr value;
+};
+
+static struct mips_hi16 *mips_hi16_list;
+
+void *module_alloc(unsigned long size)
+{
+	if (size == 0)
+		return NULL;
+	return vmalloc(size);
+}
+
+
+/* Free memory returned from module_alloc */
+void module_free(struct module *mod, void *module_region)
+{
+	vfree(module_region);
+	/* FIXME: If module_region == mod->init_region, trim exception
+           table entries. */
+}
+
+int module_frob_arch_sections(Elf_Ehdr *hdr,
+			      Elf_Shdr *sechdrs,
+			      char *secstrings,
+			      struct module *mod)
+{
+	return 0;
+}
+
+int apply_relocate(Elf64_Shdr *sechdrs,
+		   const char *strtab,
+		   unsigned int symindex,
+		   unsigned int relsec,
+		   struct module *me)
+{
+	/*
+	 * We don't want to deal with REL relocations - RELA is so much saner.
+	 */
+	if (!sechdrs[relsec].sh_size)
+		return 0;
+
+	printk(KERN_ERR "module %s: REL relocation unsupported\n",
+	       me->name);
+	return -ENOEXEC;
+}
+
+static int apply_r_mips_none(struct module *me, uint32_t *location,
+	Elf64_Addr v)
+{
+	return 0;
+}
+
+static int apply_r_mips_32(struct module *me, uint32_t *location,
+	Elf64_Addr v)
+{
+	*location = v;
+
+	return 0;
+}
+
+static int apply_r_mips_26(struct module *me, uint32_t *location,
+	Elf64_Addr v)
+{
+	if (v % 4) {
+		printk(KERN_ERR "module %s: dangerous relocation\n", me->name);
+		return -ENOEXEC;
+	}
+
+	if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
+		printk(KERN_ERR
+		       "module %s: relocation overflow\n",
+		       me->name);
+		return -ENOEXEC;
+	}
+
+	*location = (*location & ~0x03ffffff) | ((v >> 2) & 0x03ffffff);
+
+	return 0;
+}
+
+static int apply_r_mips_hi16(struct module *me, uint32_t *location,
+	Elf64_Addr v)
+{
+	struct mips_hi16 *n;
+
+	/*
+	 * We cannot relocate this one now because we don't know the value of
+	 * the carry we need to add.  Save the information, and let LO16 do the
+	 * actual relocation.
+	 */
+	n = kmalloc(sizeof *n, GFP_KERNEL);
+	if (!n)
+		return -ENOMEM;
+
+	n->addr = location;
+	n->value = v;
+	n->next = mips_hi16_list;
+	mips_hi16_list = n;
+
+	return 0;
+}
+
+static int apply_r_mips_lo16(struct module *me, uint32_t *location,
+	Elf64_Addr v)
+{
+	unsigned long insnlo = *location;
+	Elf32_Addr val, vallo;
+
+	/* Sign extend the addend we extract from the lo insn.  */
+	vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
+
+	if (mips_hi16_list != NULL) {
+		struct mips_hi16 *l;
+
+		l = mips_hi16_list;
+		while (l != NULL) {
+			struct mips_hi16 *next;
+			unsigned long insn;
+
+			/*
+			 * The value for the HI16 had best be the same.
+			 */
+			if (v != l->value)
+				goto out_danger;
+
+			/*
+			 * Do the HI16 relocation.  Note that we actually don't
+			 * need to know anything about the LO16 itself, except
+			 * where to find the low 16 bits of the addend needed
+			 * by the LO16.
+			 */
+			insn = *l->addr;
+			val = ((insn & 0xffff) << 16) + vallo;
+			val += v;
+
+			/*
+			 * Account for the sign extension that will happen in
+			 * the low bits.
+			 */
+			val = ((val >> 16) + ((val & 0x8000) != 0)) & 0xffff;
+
+			insn = (insn & ~0xffff) | val;
+			*l->addr = insn;
+
+			next = l->next;
+			kfree(l);
+			l = next;
+		}
+
+		mips_hi16_list = NULL;
+	}
+
+	/*
+	 * Ok, we're done with the HI16 relocs.  Now deal with the LO16.
+	 */
+	insnlo = (insnlo & ~0xffff) | (v & 0xffff);
+	*location = insnlo;
+
+	return 0;
+
+out_danger:
+	printk(KERN_ERR "module %s: dangerous " "relocation\n", me->name);
+
+	return -ENOEXEC;
+}
+
+static int apply_r_mips_64(struct module *me, uint32_t *location,
+	Elf64_Addr v)
+{
+	*(uint64_t *) location = v;
+
+	return 0;
+}
+
+
+static int apply_r_mips_higher(struct module *me, uint32_t *location,
+	Elf64_Addr v)
+{
+	*location = (*location & 0xffff0000) |
+	            ((((long long) v + 0x80008000LL) >> 32) & 0xffff);
+
+	return 0;
+}
+
+static int apply_r_mips_highest(struct module *me, uint32_t *location,
+	Elf64_Addr v)
+{
+	*location = (*location & 0xffff0000) |
+	            ((((long long) v + 0x800080008000LL) >> 48) & 0xffff);
+
+	return 0;
+}
+
+static int (*reloc_handlers[]) (struct module *me, uint32_t *location,
+	Elf64_Addr v) = {
+	[R_MIPS_NONE]		= apply_r_mips_none,
+	[R_MIPS_32]		= apply_r_mips_32,
+	[R_MIPS_26]		= apply_r_mips_26,
+	[R_MIPS_HI16]		= apply_r_mips_hi16,
+	[R_MIPS_LO16]		= apply_r_mips_lo16,
+	[R_MIPS_64]		= apply_r_mips_64,
+	[R_MIPS_HIGHER]		= apply_r_mips_higher,
+	[R_MIPS_HIGHEST]	= apply_r_mips_highest
+};
+
+int apply_relocate_add(Elf64_Shdr *sechdrs,
+		       const char *strtab,
+		       unsigned int symindex,
+		       unsigned int relsec,
+		       struct module *me)
+{
+	Elf64_Mips_Rela *rel = (void *) sechdrs[relsec].sh_addr;
+	Elf64_Sym *sym;
+	uint32_t *location;
+	unsigned int i;
+	Elf64_Addr v;
+	int res;
+
+	pr_debug("Applying relocate section %u to %u\n", relsec,
+	       sechdrs[relsec].sh_info);
+
+	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+		/* This is where to make the change */
+		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+			+ rel[i].r_offset;
+		/* This is the symbol it is referring to */
+		sym = (Elf64_Sym *)sechdrs[symindex].sh_addr + rel[i].r_sym;
+		if (!sym->st_value) {
+			printk(KERN_WARNING "%s: Unknown symbol %s\n",
+			       me->name, strtab + sym->st_name);
+			return -ENOENT;
+		}
+
+		v = sym->st_value;
+
+		res = reloc_handlers[rel[i].r_type](me, location, v);
+		if (res)
+			return res;
+	}
+
+	return 0;
+}
diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c
new file mode 100644
index 0000000..458af3c
--- /dev/null
+++ b/arch/mips/kernel/module.c
@@ -0,0 +1,53 @@
+#include <linux/module.h>
+#include <linux/spinlock.h>
+
+static LIST_HEAD(dbe_list);
+static DEFINE_SPINLOCK(dbe_lock);
+
+/* Given an address, look for it in the module exception tables. */
+const struct exception_table_entry *search_module_dbetables(unsigned long addr)
+{
+	unsigned long flags;
+	const struct exception_table_entry *e = NULL;
+	struct mod_arch_specific *dbe;
+
+	spin_lock_irqsave(&dbe_lock, flags);
+	list_for_each_entry(dbe, &dbe_list, dbe_list) {
+		e = search_extable(dbe->dbe_start, dbe->dbe_end - 1, addr);
+		if (e)
+			break;
+	}
+	spin_unlock_irqrestore(&dbe_lock, flags);
+
+	/* Now, if we found one, we are running inside it now, hence
+           we cannot unload the module, hence no refcnt needed. */
+	return e;
+}
+
+/* Put in dbe list if neccessary. */
+int module_finalize(const Elf_Ehdr *hdr,
+		    const Elf_Shdr *sechdrs,
+		    struct module *me)
+{
+	const Elf_Shdr *s;
+	char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+
+	INIT_LIST_HEAD(&me->arch.dbe_list);
+	for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
+		if (strcmp("__dbe_table", secstrings + s->sh_name) != 0)
+			continue;
+		me->arch.dbe_start = (void *)s->sh_addr;
+		me->arch.dbe_end = (void *)s->sh_addr + s->sh_size;
+		spin_lock_irq(&dbe_lock);
+		list_add(&me->arch.dbe_list, &dbe_list);
+		spin_unlock_irq(&dbe_lock);
+	}
+	return 0;
+}
+
+void module_arch_cleanup(struct module *mod)
+{
+	spin_lock_irq(&dbe_lock);
+	list_del(&mod->arch.dbe_list);
+	spin_unlock_irq(&dbe_lock);
+}
diff --git a/arch/mips/kernel/offset.c b/arch/mips/kernel/offset.c
new file mode 100644
index 0000000..2c11abb
--- /dev/null
+++ b/arch/mips/kernel/offset.c
@@ -0,0 +1,314 @@
+/*
+ * offset.c: Calculate pt_regs and task_struct offsets.
+ *
+ * Copyright (C) 1996 David S. Miller
+ * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ *
+ * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.
+ */
+#include <linux/config.h>
+#include <linux/compat.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+
+#include <asm/ptrace.h>
+#include <asm/processor.h>
+
+#define text(t) __asm__("\n@@@" t)
+#define _offset(type, member) (&(((type *)NULL)->member))
+#define offset(string, ptr, member) \
+	__asm__("\n@@@" string "%0" : : "i" (_offset(ptr, member)))
+#define constant(string, member) \
+	__asm__("\n@@@" string "%x0" : : "ri" (member))
+#define size(string, size) \
+	__asm__("\n@@@" string "%0" : : "i" (sizeof(size)))
+#define linefeed text("")
+
+void output_ptreg_defines(void)
+{
+	text("/* MIPS pt_regs offsets. */");
+	offset("#define PT_R0     ", struct pt_regs, regs[0]);
+	offset("#define PT_R1     ", struct pt_regs, regs[1]);
+	offset("#define PT_R2     ", struct pt_regs, regs[2]);
+	offset("#define PT_R3     ", struct pt_regs, regs[3]);
+	offset("#define PT_R4     ", struct pt_regs, regs[4]);
+	offset("#define PT_R5     ", struct pt_regs, regs[5]);
+	offset("#define PT_R6     ", struct pt_regs, regs[6]);
+	offset("#define PT_R7     ", struct pt_regs, regs[7]);
+	offset("#define PT_R8     ", struct pt_regs, regs[8]);
+	offset("#define PT_R9     ", struct pt_regs, regs[9]);
+	offset("#define PT_R10    ", struct pt_regs, regs[10]);
+	offset("#define PT_R11    ", struct pt_regs, regs[11]);
+	offset("#define PT_R12    ", struct pt_regs, regs[12]);
+	offset("#define PT_R13    ", struct pt_regs, regs[13]);
+	offset("#define PT_R14    ", struct pt_regs, regs[14]);
+	offset("#define PT_R15    ", struct pt_regs, regs[15]);
+	offset("#define PT_R16    ", struct pt_regs, regs[16]);
+	offset("#define PT_R17    ", struct pt_regs, regs[17]);
+	offset("#define PT_R18    ", struct pt_regs, regs[18]);
+	offset("#define PT_R19    ", struct pt_regs, regs[19]);
+	offset("#define PT_R20    ", struct pt_regs, regs[20]);
+	offset("#define PT_R21    ", struct pt_regs, regs[21]);
+	offset("#define PT_R22    ", struct pt_regs, regs[22]);
+	offset("#define PT_R23    ", struct pt_regs, regs[23]);
+	offset("#define PT_R24    ", struct pt_regs, regs[24]);
+	offset("#define PT_R25    ", struct pt_regs, regs[25]);
+	offset("#define PT_R26    ", struct pt_regs, regs[26]);
+	offset("#define PT_R27    ", struct pt_regs, regs[27]);
+	offset("#define PT_R28    ", struct pt_regs, regs[28]);
+	offset("#define PT_R29    ", struct pt_regs, regs[29]);
+	offset("#define PT_R30    ", struct pt_regs, regs[30]);
+	offset("#define PT_R31    ", struct pt_regs, regs[31]);
+	offset("#define PT_LO     ", struct pt_regs, lo);
+	offset("#define PT_HI     ", struct pt_regs, hi);
+	offset("#define PT_EPC    ", struct pt_regs, cp0_epc);
+	offset("#define PT_BVADDR ", struct pt_regs, cp0_badvaddr);
+	offset("#define PT_STATUS ", struct pt_regs, cp0_status);
+	offset("#define PT_CAUSE  ", struct pt_regs, cp0_cause);
+	size("#define PT_SIZE   ", struct pt_regs);
+	linefeed;
+}
+
+void output_task_defines(void)
+{
+	text("/* MIPS task_struct offsets. */");
+	offset("#define TASK_STATE         ", struct task_struct, state);
+	offset("#define TASK_THREAD_INFO   ", struct task_struct, thread_info);
+	offset("#define TASK_FLAGS         ", struct task_struct, flags);
+	offset("#define TASK_MM            ", struct task_struct, mm);
+	offset("#define TASK_PID           ", struct task_struct, pid);
+	size(  "#define TASK_STRUCT_SIZE   ", struct task_struct);
+	linefeed;
+}
+
+void output_thread_info_defines(void)
+{
+	text("/* MIPS thread_info offsets. */");
+	offset("#define TI_TASK            ", struct thread_info, task);
+	offset("#define TI_EXEC_DOMAIN     ", struct thread_info, exec_domain);
+	offset("#define TI_FLAGS           ", struct thread_info, flags);
+	offset("#define TI_CPU             ", struct thread_info, cpu);
+	offset("#define TI_PRE_COUNT       ", struct thread_info, preempt_count);
+	offset("#define TI_ADDR_LIMIT      ", struct thread_info, addr_limit);
+	offset("#define TI_RESTART_BLOCK   ", struct thread_info, restart_block);
+	constant("#define _THREAD_SIZE_ORDER ", THREAD_SIZE_ORDER);
+	constant("#define _THREAD_SIZE       ", THREAD_SIZE);
+	constant("#define _THREAD_MASK       ", THREAD_MASK);
+	linefeed;
+}
+
+void output_thread_defines(void)
+{
+	text("/* MIPS specific thread_struct offsets. */");
+	offset("#define THREAD_REG16   ", struct task_struct, thread.reg16);
+	offset("#define THREAD_REG17   ", struct task_struct, thread.reg17);
+	offset("#define THREAD_REG18   ", struct task_struct, thread.reg18);
+	offset("#define THREAD_REG19   ", struct task_struct, thread.reg19);
+	offset("#define THREAD_REG20   ", struct task_struct, thread.reg20);
+	offset("#define THREAD_REG21   ", struct task_struct, thread.reg21);
+	offset("#define THREAD_REG22   ", struct task_struct, thread.reg22);
+	offset("#define THREAD_REG23   ", struct task_struct, thread.reg23);
+	offset("#define THREAD_REG29   ", struct task_struct, thread.reg29);
+	offset("#define THREAD_REG30   ", struct task_struct, thread.reg30);
+	offset("#define THREAD_REG31   ", struct task_struct, thread.reg31);
+	offset("#define THREAD_STATUS  ", struct task_struct,
+	       thread.cp0_status);
+	offset("#define THREAD_FPU     ", struct task_struct, thread.fpu);
+
+	offset("#define THREAD_BVADDR  ", struct task_struct, \
+	       thread.cp0_badvaddr);
+	offset("#define THREAD_BUADDR  ", struct task_struct, \
+	       thread.cp0_baduaddr);
+	offset("#define THREAD_ECODE   ", struct task_struct, \
+	       thread.error_code);
+	offset("#define THREAD_TRAPNO  ", struct task_struct, thread.trap_no);
+	offset("#define THREAD_MFLAGS  ", struct task_struct, thread.mflags);
+	offset("#define THREAD_TRAMP   ", struct task_struct, \
+	       thread.irix_trampoline);
+	offset("#define THREAD_OLDCTX  ", struct task_struct, \
+	       thread.irix_oldctx);
+	linefeed;
+}
+
+void output_thread_fpu_defines(void)
+{
+	offset("#define THREAD_FPR0    ",
+	       struct task_struct, thread.fpu.hard.fpr[0]);
+	offset("#define THREAD_FPR1    ",
+	       struct task_struct, thread.fpu.hard.fpr[1]);
+	offset("#define THREAD_FPR2    ",
+	       struct task_struct, thread.fpu.hard.fpr[2]);
+	offset("#define THREAD_FPR3    ",
+	       struct task_struct, thread.fpu.hard.fpr[3]);
+	offset("#define THREAD_FPR4    ",
+	       struct task_struct, thread.fpu.hard.fpr[4]);
+	offset("#define THREAD_FPR5    ",
+	       struct task_struct, thread.fpu.hard.fpr[5]);
+	offset("#define THREAD_FPR6    ",
+	       struct task_struct, thread.fpu.hard.fpr[6]);
+	offset("#define THREAD_FPR7    ",
+	       struct task_struct, thread.fpu.hard.fpr[7]);
+	offset("#define THREAD_FPR8    ",
+	       struct task_struct, thread.fpu.hard.fpr[8]);
+	offset("#define THREAD_FPR9    ",
+	       struct task_struct, thread.fpu.hard.fpr[9]);
+	offset("#define THREAD_FPR10   ",
+	       struct task_struct, thread.fpu.hard.fpr[10]);
+	offset("#define THREAD_FPR11   ",
+	       struct task_struct, thread.fpu.hard.fpr[11]);
+	offset("#define THREAD_FPR12   ",
+	       struct task_struct, thread.fpu.hard.fpr[12]);
+	offset("#define THREAD_FPR13   ",
+	       struct task_struct, thread.fpu.hard.fpr[13]);
+	offset("#define THREAD_FPR14   ",
+	       struct task_struct, thread.fpu.hard.fpr[14]);
+	offset("#define THREAD_FPR15   ",
+	       struct task_struct, thread.fpu.hard.fpr[15]);
+	offset("#define THREAD_FPR16   ",
+	       struct task_struct, thread.fpu.hard.fpr[16]);
+	offset("#define THREAD_FPR17   ",
+	       struct task_struct, thread.fpu.hard.fpr[17]);
+	offset("#define THREAD_FPR18   ",
+	       struct task_struct, thread.fpu.hard.fpr[18]);
+	offset("#define THREAD_FPR19   ",
+	       struct task_struct, thread.fpu.hard.fpr[19]);
+	offset("#define THREAD_FPR20   ",
+	       struct task_struct, thread.fpu.hard.fpr[20]);
+	offset("#define THREAD_FPR21   ",
+	       struct task_struct, thread.fpu.hard.fpr[21]);
+	offset("#define THREAD_FPR22   ",
+	       struct task_struct, thread.fpu.hard.fpr[22]);
+	offset("#define THREAD_FPR23   ",
+	       struct task_struct, thread.fpu.hard.fpr[23]);
+	offset("#define THREAD_FPR24   ",
+	       struct task_struct, thread.fpu.hard.fpr[24]);
+	offset("#define THREAD_FPR25   ",
+	       struct task_struct, thread.fpu.hard.fpr[25]);
+	offset("#define THREAD_FPR26   ",
+	       struct task_struct, thread.fpu.hard.fpr[26]);
+	offset("#define THREAD_FPR27   ",
+	       struct task_struct, thread.fpu.hard.fpr[27]);
+	offset("#define THREAD_FPR28   ",
+	       struct task_struct, thread.fpu.hard.fpr[28]);
+	offset("#define THREAD_FPR29   ",
+	       struct task_struct, thread.fpu.hard.fpr[29]);
+	offset("#define THREAD_FPR30   ",
+	       struct task_struct, thread.fpu.hard.fpr[30]);
+	offset("#define THREAD_FPR31   ",
+	       struct task_struct, thread.fpu.hard.fpr[31]);
+
+	offset("#define THREAD_FCR31   ",
+	       struct task_struct, thread.fpu.hard.fcr31);
+	linefeed;
+}
+
+void output_mm_defines(void)
+{
+	text("/* Size of struct page  */");
+	size("#define STRUCT_PAGE_SIZE   ", struct page);
+	linefeed;
+	text("/* Linux mm_struct offsets. */");
+	offset("#define MM_USERS      ", struct mm_struct, mm_users);
+	offset("#define MM_PGD        ", struct mm_struct, pgd);
+	offset("#define MM_CONTEXT    ", struct mm_struct, context);
+	linefeed;
+	constant("#define _PAGE_SIZE     ", PAGE_SIZE);
+	constant("#define _PAGE_SHIFT    ", PAGE_SHIFT);
+	linefeed;
+	constant("#define _PGD_T_SIZE    ", sizeof(pgd_t));
+	constant("#define _PMD_T_SIZE    ", sizeof(pmd_t));
+	constant("#define _PTE_T_SIZE    ", sizeof(pte_t));
+	linefeed;
+	constant("#define _PGD_T_LOG2    ", PGD_T_LOG2);
+	constant("#define _PMD_T_LOG2    ", PMD_T_LOG2);
+	constant("#define _PTE_T_LOG2    ", PTE_T_LOG2);
+	linefeed;
+	constant("#define _PMD_SHIFT     ", PMD_SHIFT);
+	constant("#define _PGDIR_SHIFT   ", PGDIR_SHIFT);
+	linefeed;
+	constant("#define _PGD_ORDER     ", PGD_ORDER);
+	constant("#define _PMD_ORDER     ", PMD_ORDER);
+	constant("#define _PTE_ORDER     ", PTE_ORDER);
+	linefeed;
+	constant("#define _PTRS_PER_PGD  ", PTRS_PER_PGD);
+	constant("#define _PTRS_PER_PMD  ", PTRS_PER_PMD);
+	constant("#define _PTRS_PER_PTE  ", PTRS_PER_PTE);
+	linefeed;
+}
+
+void output_sc_defines(void)
+{
+	text("/* Linux sigcontext offsets. */");
+	offset("#define SC_REGS       ", struct sigcontext, sc_regs);
+	offset("#define SC_FPREGS     ", struct sigcontext, sc_fpregs);
+	offset("#define SC_MDHI       ", struct sigcontext, sc_mdhi);
+	offset("#define SC_MDLO       ", struct sigcontext, sc_mdlo);
+	offset("#define SC_PC         ", struct sigcontext, sc_pc);
+	offset("#define SC_STATUS     ", struct sigcontext, sc_status);
+	offset("#define SC_FPC_CSR    ", struct sigcontext, sc_fpc_csr);
+	offset("#define SC_FPC_EIR    ", struct sigcontext, sc_fpc_eir);
+	offset("#define SC_CAUSE      ", struct sigcontext, sc_cause);
+	offset("#define SC_BADVADDR   ", struct sigcontext, sc_badvaddr);
+	linefeed;
+}
+
+#ifdef CONFIG_MIPS32_COMPAT
+void output_sc32_defines(void)
+{
+	text("/* Linux 32-bit sigcontext offsets. */");
+	offset("#define SC32_FPREGS     ", struct sigcontext32, sc_fpregs);
+	offset("#define SC32_FPC_CSR    ", struct sigcontext32, sc_fpc_csr);
+	offset("#define SC32_FPC_EIR    ", struct sigcontext32, sc_fpc_eir);
+	linefeed;
+}
+#endif
+
+void output_signal_defined(void)
+{
+	text("/* Linux signal numbers. */");
+	constant("#define _SIGHUP     ", SIGHUP);
+	constant("#define _SIGINT     ", SIGINT);
+	constant("#define _SIGQUIT    ", SIGQUIT);
+	constant("#define _SIGILL     ", SIGILL);
+	constant("#define _SIGTRAP    ", SIGTRAP);
+	constant("#define _SIGIOT     ", SIGIOT);
+	constant("#define _SIGABRT    ", SIGABRT);
+	constant("#define _SIGEMT     ", SIGEMT);
+	constant("#define _SIGFPE     ", SIGFPE);
+	constant("#define _SIGKILL    ", SIGKILL);
+	constant("#define _SIGBUS     ", SIGBUS);
+	constant("#define _SIGSEGV    ", SIGSEGV);
+	constant("#define _SIGSYS     ", SIGSYS);
+	constant("#define _SIGPIPE    ", SIGPIPE);
+	constant("#define _SIGALRM    ", SIGALRM);
+	constant("#define _SIGTERM    ", SIGTERM);
+	constant("#define _SIGUSR1    ", SIGUSR1);
+	constant("#define _SIGUSR2    ", SIGUSR2);
+	constant("#define _SIGCHLD    ", SIGCHLD);
+	constant("#define _SIGPWR     ", SIGPWR);
+	constant("#define _SIGWINCH   ", SIGWINCH);
+	constant("#define _SIGURG     ", SIGURG);
+	constant("#define _SIGIO      ", SIGIO);
+	constant("#define _SIGSTOP    ", SIGSTOP);
+	constant("#define _SIGTSTP    ", SIGTSTP);
+	constant("#define _SIGCONT    ", SIGCONT);
+	constant("#define _SIGTTIN    ", SIGTTIN);
+	constant("#define _SIGTTOU    ", SIGTTOU);
+	constant("#define _SIGVTALRM  ", SIGVTALRM);
+	constant("#define _SIGPROF    ", SIGPROF);
+	constant("#define _SIGXCPU    ", SIGXCPU);
+	constant("#define _SIGXFSZ    ", SIGXFSZ);
+	linefeed;
+}
+
+void output_irq_cpustat_t_defines(void)
+{
+	text("/* Linux irq_cpustat_t offsets. */");
+	offset("#define IC_SOFTIRQ_PENDING ", irq_cpustat_t, __softirq_pending);
+	size("#define IC_IRQ_CPUSTAT_T   ", irq_cpustat_t);
+	linefeed;
+}
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c
new file mode 100644
index 0000000..0f159f3
--- /dev/null
+++ b/arch/mips/kernel/proc.c
@@ -0,0 +1,149 @@
+/*
+ *  linux/arch/mips/kernel/proc.c
+ *
+ *  Copyright (C) 1995, 1996, 2001  Ralf Baechle
+ *  Copyright (C) 2001  MIPS Technologies, Inc.
+ */
+#include <linux/config.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/cpu-features.h>
+#include <asm/mipsregs.h>
+#include <asm/processor.h>
+#include <asm/watch.h>
+
+unsigned int vced_count, vcei_count;
+
+static const char *cpu_name[] = {
+	[CPU_UNKNOWN]	"unknown",
+	[CPU_R2000]	"R2000",
+	[CPU_R3000]	"R3000",
+	[CPU_R3000A]	"R3000A",
+	[CPU_R3041]	"R3041",
+	[CPU_R3051]	"R3051",
+	[CPU_R3052]	"R3052",
+	[CPU_R3081]	"R3081",
+	[CPU_R3081E]	"R3081E",
+	[CPU_R4000PC]	"R4000PC",
+	[CPU_R4000SC]	"R4000SC",
+	[CPU_R4000MC]	"R4000MC",
+        [CPU_R4200]	"R4200",
+	[CPU_R4400PC]	"R4400PC",
+	[CPU_R4400SC]	"R4400SC",
+	[CPU_R4400MC]	"R4400MC",
+	[CPU_R4600]	"R4600",
+	[CPU_R6000]	"R6000",
+        [CPU_R6000A]	"R6000A",
+	[CPU_R8000]	"R8000",
+	[CPU_R10000]	"R10000",
+	[CPU_R12000]	"R12000",
+	[CPU_R4300]	"R4300",
+	[CPU_R4650]	"R4650",
+	[CPU_R4700]	"R4700",
+	[CPU_R5000]	"R5000",
+        [CPU_R5000A]	"R5000A",
+	[CPU_R4640]	"R4640",
+	[CPU_NEVADA]	"Nevada",
+	[CPU_RM7000]	"RM7000",
+	[CPU_RM9000]	"RM9000",
+	[CPU_R5432]	"R5432",
+	[CPU_4KC]	"MIPS 4Kc",
+        [CPU_5KC]	"MIPS 5Kc",
+	[CPU_R4310]	"R4310",
+	[CPU_SB1]	"SiByte SB1",
+	[CPU_TX3912]	"TX3912",
+	[CPU_TX3922]	"TX3922",
+	[CPU_TX3927]	"TX3927",
+	[CPU_AU1000]	"Au1000",
+	[CPU_AU1500]	"Au1500",
+	[CPU_4KEC]	"MIPS 4KEc",
+	[CPU_4KSC]	"MIPS 4KSc",
+	[CPU_VR41XX]	"NEC Vr41xx",
+	[CPU_R5500]	"R5500",
+	[CPU_TX49XX]	"TX49xx",
+	[CPU_20KC]	"MIPS 20Kc",
+	[CPU_24K]	"MIPS 24K",
+	[CPU_25KF]	"MIPS 25Kf",
+	[CPU_VR4111]	"NEC VR4111",
+	[CPU_VR4121]	"NEC VR4121",
+	[CPU_VR4122]	"NEC VR4122",
+	[CPU_VR4131]	"NEC VR4131",
+	[CPU_VR4133]	"NEC VR4133",
+	[CPU_VR4181]	"NEC VR4181",
+	[CPU_VR4181A]	"NEC VR4181A",
+	[CPU_SR71000]	"Sandcraft SR71000"
+};
+
+
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+	unsigned int version = current_cpu_data.processor_id;
+	unsigned int fp_vers = current_cpu_data.fpu_id;
+	unsigned long n = (unsigned long) v - 1;
+	char fmt [64];
+
+#ifdef CONFIG_SMP
+	if (!cpu_isset(n, cpu_online_map))
+		return 0;
+#endif
+
+	/*
+	 * For the first processor also print the system type
+	 */
+	if (n == 0)
+		seq_printf(m, "system type\t\t: %s\n", get_system_type());
+
+	seq_printf(m, "processor\t\t: %ld\n", n);
+	sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n",
+	        cpu_has_fpu ? "  FPU V%d.%d" : "");
+	seq_printf(m, fmt, cpu_name[current_cpu_data.cputype <= CPU_LAST ?
+	                            current_cpu_data.cputype : CPU_UNKNOWN],
+	                           (version >> 4) & 0x0f, version & 0x0f,
+	                           (fp_vers >> 4) & 0x0f, fp_vers & 0x0f);
+	seq_printf(m, "BogoMIPS\t\t: %lu.%02lu\n",
+	              loops_per_jiffy / (500000/HZ),
+	              (loops_per_jiffy / (5000/HZ)) % 100);
+	seq_printf(m, "wait instruction\t: %s\n", cpu_wait ? "yes" : "no");
+	seq_printf(m, "microsecond timers\t: %s\n",
+	              cpu_has_counter ? "yes" : "no");
+	seq_printf(m, "tlb_entries\t\t: %d\n", current_cpu_data.tlbsize);
+	seq_printf(m, "extra interrupt vector\t: %s\n",
+	              cpu_has_divec ? "yes" : "no");
+	seq_printf(m, "hardware watchpoint\t: %s\n",
+	              cpu_has_watch ? "yes" : "no");
+
+	sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
+	        cpu_has_vce ? "%u" : "not available");
+	seq_printf(m, fmt, 'D', vced_count);
+	seq_printf(m, fmt, 'I', vcei_count);
+
+	return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+	unsigned long i = *pos;
+
+	return i < NR_CPUS ? (void *) (i + 1) : NULL;
+}
+
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	++*pos;
+	return c_start(m, pos);
+}
+
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+
+struct seq_operations cpuinfo_op = {
+	.start	= c_start,
+	.next	= c_next,
+	.stop	= c_stop,
+	.show	= show_cpuinfo,
+};
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
new file mode 100644
index 0000000..6e70c42
--- /dev/null
+++ b/arch/mips/kernel/process.c
@@ -0,0 +1,364 @@
+/*
+ * 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) 1994 - 1999, 2000 by Ralf Baechle and others.
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2004 Thiemo Seufer
+ */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/mman.h>
+#include <linux/personality.h>
+#include <linux/sys.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/init.h>
+#include <linux/completion.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/fpu.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/mipsregs.h>
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/elf.h>
+#include <asm/isadep.h>
+#include <asm/inst.h>
+
+/*
+ * We use this if we don't have any better idle routine..
+ * (This to kill: kernel/platform.c.
+ */
+void default_idle (void)
+{
+}
+
+/*
+ * The idle thread. There's no useful work to be done, so just try to conserve
+ * power and have a low exit latency (ie sit in a loop waiting for somebody to
+ * say that they'd like to reschedule)
+ */
+ATTRIB_NORET void cpu_idle(void)
+{
+	/* endless idle loop with no priority at all */
+	while (1) {
+		while (!need_resched())
+			if (cpu_wait)
+				(*cpu_wait)();
+		schedule();
+	}
+}
+
+asmlinkage void ret_from_fork(void);
+
+void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
+{
+	unsigned long status;
+
+	/* New thread loses kernel privileges. */
+	status = regs->cp0_status & ~(ST0_CU0|ST0_CU1|KU_MASK);
+#ifdef CONFIG_MIPS64
+	status &= ~ST0_FR;
+	status |= (current->thread.mflags & MF_32BIT_REGS) ? 0 : ST0_FR;
+#endif
+	status |= KU_USER;
+	regs->cp0_status = status;
+	clear_used_math();
+	lose_fpu();
+	regs->cp0_epc = pc;
+	regs->regs[29] = sp;
+	current_thread_info()->addr_limit = USER_DS;
+}
+
+void exit_thread(void)
+{
+}
+
+void flush_thread(void)
+{
+}
+
+int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+	unsigned long unused, struct task_struct *p, struct pt_regs *regs)
+{
+	struct thread_info *ti = p->thread_info;
+	struct pt_regs *childregs;
+	long childksp;
+
+	childksp = (unsigned long)ti + THREAD_SIZE - 32;
+
+	preempt_disable();
+
+	if (is_fpu_owner()) {
+		save_fp(p);
+	}
+
+	preempt_enable();
+
+	/* set up new TSS. */
+	childregs = (struct pt_regs *) childksp - 1;
+	*childregs = *regs;
+	childregs->regs[7] = 0;	/* Clear error flag */
+
+#if defined(CONFIG_BINFMT_IRIX)
+	if (current->personality != PER_LINUX) {
+		/* Under IRIX things are a little different. */
+		childregs->regs[3] = 1;
+		regs->regs[3] = 0;
+	}
+#endif
+	childregs->regs[2] = 0;	/* Child gets zero as return value */
+	regs->regs[2] = p->pid;
+
+	if (childregs->cp0_status & ST0_CU0) {
+		childregs->regs[28] = (unsigned long) ti;
+		childregs->regs[29] = childksp;
+		ti->addr_limit = KERNEL_DS;
+	} else {
+		childregs->regs[29] = usp;
+		ti->addr_limit = USER_DS;
+	}
+	p->thread.reg29 = (unsigned long) childregs;
+	p->thread.reg31 = (unsigned long) ret_from_fork;
+
+	/*
+	 * New tasks lose permission to use the fpu. This accelerates context
+	 * switching for most programs since they don't use the fpu.
+	 */
+	p->thread.cp0_status = read_c0_status() & ~(ST0_CU2|ST0_CU1);
+	childregs->cp0_status &= ~(ST0_CU2|ST0_CU1);
+	clear_tsk_thread_flag(p, TIF_USEDFPU);
+
+	return 0;
+}
+
+/* Fill in the fpu structure for a core dump.. */
+int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r)
+{
+	memcpy(r, &current->thread.fpu, sizeof(current->thread.fpu));
+
+	return 1;
+}
+
+void dump_regs(elf_greg_t *gp, struct pt_regs *regs)
+{
+	int i;
+
+	for (i = 0; i < EF_R0; i++)
+		gp[i] = 0;
+	gp[EF_R0] = 0;
+	for (i = 1; i <= 31; i++)
+		gp[EF_R0 + i] = regs->regs[i];
+	gp[EF_R26] = 0;
+	gp[EF_R27] = 0;
+	gp[EF_LO] = regs->lo;
+	gp[EF_HI] = regs->hi;
+	gp[EF_CP0_EPC] = regs->cp0_epc;
+	gp[EF_CP0_BADVADDR] = regs->cp0_badvaddr;
+	gp[EF_CP0_STATUS] = regs->cp0_status;
+	gp[EF_CP0_CAUSE] = regs->cp0_cause;
+#ifdef EF_UNUSED0
+	gp[EF_UNUSED0] = 0;
+#endif
+}
+
+int dump_task_fpu (struct task_struct *t, elf_fpregset_t *fpr)
+{
+	memcpy(fpr, &t->thread.fpu, sizeof(current->thread.fpu));
+
+	return 1;
+}
+
+/*
+ * Create a kernel thread
+ */
+ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *))
+{
+	do_exit(fn(arg));
+}
+
+long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
+{
+	struct pt_regs regs;
+
+	memset(&regs, 0, sizeof(regs));
+
+	regs.regs[4] = (unsigned long) arg;
+	regs.regs[5] = (unsigned long) fn;
+	regs.cp0_epc = (unsigned long) kernel_thread_helper;
+	regs.cp0_status = read_c0_status();
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+	regs.cp0_status &= ~(ST0_KUP | ST0_IEC);
+	regs.cp0_status |= ST0_IEP;
+#else
+	regs.cp0_status |= ST0_EXL;
+#endif
+
+	/* Ok, create the new process.. */
+	return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
+}
+
+struct mips_frame_info {
+	int frame_offset;
+	int pc_offset;
+};
+static struct mips_frame_info schedule_frame;
+static struct mips_frame_info schedule_timeout_frame;
+static struct mips_frame_info sleep_on_frame;
+static struct mips_frame_info sleep_on_timeout_frame;
+static struct mips_frame_info wait_for_completion_frame;
+static int mips_frame_info_initialized;
+static int __init get_frame_info(struct mips_frame_info *info, void *func)
+{
+	int i;
+	union mips_instruction *ip = (union mips_instruction *)func;
+	info->pc_offset = -1;
+	info->frame_offset = -1;
+	for (i = 0; i < 128; i++, ip++) {
+		/* if jal, jalr, jr, stop. */
+		if (ip->j_format.opcode == jal_op ||
+		    (ip->r_format.opcode == spec_op &&
+		     (ip->r_format.func == jalr_op ||
+		      ip->r_format.func == jr_op)))
+			break;
+
+		if (
+#ifdef CONFIG_MIPS32
+		    ip->i_format.opcode == sw_op &&
+#endif
+#ifdef CONFIG_MIPS64
+		    ip->i_format.opcode == sd_op &&
+#endif
+		    ip->i_format.rs == 29)
+		{
+			/* sw / sd $ra, offset($sp) */
+			if (ip->i_format.rt == 31) {
+				if (info->pc_offset != -1)
+					break;
+				info->pc_offset =
+					ip->i_format.simmediate / sizeof(long);
+			}
+			/* sw / sd $s8, offset($sp) */
+			if (ip->i_format.rt == 30) {
+				if (info->frame_offset != -1)
+					break;
+				info->frame_offset =
+					ip->i_format.simmediate / sizeof(long);
+			}
+		}
+	}
+	if (info->pc_offset == -1 || info->frame_offset == -1) {
+		printk("Can't analyze prologue code at %p\n", func);
+		info->pc_offset = -1;
+		info->frame_offset = -1;
+		return -1;
+	}
+
+	return 0;
+}
+
+static int __init frame_info_init(void)
+{
+	mips_frame_info_initialized =
+		!get_frame_info(&schedule_frame, schedule) &&
+		!get_frame_info(&schedule_timeout_frame, schedule_timeout) &&
+		!get_frame_info(&sleep_on_frame, sleep_on) &&
+		!get_frame_info(&sleep_on_timeout_frame, sleep_on_timeout) &&
+		!get_frame_info(&wait_for_completion_frame, wait_for_completion);
+
+	return 0;
+}
+
+arch_initcall(frame_info_init);
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+unsigned long thread_saved_pc(struct task_struct *tsk)
+{
+	struct thread_struct *t = &tsk->thread;
+
+	/* New born processes are a special case */
+	if (t->reg31 == (unsigned long) ret_from_fork)
+		return t->reg31;
+
+	if (schedule_frame.pc_offset < 0)
+		return 0;
+	return ((unsigned long *)t->reg29)[schedule_frame.pc_offset];
+}
+
+/* get_wchan - a maintenance nightmare^W^Wpain in the ass ...  */
+unsigned long get_wchan(struct task_struct *p)
+{
+	unsigned long frame, pc;
+
+	if (!p || p == current || p->state == TASK_RUNNING)
+		return 0;
+
+	if (!mips_frame_info_initialized)
+		return 0;
+	pc = thread_saved_pc(p);
+	if (!in_sched_functions(pc))
+		goto out;
+
+	if (pc >= (unsigned long) sleep_on_timeout)
+		goto schedule_timeout_caller;
+	if (pc >= (unsigned long) sleep_on)
+		goto schedule_caller;
+	if (pc >= (unsigned long) interruptible_sleep_on_timeout)
+		goto schedule_timeout_caller;
+	if (pc >= (unsigned long)interruptible_sleep_on)
+		goto schedule_caller;
+	if (pc >= (unsigned long)wait_for_completion)
+		goto schedule_caller;
+	goto schedule_timeout_caller;
+
+schedule_caller:
+	frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset];
+	if (pc >= (unsigned long) sleep_on)
+		pc = ((unsigned long *)frame)[sleep_on_frame.pc_offset];
+	else
+		pc = ((unsigned long *)frame)[wait_for_completion_frame.pc_offset];
+	goto out;
+
+schedule_timeout_caller:
+	/*
+	 * The schedule_timeout frame
+	 */
+	frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset];
+
+	/*
+	 * frame now points to sleep_on_timeout's frame
+	 */
+	pc    = ((unsigned long *)frame)[schedule_timeout_frame.pc_offset];
+
+	if (in_sched_functions(pc)) {
+		/* schedule_timeout called by [interruptible_]sleep_on_timeout */
+		frame = ((unsigned long *)frame)[schedule_timeout_frame.frame_offset];
+		pc    = ((unsigned long *)frame)[sleep_on_timeout_frame.pc_offset];
+	}
+
+out:
+
+#ifdef CONFIG_MIPS64
+	if (current->thread.mflags & MF_32BIT_REGS) /* Kludge for 32-bit ps  */
+		pc &= 0xffffffffUL;
+#endif
+
+	return pc;
+}
+
+EXPORT_SYMBOL(get_wchan);
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
new file mode 100644
index 0000000..a166954
--- /dev/null
+++ b/arch/mips/kernel/ptrace.c
@@ -0,0 +1,338 @@
+/*
+ * 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) 1992 Ross Biro
+ * Copyright (C) Linus Torvalds
+ * Copyright (C) 1994, 95, 96, 97, 98, 2000 Ralf Baechle
+ * Copyright (C) 1996 David S. Miller
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999 MIPS Technologies, Inc.
+ * Copyright (C) 2000 Ulf Carlsson
+ *
+ * At this time Linux/MIPS64 only supports syscall tracing, even for 32-bit
+ * binaries.
+ */
+#include <linux/config.h>
+#include <linux/compiler.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/audit.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/user.h>
+#include <linux/security.h>
+#include <linux/audit.h>
+
+#include <asm/cpu.h>
+#include <asm/fpu.h>
+#include <asm/mipsregs.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/bootinfo.h>
+
+/*
+ * Called by kernel/ptrace.c when detaching..
+ *
+ * Make sure single step bits etc are not set.
+ */
+void ptrace_disable(struct task_struct *child)
+{
+	/* Nothing to do.. */
+}
+
+asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+{
+	struct task_struct *child;
+	int ret;
+
+#if 0
+	printk("ptrace(r=%d,pid=%d,addr=%08lx,data=%08lx)\n",
+	       (int) request, (int) pid, (unsigned long) addr,
+	       (unsigned long) data);
+#endif
+	lock_kernel();
+	ret = -EPERM;
+	if (request == PTRACE_TRACEME) {
+		/* are we already being traced? */
+		if (current->ptrace & PT_PTRACED)
+			goto out;
+		if ((ret = security_ptrace(current->parent, current)))
+			goto out;
+		/* set the ptrace bit in the process flags. */
+		current->ptrace |= PT_PTRACED;
+		ret = 0;
+		goto out;
+	}
+	ret = -ESRCH;
+	read_lock(&tasklist_lock);
+	child = find_task_by_pid(pid);
+	if (child)
+		get_task_struct(child);
+	read_unlock(&tasklist_lock);
+	if (!child)
+		goto out;
+
+	ret = -EPERM;
+	if (pid == 1)		/* you may not mess with init */
+		goto out_tsk;
+
+	if (request == PTRACE_ATTACH) {
+		ret = ptrace_attach(child);
+		goto out_tsk;
+	}
+
+	ret = ptrace_check_attach(child, request == PTRACE_KILL);
+	if (ret < 0)
+		goto out_tsk;
+
+	switch (request) {
+	/* when I and D space are separate, these will need to be fixed. */
+	case PTRACE_PEEKTEXT: /* read word at location addr. */
+	case PTRACE_PEEKDATA: {
+		unsigned long tmp;
+		int copied;
+
+		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+		ret = -EIO;
+		if (copied != sizeof(tmp))
+			break;
+		ret = put_user(tmp,(unsigned long *) data);
+		break;
+	}
+
+	/* Read the word at location addr in the USER area. */
+	case PTRACE_PEEKUSR: {
+		struct pt_regs *regs;
+		unsigned long tmp = 0;
+
+		regs = (struct pt_regs *) ((unsigned long) child->thread_info +
+		       THREAD_SIZE - 32 - sizeof(struct pt_regs));
+		ret = 0;  /* Default return value. */
+
+		switch (addr) {
+		case 0 ... 31:
+			tmp = regs->regs[addr];
+			break;
+		case FPR_BASE ... FPR_BASE + 31:
+			if (tsk_used_math(child)) {
+				fpureg_t *fregs = get_fpu_regs(child);
+
+#ifdef CONFIG_MIPS32
+				/*
+				 * The odd registers are actually the high
+				 * order bits of the values stored in the even
+				 * registers - unless we're using r2k_switch.S.
+				 */
+				if (addr & 1)
+					tmp = (unsigned long) (fregs[((addr & ~1) - 32)] >> 32);
+				else
+					tmp = (unsigned long) (fregs[(addr - 32)] & 0xffffffff);
+#endif
+#ifdef CONFIG_MIPS64
+				tmp = fregs[addr - FPR_BASE];
+#endif
+			} else {
+				tmp = -1;	/* FP not yet used  */
+			}
+			break;
+		case PC:
+			tmp = regs->cp0_epc;
+			break;
+		case CAUSE:
+			tmp = regs->cp0_cause;
+			break;
+		case BADVADDR:
+			tmp = regs->cp0_badvaddr;
+			break;
+		case MMHI:
+			tmp = regs->hi;
+			break;
+		case MMLO:
+			tmp = regs->lo;
+			break;
+		case FPC_CSR:
+			if (cpu_has_fpu)
+				tmp = child->thread.fpu.hard.fcr31;
+			else
+				tmp = child->thread.fpu.soft.fcr31;
+			break;
+		case FPC_EIR: {	/* implementation / version register */
+			unsigned int flags;
+
+			if (!cpu_has_fpu)
+				break;
+
+			flags = read_c0_status();
+			__enable_fpu();
+			__asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
+			write_c0_status(flags);
+			break;
+		}
+		default:
+			tmp = 0;
+			ret = -EIO;
+			goto out_tsk;
+		}
+		ret = put_user(tmp, (unsigned long *) data);
+		break;
+	}
+
+	/* when I and D space are separate, this will have to be fixed. */
+	case PTRACE_POKETEXT: /* write the word at location addr. */
+	case PTRACE_POKEDATA:
+		ret = 0;
+		if (access_process_vm(child, addr, &data, sizeof(data), 1)
+		    == sizeof(data))
+			break;
+		ret = -EIO;
+		break;
+
+	case PTRACE_POKEUSR: {
+		struct pt_regs *regs;
+		ret = 0;
+		regs = (struct pt_regs *) ((unsigned long) child->thread_info +
+		       THREAD_SIZE - 32 - sizeof(struct pt_regs));
+
+		switch (addr) {
+		case 0 ... 31:
+			regs->regs[addr] = data;
+			break;
+		case FPR_BASE ... FPR_BASE + 31: {
+			fpureg_t *fregs = get_fpu_regs(child);
+
+			if (!tsk_used_math(child)) {
+				/* FP not yet used  */
+				memset(&child->thread.fpu.hard, ~0,
+				       sizeof(child->thread.fpu.hard));
+				child->thread.fpu.hard.fcr31 = 0;
+			}
+#ifdef CONFIG_MIPS32
+			/*
+			 * The odd registers are actually the high order bits
+			 * of the values stored in the even registers - unless
+			 * we're using r2k_switch.S.
+			 */
+			if (addr & 1) {
+				fregs[(addr & ~1) - FPR_BASE] &= 0xffffffff;
+				fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long long) data) << 32;
+			} else {
+				fregs[addr - FPR_BASE] &= ~0xffffffffLL;
+				fregs[addr - FPR_BASE] |= data;
+			}
+#endif
+#ifdef CONFIG_MIPS64
+			fregs[addr - FPR_BASE] = data;
+#endif
+			break;
+		}
+		case PC:
+			regs->cp0_epc = data;
+			break;
+		case MMHI:
+			regs->hi = data;
+			break;
+		case MMLO:
+			regs->lo = data;
+			break;
+		case FPC_CSR:
+			if (cpu_has_fpu)
+				child->thread.fpu.hard.fcr31 = data;
+			else
+				child->thread.fpu.soft.fcr31 = data;
+			break;
+		default:
+			/* The rest are not allowed. */
+			ret = -EIO;
+			break;
+		}
+		break;
+		}
+
+	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
+	case PTRACE_CONT: { /* restart after signal. */
+		ret = -EIO;
+		if ((unsigned long) data > _NSIG)
+			break;
+		if (request == PTRACE_SYSCALL) {
+			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+		}
+		else {
+			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+		}
+		child->exit_code = data;
+		wake_up_process(child);
+		ret = 0;
+		break;
+	}
+
+	/*
+	 * make the child exit.  Best I can do is send it a sigkill.
+	 * perhaps it should be put in the status that it wants to
+	 * exit.
+	 */
+	case PTRACE_KILL:
+		ret = 0;
+		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
+			break;
+		child->exit_code = SIGKILL;
+		wake_up_process(child);
+		break;
+
+	case PTRACE_DETACH: /* detach a process that was attached. */
+		ret = ptrace_detach(child, data);
+		break;
+
+	default:
+		ret = ptrace_request(child, request, addr, data);
+		break;
+	}
+
+out_tsk:
+	put_task_struct(child);
+out:
+	unlock_kernel();
+	return ret;
+}
+
+/*
+ * Notification of system call entry/exit
+ * - triggered by current->work.syscall_trace
+ */
+asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
+{
+	if (unlikely(current->audit_context)) {
+		if (!entryexit)
+			audit_syscall_entry(current, regs->regs[2],
+			                    regs->regs[4], regs->regs[5],
+			                    regs->regs[6], regs->regs[7]);
+		else
+			audit_syscall_exit(current, regs->regs[2]);
+	}
+
+	if (!test_thread_flag(TIF_SYSCALL_TRACE))
+		return;
+	if (!(current->ptrace & PT_PTRACED))
+		return;
+
+	/* The 0x80 provides a way for the tracing parent to distinguish
+	   between a syscall stop and SIGTRAP delivery */
+	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ?
+	                         0x80 : 0));
+
+	/*
+	 * this isn't the same as continuing with a signal, but it will do
+	 * for normal use.  strace only continues with a signal if the
+	 * stopping signal is not SIGTRAP.  -brl
+	 */
+	if (current->exit_code) {
+		send_sig(current->exit_code, current, 1);
+		current->exit_code = 0;
+	}
+}
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c
new file mode 100644
index 0000000..611dee9
--- /dev/null
+++ b/arch/mips/kernel/ptrace32.c
@@ -0,0 +1,285 @@
+/*
+ * 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) 1992 Ross Biro
+ * Copyright (C) Linus Torvalds
+ * Copyright (C) 1994, 95, 96, 97, 98, 2000 Ralf Baechle
+ * Copyright (C) 1996 David S. Miller
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999 MIPS Technologies, Inc.
+ * Copyright (C) 2000 Ulf Carlsson
+ *
+ * At this time Linux/MIPS64 only supports syscall tracing, even for 32-bit
+ * binaries.
+ */
+#include <linux/compiler.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/user.h>
+#include <linux/security.h>
+
+#include <asm/cpu.h>
+#include <asm/fpu.h>
+#include <asm/mipsregs.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/bootinfo.h>
+
+/*
+ * Tracing a 32-bit process with a 64-bit strace and vice versa will not
+ * work.  I don't know how to fix this.
+ */
+asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
+{
+	struct task_struct *child;
+	int ret;
+
+#if 0
+	printk("ptrace(r=%d,pid=%d,addr=%08lx,data=%08lx)\n",
+	       (int) request, (int) pid, (unsigned long) addr,
+	       (unsigned long) data);
+#endif
+	lock_kernel();
+	ret = -EPERM;
+	if (request == PTRACE_TRACEME) {
+		/* are we already being traced? */
+		if (current->ptrace & PT_PTRACED)
+			goto out;
+		if ((ret = security_ptrace(current->parent, current)))
+			goto out;
+		/* set the ptrace bit in the process flags. */
+		current->ptrace |= PT_PTRACED;
+		ret = 0;
+		goto out;
+	}
+	ret = -ESRCH;
+	read_lock(&tasklist_lock);
+	child = find_task_by_pid(pid);
+	if (child)
+		get_task_struct(child);
+	read_unlock(&tasklist_lock);
+	if (!child)
+		goto out;
+
+	ret = -EPERM;
+	if (pid == 1)		/* you may not mess with init */
+		goto out_tsk;
+
+	if (request == PTRACE_ATTACH) {
+		ret = ptrace_attach(child);
+		goto out_tsk;
+	}
+
+	ret = ptrace_check_attach(child, request == PTRACE_KILL);
+	if (ret < 0)
+		goto out_tsk;
+
+	switch (request) {
+	/* when I and D space are separate, these will need to be fixed. */
+	case PTRACE_PEEKTEXT: /* read word at location addr. */
+	case PTRACE_PEEKDATA: {
+		unsigned int tmp;
+		int copied;
+
+		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+		ret = -EIO;
+		if (copied != sizeof(tmp))
+			break;
+		ret = put_user(tmp, (unsigned int *) (unsigned long) data);
+		break;
+	}
+
+	/* Read the word at location addr in the USER area. */
+	case PTRACE_PEEKUSR: {
+		struct pt_regs *regs;
+		unsigned int tmp;
+
+		regs = (struct pt_regs *) ((unsigned long) child->thread_info +
+		       THREAD_SIZE - 32 - sizeof(struct pt_regs));
+		ret = 0;  /* Default return value. */
+
+		switch (addr) {
+		case 0 ... 31:
+			tmp = regs->regs[addr];
+			break;
+		case FPR_BASE ... FPR_BASE + 31:
+			if (tsk_used_math(child)) {
+				fpureg_t *fregs = get_fpu_regs(child);
+
+				/*
+				 * The odd registers are actually the high
+				 * order bits of the values stored in the even
+				 * registers - unless we're using r2k_switch.S.
+				 */
+				if (addr & 1)
+					tmp = (unsigned long) (fregs[((addr & ~1) - 32)] >> 32);
+				else
+					tmp = (unsigned long) (fregs[(addr - 32)] & 0xffffffff);
+			} else {
+				tmp = -1;	/* FP not yet used  */
+			}
+			break;
+		case PC:
+			tmp = regs->cp0_epc;
+			break;
+		case CAUSE:
+			tmp = regs->cp0_cause;
+			break;
+		case BADVADDR:
+			tmp = regs->cp0_badvaddr;
+			break;
+		case MMHI:
+			tmp = regs->hi;
+			break;
+		case MMLO:
+			tmp = regs->lo;
+			break;
+		case FPC_CSR:
+			if (cpu_has_fpu)
+				tmp = child->thread.fpu.hard.fcr31;
+			else
+				tmp = child->thread.fpu.soft.fcr31;
+			break;
+		case FPC_EIR: {	/* implementation / version register */
+			unsigned int flags;
+
+			if (!cpu_has_fpu)
+				break;
+
+			flags = read_c0_status();
+			__enable_fpu();
+			__asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
+			write_c0_status(flags);
+			break;
+		}
+		default:
+			tmp = 0;
+			ret = -EIO;
+			goto out_tsk;
+		}
+		ret = put_user(tmp, (unsigned *) (unsigned long) data);
+		break;
+	}
+
+	/* when I and D space are separate, this will have to be fixed. */
+	case PTRACE_POKETEXT: /* write the word at location addr. */
+	case PTRACE_POKEDATA:
+		ret = 0;
+		if (access_process_vm(child, addr, &data, sizeof(data), 1)
+		    == sizeof(data))
+			break;
+		ret = -EIO;
+		break;
+
+	case PTRACE_POKEUSR: {
+		struct pt_regs *regs;
+		ret = 0;
+		regs = (struct pt_regs *) ((unsigned long) child->thread_info +
+		       THREAD_SIZE - 32 - sizeof(struct pt_regs));
+
+		switch (addr) {
+		case 0 ... 31:
+			regs->regs[addr] = data;
+			break;
+		case FPR_BASE ... FPR_BASE + 31: {
+			fpureg_t *fregs = get_fpu_regs(child);
+
+			if (!tsk_used_math(child)) {
+				/* FP not yet used  */
+				memset(&child->thread.fpu.hard, ~0,
+				       sizeof(child->thread.fpu.hard));
+				child->thread.fpu.hard.fcr31 = 0;
+			}
+			/*
+			 * The odd registers are actually the high order bits
+			 * of the values stored in the even registers - unless
+			 * we're using r2k_switch.S.
+			 */
+			if (addr & 1) {
+				fregs[(addr & ~1) - FPR_BASE] &= 0xffffffff;
+				fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long long) data) << 32;
+			} else {
+				fregs[addr - FPR_BASE] &= ~0xffffffffLL;
+				/* Must cast, lest sign extension fill upper
+				   bits!  */
+				fregs[addr - FPR_BASE] |= (unsigned int)data;
+			}
+			break;
+		}
+		case PC:
+			regs->cp0_epc = data;
+			break;
+		case MMHI:
+			regs->hi = data;
+			break;
+		case MMLO:
+			regs->lo = data;
+			break;
+		case FPC_CSR:
+			if (cpu_has_fpu)
+				child->thread.fpu.hard.fcr31 = data;
+			else
+				child->thread.fpu.soft.fcr31 = data;
+			break;
+		default:
+			/* The rest are not allowed. */
+			ret = -EIO;
+			break;
+		}
+		break;
+		}
+
+	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
+	case PTRACE_CONT: { /* restart after signal. */
+		ret = -EIO;
+		if ((unsigned int) data > _NSIG)
+			break;
+		if (request == PTRACE_SYSCALL) {
+			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+		}
+		else {
+			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+		}
+		child->exit_code = data;
+		wake_up_process(child);
+		ret = 0;
+		break;
+	}
+
+	/*
+	 * make the child exit.  Best I can do is send it a sigkill.
+	 * perhaps it should be put in the status that it wants to
+	 * exit.
+	 */
+	case PTRACE_KILL:
+		ret = 0;
+		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
+			break;
+		child->exit_code = SIGKILL;
+		wake_up_process(child);
+		break;
+
+	case PTRACE_DETACH: /* detach a process that was attached. */
+		ret = ptrace_detach(child, data);
+		break;
+
+	default:
+		ret = ptrace_request(child, request, addr, data);
+		break;
+	}
+
+out_tsk:
+	put_task_struct(child);
+out:
+	unlock_kernel();
+	return ret;
+}
diff --git a/arch/mips/kernel/r2300_fpu.S b/arch/mips/kernel/r2300_fpu.S
new file mode 100644
index 0000000..f83c31f
--- /dev/null
+++ b/arch/mips/kernel/r2300_fpu.S
@@ -0,0 +1,126 @@
+/*
+ * 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) 1996, 1998 by Ralf Baechle
+ *
+ * Multi-arch abstraction and asm macros for easier reading:
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ *
+ * Further modifications to make this work:
+ * Copyright (c) 1998 Harald Koerfgen
+ */
+#include <asm/asm.h>
+#include <asm/errno.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/offset.h>
+#include <asm/regdef.h>
+
+#define EX(a,b)							\
+9:	a,##b;							\
+	.section __ex_table,"a";				\
+	PTR	9b,bad_stack;					\
+	.previous
+
+	.set	noreorder
+	.set	mips1
+	/* Save floating point context */
+LEAF(_save_fp_context)
+	li	v0, 0					# assume success
+	cfc1	t1,fcr31
+	EX(swc1	$f0,(SC_FPREGS+0)(a0))
+	EX(swc1	$f1,(SC_FPREGS+8)(a0))
+	EX(swc1	$f2,(SC_FPREGS+16)(a0))
+	EX(swc1	$f3,(SC_FPREGS+24)(a0))
+	EX(swc1	$f4,(SC_FPREGS+32)(a0))
+	EX(swc1	$f5,(SC_FPREGS+40)(a0))
+	EX(swc1	$f6,(SC_FPREGS+48)(a0))
+	EX(swc1	$f7,(SC_FPREGS+56)(a0))
+	EX(swc1	$f8,(SC_FPREGS+64)(a0))
+	EX(swc1	$f9,(SC_FPREGS+72)(a0))
+	EX(swc1	$f10,(SC_FPREGS+80)(a0))
+	EX(swc1	$f11,(SC_FPREGS+88)(a0))
+	EX(swc1	$f12,(SC_FPREGS+96)(a0))
+	EX(swc1	$f13,(SC_FPREGS+104)(a0))
+	EX(swc1	$f14,(SC_FPREGS+112)(a0))
+	EX(swc1	$f15,(SC_FPREGS+120)(a0))
+	EX(swc1	$f16,(SC_FPREGS+128)(a0))
+	EX(swc1	$f17,(SC_FPREGS+136)(a0))
+	EX(swc1	$f18,(SC_FPREGS+144)(a0))
+	EX(swc1	$f19,(SC_FPREGS+152)(a0))
+	EX(swc1	$f20,(SC_FPREGS+160)(a0))
+	EX(swc1	$f21,(SC_FPREGS+168)(a0))
+	EX(swc1	$f22,(SC_FPREGS+176)(a0))
+	EX(swc1	$f23,(SC_FPREGS+184)(a0))
+	EX(swc1	$f24,(SC_FPREGS+192)(a0))
+	EX(swc1	$f25,(SC_FPREGS+200)(a0))
+	EX(swc1	$f26,(SC_FPREGS+208)(a0))
+	EX(swc1	$f27,(SC_FPREGS+216)(a0))
+	EX(swc1	$f28,(SC_FPREGS+224)(a0))
+	EX(swc1	$f29,(SC_FPREGS+232)(a0))
+	EX(swc1	$f30,(SC_FPREGS+240)(a0))
+	EX(swc1	$f31,(SC_FPREGS+248)(a0))
+	EX(sw	t1,(SC_FPC_CSR)(a0))
+	cfc1	t0,$0				# implementation/version
+	jr	ra
+	.set	nomacro
+	 EX(sw	t0,(SC_FPC_EIR)(a0))
+	.set	macro
+	END(_save_fp_context)
+
+/*
+ * Restore FPU state:
+ *  - fp gp registers
+ *  - cp1 status/control register
+ *
+ * We base the decision which registers to restore from the signal stack
+ * frame on the current content of c0_status, not on the content of the
+ * stack frame which might have been changed by the user.
+ */
+LEAF(_restore_fp_context)
+	li	v0, 0					# assume success
+	EX(lw t0,(SC_FPC_CSR)(a0))
+	EX(lwc1	$f0,(SC_FPREGS+0)(a0))
+	EX(lwc1	$f1,(SC_FPREGS+8)(a0))
+	EX(lwc1	$f2,(SC_FPREGS+16)(a0))
+	EX(lwc1	$f3,(SC_FPREGS+24)(a0))
+	EX(lwc1	$f4,(SC_FPREGS+32)(a0))
+	EX(lwc1	$f5,(SC_FPREGS+40)(a0))
+	EX(lwc1	$f6,(SC_FPREGS+48)(a0))
+	EX(lwc1	$f7,(SC_FPREGS+56)(a0))
+	EX(lwc1	$f8,(SC_FPREGS+64)(a0))
+	EX(lwc1	$f9,(SC_FPREGS+72)(a0))
+	EX(lwc1	$f10,(SC_FPREGS+80)(a0))
+	EX(lwc1	$f11,(SC_FPREGS+88)(a0))
+	EX(lwc1	$f12,(SC_FPREGS+96)(a0))
+	EX(lwc1	$f13,(SC_FPREGS+104)(a0))
+	EX(lwc1	$f14,(SC_FPREGS+112)(a0))
+	EX(lwc1	$f15,(SC_FPREGS+120)(a0))
+	EX(lwc1	$f16,(SC_FPREGS+128)(a0))
+	EX(lwc1	$f17,(SC_FPREGS+136)(a0))
+	EX(lwc1	$f18,(SC_FPREGS+144)(a0))
+	EX(lwc1	$f19,(SC_FPREGS+152)(a0))
+	EX(lwc1	$f20,(SC_FPREGS+160)(a0))
+	EX(lwc1	$f21,(SC_FPREGS+168)(a0))
+	EX(lwc1	$f22,(SC_FPREGS+176)(a0))
+	EX(lwc1	$f23,(SC_FPREGS+184)(a0))
+	EX(lwc1	$f24,(SC_FPREGS+192)(a0))
+	EX(lwc1	$f25,(SC_FPREGS+200)(a0))
+	EX(lwc1	$f26,(SC_FPREGS+208)(a0))
+	EX(lwc1	$f27,(SC_FPREGS+216)(a0))
+	EX(lwc1	$f28,(SC_FPREGS+224)(a0))
+	EX(lwc1	$f29,(SC_FPREGS+232)(a0))
+	EX(lwc1	$f30,(SC_FPREGS+240)(a0))
+	EX(lwc1	$f31,(SC_FPREGS+248)(a0))
+	jr	ra
+	 ctc1	t0,fcr31
+	END(_restore_fp_context)
+	.set	reorder
+
+	.type	fault@function
+	.ent	fault
+fault:	li	v0, -EFAULT
+	jr	ra
+	.end	fault
diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S
new file mode 100644
index 0000000..243e7b6
--- /dev/null
+++ b/arch/mips/kernel/r2300_switch.S
@@ -0,0 +1,174 @@
+/*
+ * r2300_switch.S: R2300 specific task switching code.
+ *
+ * Copyright (C) 1994, 1995, 1996, 1999 by Ralf Baechle
+ * Copyright (C) 1994, 1995, 1996 by Andreas Busse
+ *
+ * Multi-cpu abstraction and macros for easier reading:
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ *
+ * Further modifications to make this work:
+ * Copyright (c) 1998-2000 Harald Koerfgen
+ */
+#include <linux/config.h>
+#include <asm/asm.h>
+#include <asm/cachectl.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/offset.h>
+#include <asm/page.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/thread_info.h>
+
+#include <asm/asmmacro.h>
+
+	.set	mips1
+	.align	5
+
+/*
+ * Offset to the current process status flags, the first 32 bytes of the
+ * stack are not used.
+ */
+#define ST_OFF (_THREAD_SIZE - 32 - PT_SIZE + PT_STATUS)
+
+/*
+ * FPU context is saved iff the process has used it's FPU in the current
+ * time slice as indicated by TIF_USEDFPU.  In any case, the CU1 bit for user
+ * space STATUS register should be 0, so that a process *always* starts its 
+ * userland with FPU disabled after each context switch.
+ *
+ * FPU will be enabled as soon as the process accesses FPU again, through
+ * do_cpu() trap.
+ */
+
+/*
+ * task_struct *resume(task_struct *prev, task_struct *next,
+ *                     struct thread_info *next_ti) )
+ */
+LEAF(resume)
+#ifndef CONFIG_CPU_HAS_LLSC
+	sw      zero, ll_bit
+#endif
+	mfc0	t1, CP0_STATUS
+	sw	t1, THREAD_STATUS(a0)
+	cpu_save_nonscratch a0
+	sw	ra, THREAD_REG31(a0)
+
+	/* 
+	 * check if we need to save FPU registers
+	 */
+	lw	t3, TASK_THREAD_INFO(a0)
+	lw	t0, TI_FLAGS(t3)
+	li	t1, _TIF_USEDFPU
+	and	t2, t0, t1
+	beqz	t2, 1f
+	nor	t1, zero, t1
+
+	and	t0, t0, t1
+	sw	t0, TI_FLAGS(t3)
+
+	/*
+	 * clear saved user stack CU1 bit
+	 */
+	lw	t0, ST_OFF(t3)
+	li	t1, ~ST0_CU1
+	and	t0, t0, t1
+	sw	t0, ST_OFF(t3)
+
+	fpu_save_single a0, t0			# clobbers t0
+
+1:
+	/*
+	 * The order of restoring the registers takes care of the race
+	 * updating $28, $29 and kernelsp without disabling ints.
+	 */
+	move	$28, a2
+	cpu_restore_nonscratch a1
+
+	addiu	t1, $28, _THREAD_SIZE - 32
+	sw	t1, kernelsp
+
+	mfc0	t1, CP0_STATUS		/* Do we really need this? */
+	li	a3, 0xff01
+	and	t1, a3
+	lw	a2, THREAD_STATUS(a1)
+	nor	a3, $0, a3
+	and	a2, a3
+	or	a2, t1
+	mtc0	a2, CP0_STATUS
+	move	v0, a0
+	jr	ra
+	END(resume)
+
+/*
+ * Save a thread's fp context.
+ */
+LEAF(_save_fp)
+	fpu_save_single a0, t1			# clobbers t1
+	jr	ra
+	END(_save_fp)
+
+/*
+ * Restore a thread's fp context.
+ */
+LEAF(_restore_fp)
+	fpu_restore_single a0, t1		# clobbers t1
+	jr	ra
+	END(_restore_fp)
+
+/*
+ * Load the FPU with signalling NANS.  This bit pattern we're using has
+ * the property that no matter whether considered as single or as double
+ * precision represents signaling NANS.
+ *
+ * We initialize fcr31 to rounding to nearest, no exceptions.
+ */
+
+#define FPU_DEFAULT  0x00000000
+
+LEAF(_init_fpu)
+	mfc0	t0, CP0_STATUS
+	li	t1, ST0_CU1
+	or	t0, t1
+	mtc0	t0, CP0_STATUS
+
+	li	t1, FPU_DEFAULT
+	ctc1	t1, fcr31
+
+	li	t0, -1
+
+	mtc1	t0, $f0
+	mtc1	t0, $f1
+	mtc1	t0, $f2
+	mtc1	t0, $f3
+	mtc1	t0, $f4
+	mtc1	t0, $f5
+	mtc1	t0, $f6
+	mtc1	t0, $f7
+	mtc1	t0, $f8
+	mtc1	t0, $f9
+	mtc1	t0, $f10
+	mtc1	t0, $f11
+	mtc1	t0, $f12
+	mtc1	t0, $f13
+	mtc1	t0, $f14
+	mtc1	t0, $f15
+	mtc1	t0, $f16
+	mtc1	t0, $f17
+	mtc1	t0, $f18
+	mtc1	t0, $f19
+	mtc1	t0, $f20
+	mtc1	t0, $f21
+	mtc1	t0, $f22
+	mtc1	t0, $f23
+	mtc1	t0, $f24
+	mtc1	t0, $f25
+	mtc1	t0, $f26
+	mtc1	t0, $f27
+	mtc1	t0, $f28
+	mtc1	t0, $f29
+	mtc1	t0, $f30
+	mtc1	t0, $f31
+	jr	ra
+	END(_init_fpu)
diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S
new file mode 100644
index 0000000..ebb643d
--- /dev/null
+++ b/arch/mips/kernel/r4k_fpu.S
@@ -0,0 +1,191 @@
+/*
+ * 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) 1996, 98, 99, 2000, 01 Ralf Baechle
+ *
+ * Multi-arch abstraction and asm macros for easier reading:
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.
+ * Copyright (C) 1999, 2001 Silicon Graphics, Inc.
+ */
+#include <linux/config.h>
+#include <asm/asm.h>
+#include <asm/errno.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/offset.h>
+#include <asm/regdef.h>
+
+	.macro	EX insn, reg, src
+	.set	push
+	.set	nomacro
+.ex\@:	\insn	\reg, \src
+	.set	pop
+	.section __ex_table,"a"
+	PTR	.ex\@, fault
+	.previous
+	.endm
+
+	.set	noreorder
+	.set	mips3
+	/* Save floating point context */
+LEAF(_save_fp_context)
+	cfc1	t1, fcr31
+
+#ifdef CONFIG_MIPS64
+	/* Store the 16 odd double precision registers */
+	EX	sdc1 $f1, SC_FPREGS+8(a0)
+	EX	sdc1 $f3, SC_FPREGS+24(a0)
+	EX	sdc1 $f5, SC_FPREGS+40(a0)
+	EX	sdc1 $f7, SC_FPREGS+56(a0)
+	EX	sdc1 $f9, SC_FPREGS+72(a0)
+	EX	sdc1 $f11, SC_FPREGS+88(a0)
+	EX	sdc1 $f13, SC_FPREGS+104(a0)
+	EX	sdc1 $f15, SC_FPREGS+120(a0)
+	EX	sdc1 $f17, SC_FPREGS+136(a0)
+	EX	sdc1 $f19, SC_FPREGS+152(a0)
+	EX	sdc1 $f21, SC_FPREGS+168(a0)
+	EX	sdc1 $f23, SC_FPREGS+184(a0)
+	EX	sdc1 $f25, SC_FPREGS+200(a0)
+	EX	sdc1 $f27, SC_FPREGS+216(a0)
+	EX	sdc1 $f29, SC_FPREGS+232(a0)
+	EX	sdc1 $f31, SC_FPREGS+248(a0)
+#endif
+
+	/* Store the 16 even double precision registers */
+	EX	sdc1 $f0, SC_FPREGS+0(a0)
+	EX	sdc1 $f2, SC_FPREGS+16(a0)
+	EX	sdc1 $f4, SC_FPREGS+32(a0)
+	EX	sdc1 $f6, SC_FPREGS+48(a0)
+	EX	sdc1 $f8, SC_FPREGS+64(a0)
+	EX	sdc1 $f10, SC_FPREGS+80(a0)
+	EX	sdc1 $f12, SC_FPREGS+96(a0)
+	EX	sdc1 $f14, SC_FPREGS+112(a0)
+	EX	sdc1 $f16, SC_FPREGS+128(a0)
+	EX	sdc1 $f18, SC_FPREGS+144(a0)
+	EX	sdc1 $f20, SC_FPREGS+160(a0)
+	EX	sdc1 $f22, SC_FPREGS+176(a0)
+	EX	sdc1 $f24, SC_FPREGS+192(a0)
+	EX	sdc1 $f26, SC_FPREGS+208(a0)
+	EX	sdc1 $f28, SC_FPREGS+224(a0)
+	EX	sdc1 $f30, SC_FPREGS+240(a0)
+	EX	sw t1, SC_FPC_CSR(a0)
+	cfc1	t0, $0				# implementation/version
+	EX	sw t0, SC_FPC_EIR(a0)
+
+	jr	ra
+	 li	v0, 0					# success
+	END(_save_fp_context)
+
+#ifdef CONFIG_MIPS32_COMPAT
+	/* Save 32-bit process floating point context */
+LEAF(_save_fp_context32)
+	cfc1	t1, fcr31
+
+	EX	sdc1 $f0, SC32_FPREGS+0(a0)
+	EX	sdc1 $f2, SC32_FPREGS+16(a0)
+	EX	sdc1 $f4, SC32_FPREGS+32(a0)
+	EX	sdc1 $f6, SC32_FPREGS+48(a0)
+	EX	sdc1 $f8, SC32_FPREGS+64(a0)
+	EX	sdc1 $f10, SC32_FPREGS+80(a0)
+	EX	sdc1 $f12, SC32_FPREGS+96(a0)
+	EX	sdc1 $f14, SC32_FPREGS+112(a0)
+	EX	sdc1 $f16, SC32_FPREGS+128(a0)
+	EX	sdc1 $f18, SC32_FPREGS+144(a0)
+	EX	sdc1 $f20, SC32_FPREGS+160(a0)
+	EX	sdc1 $f22, SC32_FPREGS+176(a0)
+	EX	sdc1 $f24, SC32_FPREGS+192(a0)
+	EX	sdc1 $f26, SC32_FPREGS+208(a0)
+	EX	sdc1 $f28, SC32_FPREGS+224(a0)
+	EX	sdc1 $f30, SC32_FPREGS+240(a0)
+	EX	sw t1, SC32_FPC_CSR(a0)
+	cfc1	t0, $0				# implementation/version
+	EX	sw t0, SC32_FPC_EIR(a0)
+
+	jr	ra
+	 li	v0, 0					# success
+	END(_save_fp_context32)
+#endif
+
+/*
+ * Restore FPU state:
+ *  - fp gp registers
+ *  - cp1 status/control register
+ */
+LEAF(_restore_fp_context)
+	EX	lw t0, SC_FPC_CSR(a0)
+#ifdef CONFIG_MIPS64
+	EX	ldc1 $f1, SC_FPREGS+8(a0)
+	EX	ldc1 $f3, SC_FPREGS+24(a0)
+	EX	ldc1 $f5, SC_FPREGS+40(a0)
+	EX	ldc1 $f7, SC_FPREGS+56(a0)
+	EX	ldc1 $f9, SC_FPREGS+72(a0)
+	EX	ldc1 $f11, SC_FPREGS+88(a0)
+	EX	ldc1 $f13, SC_FPREGS+104(a0)
+	EX	ldc1 $f15, SC_FPREGS+120(a0)
+	EX	ldc1 $f17, SC_FPREGS+136(a0)
+	EX	ldc1 $f19, SC_FPREGS+152(a0)
+	EX	ldc1 $f21, SC_FPREGS+168(a0)
+	EX	ldc1 $f23, SC_FPREGS+184(a0)
+	EX	ldc1 $f25, SC_FPREGS+200(a0)
+	EX	ldc1 $f27, SC_FPREGS+216(a0)
+	EX	ldc1 $f29, SC_FPREGS+232(a0)
+	EX	ldc1 $f31, SC_FPREGS+248(a0)
+#endif
+	EX	ldc1 $f0, SC_FPREGS+0(a0)
+	EX	ldc1 $f2, SC_FPREGS+16(a0)
+	EX	ldc1 $f4, SC_FPREGS+32(a0)
+	EX	ldc1 $f6, SC_FPREGS+48(a0)
+	EX	ldc1 $f8, SC_FPREGS+64(a0)
+	EX	ldc1 $f10, SC_FPREGS+80(a0)
+	EX	ldc1 $f12, SC_FPREGS+96(a0)
+	EX	ldc1 $f14, SC_FPREGS+112(a0)
+	EX	ldc1 $f16, SC_FPREGS+128(a0)
+	EX	ldc1 $f18, SC_FPREGS+144(a0)
+	EX	ldc1 $f20, SC_FPREGS+160(a0)
+	EX	ldc1 $f22, SC_FPREGS+176(a0)
+	EX	ldc1 $f24, SC_FPREGS+192(a0)
+	EX	ldc1 $f26, SC_FPREGS+208(a0)
+	EX	ldc1 $f28, SC_FPREGS+224(a0)
+	EX	ldc1 $f30, SC_FPREGS+240(a0)
+	ctc1	t0, fcr31
+	jr	ra
+	 li	v0, 0					# success
+	END(_restore_fp_context)
+
+#ifdef CONFIG_MIPS32_COMPAT
+LEAF(_restore_fp_context32)
+	/* Restore an o32 sigcontext.  */
+	EX	lw t0, SC32_FPC_CSR(a0)
+	EX	ldc1 $f0, SC32_FPREGS+0(a0)
+	EX	ldc1 $f2, SC32_FPREGS+16(a0)
+	EX	ldc1 $f4, SC32_FPREGS+32(a0)
+	EX	ldc1 $f6, SC32_FPREGS+48(a0)
+	EX	ldc1 $f8, SC32_FPREGS+64(a0)
+	EX	ldc1 $f10, SC32_FPREGS+80(a0)
+	EX	ldc1 $f12, SC32_FPREGS+96(a0)
+	EX	ldc1 $f14, SC32_FPREGS+112(a0)
+	EX	ldc1 $f16, SC32_FPREGS+128(a0)
+	EX	ldc1 $f18, SC32_FPREGS+144(a0)
+	EX	ldc1 $f20, SC32_FPREGS+160(a0)
+	EX	ldc1 $f22, SC32_FPREGS+176(a0)
+	EX	ldc1 $f24, SC32_FPREGS+192(a0)
+	EX	ldc1 $f26, SC32_FPREGS+208(a0)
+	EX	ldc1 $f28, SC32_FPREGS+224(a0)
+	EX	ldc1 $f30, SC32_FPREGS+240(a0)
+	ctc1	t0, fcr31
+	jr	ra
+	 li	v0, 0					# success
+	END(_restore_fp_context32)
+	.set	reorder
+#endif
+
+	.type	fault@function
+	.ent	fault
+fault:	li	v0, -EFAULT				# failure
+	jr	ra
+	.end	fault
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S
new file mode 100644
index 0000000..1fc3b2e
--- /dev/null
+++ b/arch/mips/kernel/r4k_switch.S
@@ -0,0 +1,221 @@
+/*
+ * 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) 1994, 1995, 1996, 1998, 1999, 2002, 2003 Ralf Baechle
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1994, 1995, 1996, by Andreas Busse
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 2000 MIPS Technologies, Inc.
+ *    written by Carsten Langgaard, carstenl@mips.com
+ */
+#include <linux/config.h>
+#include <asm/asm.h>
+#include <asm/cachectl.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/offset.h>
+#include <asm/page.h>
+#include <asm/pgtable-bits.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/thread_info.h>
+
+#include <asm/asmmacro.h>
+
+/*
+ * Offset to the current process status flags, the first 32 bytes of the
+ * stack are not used.
+ */
+#define ST_OFF (_THREAD_SIZE - 32 - PT_SIZE + PT_STATUS)
+
+/*
+ * FPU context is saved iff the process has used it's FPU in the current
+ * time slice as indicated by _TIF_USEDFPU.  In any case, the CU1 bit for user
+ * space STATUS register should be 0, so that a process *always* starts its 
+ * userland with FPU disabled after each context switch.
+ *
+ * FPU will be enabled as soon as the process accesses FPU again, through
+ * do_cpu() trap.
+ */
+
+/*
+ * task_struct *resume(task_struct *prev, task_struct *next,
+ *                     struct thread_info *next_ti)
+ */
+	.align	5
+	LEAF(resume)
+#ifndef CONFIG_CPU_HAS_LLSC
+	sw	zero, ll_bit
+#endif
+	mfc0	t1, CP0_STATUS
+	LONG_S	t1, THREAD_STATUS(a0)
+	cpu_save_nonscratch a0
+	LONG_S	ra, THREAD_REG31(a0)
+
+	/*
+	 * check if we need to save FPU registers
+	 */
+	PTR_L	t3, TASK_THREAD_INFO(a0)
+	LONG_L	t0, TI_FLAGS(t3)
+	li	t1, _TIF_USEDFPU
+	and	t2, t0, t1
+	beqz	t2, 1f
+	nor	t1, zero, t1
+
+	and	t0, t0, t1
+	LONG_S	t0, TI_FLAGS(t3)
+
+	/*
+	 * clear saved user stack CU1 bit
+	 */
+	LONG_L	t0, ST_OFF(t3)
+	li	t1, ~ST0_CU1
+	and	t0, t0, t1
+	LONG_S	t0, ST_OFF(t3)
+
+	fpu_save_double a0 t1 t0 t2		# c0_status passed in t1
+						# clobbers t0 and t2
+1:
+
+	/*
+	 * The order of restoring the registers takes care of the race
+	 * updating $28, $29 and kernelsp without disabling ints.
+	 */
+	move	$28, a2
+	cpu_restore_nonscratch a1
+
+	PTR_ADDIU	t0, $28, _THREAD_SIZE - 32
+	set_saved_sp	t0, t1, t2
+
+	mfc0	t1, CP0_STATUS		/* Do we really need this? */
+	li	a3, 0xff01
+	and	t1, a3
+	LONG_L	a2, THREAD_STATUS(a1)
+	nor	a3, $0, a3
+	and	a2, a3
+	or	a2, t1
+	mtc0	a2, CP0_STATUS
+	move	v0, a0
+	jr	ra
+	END(resume)
+
+/*
+ * Save a thread's fp context.
+ */
+LEAF(_save_fp)
+#ifdef CONFIG_MIPS64
+	mfc0	t1, CP0_STATUS
+#endif
+	fpu_save_double a0 t1 t0 t2		# clobbers t1
+	jr	ra
+	END(_save_fp)
+
+/*
+ * Restore a thread's fp context.
+ */
+LEAF(_restore_fp)
+	fpu_restore_double a0, t1		# clobbers t1
+	jr	ra
+	END(_restore_fp)
+
+/*
+ * Load the FPU with signalling NANS.  This bit pattern we're using has
+ * the property that no matter whether considered as single or as double
+ * precision represents signaling NANS.
+ *
+ * We initialize fcr31 to rounding to nearest, no exceptions.
+ */
+
+#define FPU_DEFAULT  0x00000000
+
+LEAF(_init_fpu)
+	mfc0	t0, CP0_STATUS
+	li	t1, ST0_CU1
+	or	t0, t1
+	mtc0	t0, CP0_STATUS
+	fpu_enable_hazard
+
+	li	t1, FPU_DEFAULT
+	ctc1	t1, fcr31
+
+	li	t1, -1				# SNaN
+
+#ifdef CONFIG_MIPS64
+	sll	t0, t0, 5
+	bgez	t0, 1f				# 16 / 32 register mode?
+
+	dmtc1	t1, $f1
+	dmtc1	t1, $f3
+	dmtc1	t1, $f5
+	dmtc1	t1, $f7
+	dmtc1	t1, $f9
+	dmtc1	t1, $f11
+	dmtc1	t1, $f13
+	dmtc1	t1, $f15
+	dmtc1	t1, $f17
+	dmtc1	t1, $f19
+	dmtc1	t1, $f21
+	dmtc1	t1, $f23
+	dmtc1	t1, $f25
+	dmtc1	t1, $f27
+	dmtc1	t1, $f29
+	dmtc1	t1, $f31
+1:
+#endif
+	
+#ifdef CONFIG_CPU_MIPS32
+	mtc1	t1, $f0
+	mtc1	t1, $f1
+	mtc1	t1, $f2
+	mtc1	t1, $f3
+	mtc1	t1, $f4
+	mtc1	t1, $f5
+	mtc1	t1, $f6
+	mtc1	t1, $f7
+	mtc1	t1, $f8
+	mtc1	t1, $f9
+	mtc1	t1, $f10
+	mtc1	t1, $f11
+	mtc1	t1, $f12
+	mtc1	t1, $f13
+	mtc1	t1, $f14
+	mtc1	t1, $f15
+	mtc1	t1, $f16
+	mtc1	t1, $f17
+	mtc1	t1, $f18
+	mtc1	t1, $f19
+	mtc1	t1, $f20
+	mtc1	t1, $f21
+	mtc1	t1, $f22
+	mtc1	t1, $f23
+	mtc1	t1, $f24
+	mtc1	t1, $f25
+	mtc1	t1, $f26
+	mtc1	t1, $f27
+	mtc1	t1, $f28
+	mtc1	t1, $f29
+	mtc1	t1, $f30
+	mtc1	t1, $f31
+#else
+	.set	mips3
+	dmtc1	t1, $f0
+	dmtc1	t1, $f2
+	dmtc1	t1, $f4
+	dmtc1	t1, $f6
+	dmtc1	t1, $f8
+	dmtc1	t1, $f10
+	dmtc1	t1, $f12
+	dmtc1	t1, $f14
+	dmtc1	t1, $f16
+	dmtc1	t1, $f18
+	dmtc1	t1, $f20
+	dmtc1	t1, $f22
+	dmtc1	t1, $f24
+	dmtc1	t1, $f26
+	dmtc1	t1, $f28
+	dmtc1	t1, $f30
+#endif
+	jr	ra
+	END(_init_fpu)
diff --git a/arch/mips/kernel/r6000_fpu.S b/arch/mips/kernel/r6000_fpu.S
new file mode 100644
index 0000000..d8d3b13
--- /dev/null
+++ b/arch/mips/kernel/r6000_fpu.S
@@ -0,0 +1,87 @@
+/*
+ * r6000_fpu.S: Save/restore floating point context for signal handlers.
+ *
+ * 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) 1996 by Ralf Baechle
+ *
+ * Multi-arch abstraction and asm macros for easier reading:
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ */
+#include <asm/asm.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/offset.h>
+#include <asm/regdef.h>
+
+	.set	noreorder
+	.set	mips2
+	/* Save floating point context */
+	LEAF(_save_fp_context)
+	mfc0	t0,CP0_STATUS
+	sll	t0,t0,2
+	bgez	t0,1f
+	 nop
+
+	cfc1	t1,fcr31
+	/* Store the 16 double precision registers */
+	sdc1	$f0,(SC_FPREGS+0)(a0)
+	sdc1	$f2,(SC_FPREGS+16)(a0)
+	sdc1	$f4,(SC_FPREGS+32)(a0)
+	sdc1	$f6,(SC_FPREGS+48)(a0)
+	sdc1	$f8,(SC_FPREGS+64)(a0)
+	sdc1	$f10,(SC_FPREGS+80)(a0)
+	sdc1	$f12,(SC_FPREGS+96)(a0)
+	sdc1	$f14,(SC_FPREGS+112)(a0)
+	sdc1	$f16,(SC_FPREGS+128)(a0)
+	sdc1	$f18,(SC_FPREGS+144)(a0)
+	sdc1	$f20,(SC_FPREGS+160)(a0)
+	sdc1	$f22,(SC_FPREGS+176)(a0)
+	sdc1	$f24,(SC_FPREGS+192)(a0)
+	sdc1	$f26,(SC_FPREGS+208)(a0)
+	sdc1	$f28,(SC_FPREGS+224)(a0)
+	sdc1	$f30,(SC_FPREGS+240)(a0)
+	jr	ra
+	 sw	t0,SC_FPC_CSR(a0)
+1:	jr	ra
+	 nop
+	END(_save_fp_context)
+
+/* Restore FPU state:
+ *  - fp gp registers
+ *  - cp1 status/control register
+ *
+ * We base the decision which registers to restore from the signal stack
+ * frame on the current content of c0_status, not on the content of the
+ * stack frame which might have been changed by the user.
+ */
+	LEAF(_restore_fp_context)
+	mfc0	t0,CP0_STATUS
+	sll	t0,t0,2
+
+	bgez	t0,1f
+	 lw	t0,SC_FPC_CSR(a0)
+	/* Restore the 16 double precision registers */
+	ldc1	$f0,(SC_FPREGS+0)(a0)
+	ldc1	$f2,(SC_FPREGS+16)(a0)
+	ldc1	$f4,(SC_FPREGS+32)(a0)
+	ldc1	$f6,(SC_FPREGS+48)(a0)
+	ldc1	$f8,(SC_FPREGS+64)(a0)
+	ldc1	$f10,(SC_FPREGS+80)(a0)
+	ldc1	$f12,(SC_FPREGS+96)(a0)
+	ldc1	$f14,(SC_FPREGS+112)(a0)
+	ldc1	$f16,(SC_FPREGS+128)(a0)
+	ldc1	$f18,(SC_FPREGS+144)(a0)
+	ldc1	$f20,(SC_FPREGS+160)(a0)
+	ldc1	$f22,(SC_FPREGS+176)(a0)
+	ldc1	$f24,(SC_FPREGS+192)(a0)
+	ldc1	$f26,(SC_FPREGS+208)(a0)
+	ldc1	$f28,(SC_FPREGS+224)(a0)
+	ldc1	$f30,(SC_FPREGS+240)(a0)
+	jr	ra
+	 ctc1	t0,fcr31
+1:	jr	ra
+	 nop
+	END(_restore_fp_context)
diff --git a/arch/mips/kernel/reset.c b/arch/mips/kernel/reset.c
new file mode 100644
index 0000000..7e0a982
--- /dev/null
+++ b/arch/mips/kernel/reset.c
@@ -0,0 +1,43 @@
+/*
+ * 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) 2001 by Ralf Baechle
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/reboot.h>
+#include <asm/reboot.h>
+
+/*
+ * Urgs ...  Too many MIPS machines to handle this in a generic way.
+ * So handle all using function pointers to machine specific
+ * functions.
+ */
+void (*_machine_restart)(char *command);
+void (*_machine_halt)(void);
+void (*_machine_power_off)(void);
+
+void machine_restart(char *command)
+{
+	_machine_restart(command);
+}
+
+EXPORT_SYMBOL(machine_restart);
+
+void machine_halt(void)
+{
+	_machine_halt();
+}
+
+EXPORT_SYMBOL(machine_halt);
+
+void machine_power_off(void)
+{
+	_machine_power_off();
+}
+
+EXPORT_SYMBOL(machine_power_off);
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
new file mode 100644
index 0000000..344f2e2
--- /dev/null
+++ b/arch/mips/kernel/scall32-o32.S
@@ -0,0 +1,641 @@
+/*
+ * 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, 96, 97, 98, 99, 2000, 01, 02 by Ralf Baechle
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ * Copyright (C) 2004 Thiemo Seufer
+ */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <asm/asm.h>
+#include <asm/asmmacro.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/isadep.h>
+#include <asm/sysmips.h>
+#include <asm/thread_info.h>
+#include <asm/unistd.h>
+#include <asm/war.h>
+#include <asm/offset.h>
+
+/* Highest syscall used of any syscall flavour */
+#define MAX_SYSCALL_NO	__NR_O32_Linux + __NR_O32_Linux_syscalls
+
+	.align  5
+NESTED(handle_sys, PT_SIZE, sp)
+	.set	noat
+	SAVE_SOME
+	STI
+	.set	at
+
+	lw	t1, PT_EPC(sp)		# skip syscall on return
+
+#if defined(CONFIG_BINFMT_IRIX)
+	sltiu	t0, v0, MAX_SYSCALL_NO + 1 # check syscall number
+#else
+	subu	v0, v0, __NR_O32_Linux	# check syscall number
+	sltiu	t0, v0, __NR_O32_Linux_syscalls + 1
+#endif
+	addiu	t1, 4			# skip to next instruction
+	sw	t1, PT_EPC(sp)
+	beqz	t0, illegal_syscall
+
+	sll	t0, v0, 3
+	la	t1, sys_call_table
+	addu	t1, t0
+	lw	t2, (t1)		# syscall routine
+	lw	t3, 4(t1)		# >= 0 if we need stack arguments
+	beqz	t2, illegal_syscall
+
+	sw	a3, PT_R26(sp)		# save a3 for syscall restarting
+	bgez	t3, stackargs
+
+stack_done:
+	lw	t0, TI_FLAGS($28)	# syscall tracing enabled?
+	li	t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+	and	t0, t1
+	bnez	t0, syscall_trace_entry	# -> yes
+
+	jalr	t2			# Do The Real Thing (TM)
+
+	li	t0, -EMAXERRNO - 1	# error?
+	sltu	t0, t0, v0
+	sw	t0, PT_R7(sp)		# set error flag
+	beqz	t0, 1f
+
+	negu	v0			# error
+	sw	v0, PT_R0(sp)		# set flag for syscall
+					# restarting
+1:	sw	v0, PT_R2(sp)		# result
+
+o32_syscall_exit:
+	local_irq_disable		# make sure need_resched and
+					# signals dont change between
+					# sampling and return
+	lw	a2, TI_FLAGS($28)	# current->work
+	li	t0, _TIF_ALLWORK_MASK
+	and	t0, a2
+	bnez	t0, o32_syscall_exit_work
+
+	j	restore_partial
+
+o32_syscall_exit_work:
+	j	syscall_exit_work_partial
+
+/* ------------------------------------------------------------------------ */
+
+syscall_trace_entry:
+	SAVE_STATIC
+	move	s0, t2
+	move	a0, sp
+	li	a1, 0
+	jal	do_syscall_trace
+
+	lw	a0, PT_R4(sp)		# Restore argument registers
+	lw	a1, PT_R5(sp)
+	lw	a2, PT_R6(sp)
+	lw	a3, PT_R7(sp)
+	jalr	s0
+
+	li	t0, -EMAXERRNO - 1	# error?
+	sltu	t0, t0, v0
+	sw	t0, PT_R7(sp)		# set error flag
+	beqz	t0, 1f
+
+	negu	v0			# error
+	sw	v0, PT_R0(sp)		# set flag for syscall
+					# restarting
+1:	sw	v0, PT_R2(sp)		# result
+
+	j	syscall_exit
+
+/* ------------------------------------------------------------------------ */
+
+	/*
+	 * More than four arguments.  Try to deal with it by copying the
+	 * stack arguments from the user stack to the kernel stack.
+	 * This Sucks (TM).
+	 */
+stackargs:
+	lw	t0, PT_R29(sp)		# get old user stack pointer
+
+	/*
+	 * We intentionally keep the kernel stack a little below the top of
+	 * userspace so we don't have to do a slower byte accurate check here.
+	 */
+	lw	t5, TI_ADDR_LIMIT($28)
+	addu	t4, t0, 32
+	and	t5, t4
+	bltz	t5, bad_stack		# -> sp is bad
+
+	/* Ok, copy the args from the luser stack to the kernel stack.
+	 * t3 is the precomputed number of instruction bytes needed to
+	 * load or store arguments 6-8.
+	 */
+
+	la	t1, 5f			# load up to 3 arguments
+	subu	t1, t3
+1:	lw	t5, 16(t0)		# argument #5 from usp
+	.set    push
+	.set    noreorder
+	.set	nomacro
+	jr	t1
+	 addiu	t1, 6f - 5f
+
+2:	lw	t8, 28(t0)		# argument #8 from usp
+3:	lw	t7, 24(t0)		# argument #7 from usp
+4:	lw	t6, 20(t0)		# argument #6 from usp
+5:	jr	t1
+	 sw	t5, 16(sp)		# argument #5 to ksp
+
+	sw	t8, 28(sp)		# argument #8 to ksp
+	sw	t7, 24(sp)		# argument #7 to ksp
+	sw	t6, 20(sp)		# argument #6 to ksp
+6:	j	stack_done		# go back
+	 nop
+	.set	pop
+
+	.section __ex_table,"a"
+	PTR	1b,bad_stack
+	PTR	2b,bad_stack
+	PTR	3b,bad_stack
+	PTR	4b,bad_stack
+	.previous
+
+	/*
+	 * The stackpointer for a call with more than 4 arguments is bad.
+	 * We probably should handle this case a bit more drastic.
+	 */
+bad_stack:
+	negu	v0				# error
+	sw	v0, PT_R0(sp)
+	sw	v0, PT_R2(sp)
+	li	t0, 1				# set error flag
+	sw	t0, PT_R7(sp)
+	j	o32_syscall_exit
+
+	/*
+	 * The system call does not exist in this kernel
+	 */
+illegal_syscall:
+	li	v0, -ENOSYS			# error
+	sw	v0, PT_R2(sp)
+	li	t0, 1				# set error flag
+	sw	t0, PT_R7(sp)
+	j	o32_syscall_exit
+	END(handle_sys)
+
+	LEAF(mips_atomic_set)
+	andi	v0, a1, 3			# must be word aligned
+	bnez	v0, bad_alignment
+
+	lw	v1, TI_ADDR_LIMIT($28)		# in legal address range?
+	addiu	a0, a1, 4
+	or	a0, a0, a1
+	and	a0, a0, v1
+	bltz	a0, bad_address
+
+#ifdef CONFIG_CPU_HAS_LLSC
+	/* Ok, this is the ll/sc case.  World is sane :-)  */
+1:	ll	v0, (a1)
+	move	a0, a2
+2:	sc	a0, (a1)
+#if R10000_LLSC_WAR
+	beqzl	a0, 1b
+#else
+	beqz	a0, 1b
+#endif
+
+	.section __ex_table,"a"
+	PTR	1b, bad_stack
+	PTR	2b, bad_stack
+	.previous
+#else
+	sw	a1, 16(sp)
+	sw	a2, 20(sp)
+
+	move	a0, sp
+	move	a2, a1
+	li	a1, 1
+	jal	do_page_fault
+
+	lw	a1, 16(sp)
+	lw	a2, 20(sp)
+
+	/*
+	 * At this point the page should be readable and writable unless
+	 * there was no more memory available.
+	 */
+1:	lw	v0, (a1)
+2:	sw	a2, (a1)
+
+	.section __ex_table,"a"
+	PTR	1b, no_mem
+	PTR	2b, no_mem
+	.previous
+#endif
+
+	sw	zero, PT_R7(sp)		# success
+	sw	v0, PT_R2(sp)		# result
+
+	/* Success, so skip usual error handling garbage.  */
+	lw	a2, TI_FLAGS($28)	# syscall tracing enabled?
+	li	t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+	and	t0, a2, t0
+	bnez	t0, 1f
+
+	j	o32_syscall_exit
+
+1:	SAVE_STATIC
+	move	a0, sp
+	li	a1, 1
+	jal	do_syscall_trace
+	j	syscall_exit
+
+no_mem:	li	v0, -ENOMEM
+	jr	ra
+
+bad_address:
+	li	v0, -EFAULT
+	jr	ra
+
+bad_alignment:
+	li	v0, -EINVAL
+	jr	ra
+	END(mips_atomic_set)
+
+	LEAF(sys_sysmips)
+	beq	a0, MIPS_ATOMIC_SET, mips_atomic_set
+	j	_sys_sysmips
+	END(sys_sysmips)
+
+	LEAF(sys_syscall)
+#if defined(CONFIG_BINFMT_IRIX)
+	sltiu	v0, a0, MAX_SYSCALL_NO + 1 # check syscall number
+#else
+	subu	t0, a0, __NR_O32_Linux	# check syscall number
+	sltiu	v0, t0, __NR_O32_Linux_syscalls + 1
+#endif
+	sll	t1, t0, 3
+	beqz	v0, einval
+
+	lw	t2, sys_call_table(t1)		# syscall routine
+
+#if defined(CONFIG_BINFMT_IRIX)
+	li	v1, 4000			# nr of sys_syscall
+#else
+	li	v1, 4000 - __NR_O32_Linux	# index of sys_syscall
+#endif
+	beq	t0, v1, einval			# do not recurse
+
+	/* Some syscalls like execve get their arguments from struct pt_regs
+	   and claim zero arguments in the syscall table. Thus we have to
+	   assume the worst case and shuffle around all potential arguments.
+	   If you want performance, don't use indirect syscalls. */
+
+	move	a0, a1				# shift argument registers
+	move	a1, a2
+	move	a2, a3
+	lw	a3, 16(sp)
+	lw	t4, 20(sp)
+	lw	t5, 24(sp)
+	lw	t6, 28(sp)
+	sw	t4, 16(sp)
+	sw	t5, 20(sp)
+	sw	t6, 24(sp)
+	sw	a0, PT_R4(sp)			# .. and push back a0 - a3, some
+	sw	a1, PT_R5(sp)			# syscalls expect them there
+	sw	a2, PT_R6(sp)
+	sw	a3, PT_R7(sp)
+	sw	a3, PT_R26(sp)			# update a3 for syscall restarting
+	jr	t2
+	/* Unreached */
+
+einval:	li	v0, -EINVAL
+	jr	ra
+	END(sys_syscall)
+
+	.macro	fifty ptr, nargs, from=1, to=50
+	sys	\ptr		\nargs
+	.if	\to-\from
+	fifty	\ptr,\nargs,"(\from+1)",\to
+	.endif
+	.endm
+
+	.macro	mille ptr, nargs, from=1, to=20
+	fifty	\ptr,\nargs
+	.if	\to-\from
+	mille	\ptr,\nargs,"(\from+1)",\to
+	.endif
+	.endm
+
+	.macro	syscalltable
+#if defined(CONFIG_BINFMT_IRIX)
+	mille	sys_ni_syscall		0	/*    0 -  999 SVR4 flavour */
+	mille	sys_ni_syscall		0	/* 1000 - 1999 32-bit IRIX */
+	mille	sys_ni_syscall		0	/* 2000 - 2999 BSD43 flavour */
+	mille	sys_ni_syscall		0	/* 3000 - 3999 POSIX flavour */
+#endif
+
+	sys	sys_syscall		8	/* 4000 */
+	sys	sys_exit		1
+	sys	sys_fork		0
+	sys	sys_read		3
+	sys	sys_write		3
+	sys	sys_open		3	/* 4005 */
+	sys	sys_close		1
+	sys	sys_waitpid		3
+	sys	sys_creat		2
+	sys	sys_link		2
+	sys	sys_unlink		1	/* 4010 */
+	sys	sys_execve		0
+	sys	sys_chdir		1
+	sys	sys_time		1
+	sys	sys_mknod		3
+	sys	sys_chmod		2	/* 4015 */
+	sys	sys_lchown		3
+	sys	sys_ni_syscall		0
+	sys	sys_ni_syscall		0	/* was sys_stat */
+	sys	sys_lseek		3
+	sys	sys_getpid		0	/* 4020 */
+	sys	sys_mount		5
+	sys	sys_oldumount		1
+	sys	sys_setuid		1
+	sys	sys_getuid		0
+	sys	sys_stime		1	/* 4025 */
+	sys	sys_ptrace		4
+	sys	sys_alarm		1
+	sys	sys_ni_syscall		0	/* was sys_fstat */
+	sys	sys_pause		0
+	sys	sys_utime		2	/* 4030 */
+	sys	sys_ni_syscall		0
+	sys	sys_ni_syscall		0
+	sys	sys_access		2
+	sys	sys_nice		1
+	sys	sys_ni_syscall		0	/* 4035 */
+	sys	sys_sync		0
+	sys	sys_kill		2
+	sys	sys_rename		2
+	sys	sys_mkdir		2
+	sys	sys_rmdir		1	/* 4040 */
+	sys	sys_dup			1
+	sys	sys_pipe		0
+	sys	sys_times		1
+	sys	sys_ni_syscall		0
+	sys	sys_brk			1	/* 4045 */
+	sys	sys_setgid		1
+	sys	sys_getgid		0
+	sys	sys_ni_syscall		0	/* was signal(2) */
+	sys	sys_geteuid		0
+	sys	sys_getegid		0	/* 4050 */
+	sys	sys_acct		1
+	sys	sys_umount		2
+	sys	sys_ni_syscall		0
+	sys	sys_ioctl		3
+	sys	sys_fcntl		3	/* 4055 */
+	sys	sys_ni_syscall		2
+	sys	sys_setpgid		2
+	sys	sys_ni_syscall		0
+	sys	sys_olduname		1
+	sys	sys_umask		1	/* 4060 */
+	sys	sys_chroot		1
+	sys	sys_ustat		2
+	sys	sys_dup2		2
+	sys	sys_getppid		0
+	sys	sys_getpgrp		0	/* 4065 */
+	sys	sys_setsid		0
+	sys	sys_sigaction		3
+	sys	sys_sgetmask		0
+	sys	sys_ssetmask		1
+	sys	sys_setreuid		2	/* 4070 */
+	sys	sys_setregid		2
+	sys	sys_sigsuspend		0
+	sys	sys_sigpending		1
+	sys	sys_sethostname		2
+	sys	sys_setrlimit		2	/* 4075 */
+	sys	sys_getrlimit		2
+	sys	sys_getrusage		2
+	sys	sys_gettimeofday	2
+	sys	sys_settimeofday	2
+	sys	sys_getgroups		2	/* 4080 */
+	sys	sys_setgroups		2
+	sys	sys_ni_syscall		0	/* old_select */
+	sys	sys_symlink		2
+	sys	sys_ni_syscall		0	/* was sys_lstat */
+	sys	sys_readlink		3	/* 4085 */
+	sys	sys_uselib		1
+	sys	sys_swapon		2
+	sys	sys_reboot		3
+	sys	old_readdir		3
+	sys	old_mmap		6	/* 4090 */
+	sys	sys_munmap		2
+	sys	sys_truncate		2
+	sys	sys_ftruncate		2
+	sys	sys_fchmod		2
+	sys	sys_fchown		3	/* 4095 */
+	sys	sys_getpriority		2
+	sys	sys_setpriority		3
+	sys	sys_ni_syscall		0
+	sys	sys_statfs		2
+	sys	sys_fstatfs		2	/* 4100 */
+	sys	sys_ni_syscall		0	/* was ioperm(2) */
+	sys	sys_socketcall		2
+	sys	sys_syslog		3
+	sys	sys_setitimer		3
+	sys	sys_getitimer		2	/* 4105 */
+	sys	sys_newstat		2
+	sys	sys_newlstat		2
+	sys	sys_newfstat		2
+	sys	sys_uname		1
+	sys	sys_ni_syscall		0	/* 4110 was iopl(2) */
+	sys	sys_vhangup		0
+	sys	sys_ni_syscall		0	/* was sys_idle() */
+	sys	sys_ni_syscall		0	/* was sys_vm86 */
+	sys	sys_wait4		4
+	sys	sys_swapoff		1	/* 4115 */
+	sys	sys_sysinfo		1
+	sys	sys_ipc			6
+	sys	sys_fsync		1
+	sys	sys_sigreturn		0
+	sys	sys_clone		0	/* 4120 */
+	sys	sys_setdomainname	2
+	sys	sys_newuname		1
+	sys	sys_ni_syscall		0	/* sys_modify_ldt */
+	sys	sys_adjtimex		1
+	sys	sys_mprotect		3	/* 4125 */
+	sys	sys_sigprocmask		3
+	sys	sys_ni_syscall		0	/* was create_module */
+	sys	sys_init_module		5
+	sys	sys_delete_module	1
+	sys	sys_ni_syscall		0	/* 4130	was get_kernel_syms */
+	sys	sys_quotactl		4
+	sys	sys_getpgid		1
+	sys	sys_fchdir		1
+	sys	sys_bdflush		2
+	sys	sys_sysfs		3	/* 4135 */
+	sys	sys_personality		1
+	sys	sys_ni_syscall		0	/* for afs_syscall */
+	sys	sys_setfsuid		1
+	sys	sys_setfsgid		1
+	sys	sys_llseek		5	/* 4140 */
+	sys	sys_getdents		3
+	sys	sys_select		5
+	sys	sys_flock		2
+	sys	sys_msync		3
+	sys	sys_readv		3	/* 4145 */
+	sys	sys_writev		3
+	sys	sys_cacheflush		3
+	sys	sys_cachectl		3
+	sys	sys_sysmips		4
+	sys	sys_ni_syscall		0	/* 4150 */
+	sys	sys_getsid		1
+	sys	sys_fdatasync		1
+	sys	sys_sysctl		1
+	sys	sys_mlock		2
+	sys	sys_munlock		2	/* 4155 */
+	sys	sys_mlockall		1
+	sys	sys_munlockall		0
+	sys	sys_sched_setparam	2
+	sys	sys_sched_getparam	2
+	sys	sys_sched_setscheduler	3	/* 4160 */
+	sys	sys_sched_getscheduler	1
+	sys	sys_sched_yield		0
+	sys	sys_sched_get_priority_max 1
+	sys	sys_sched_get_priority_min 1
+	sys	sys_sched_rr_get_interval 2	/* 4165 */
+	sys	sys_nanosleep,		2
+	sys	sys_mremap,		4
+	sys	sys_accept		3
+	sys	sys_bind		3
+	sys	sys_connect		3	/* 4170 */
+	sys	sys_getpeername		3
+	sys	sys_getsockname		3
+	sys	sys_getsockopt		5
+	sys	sys_listen		2
+	sys	sys_recv		4	/* 4175 */
+	sys	sys_recvfrom		6
+	sys	sys_recvmsg		3
+	sys	sys_send		4
+	sys	sys_sendmsg		3
+	sys	sys_sendto		6	/* 4180 */
+	sys	sys_setsockopt		5
+	sys	sys_shutdown		2
+	sys	sys_socket		3
+	sys	sys_socketpair		4
+	sys	sys_setresuid		3	/* 4185 */
+	sys	sys_getresuid		3
+	sys	sys_ni_syscall		0	/* was sys_query_module */
+	sys	sys_poll		3
+	sys	sys_nfsservctl		3
+	sys	sys_setresgid		3	/* 4190 */
+	sys	sys_getresgid		3
+	sys	sys_prctl		5
+	sys	sys_rt_sigreturn	0
+	sys	sys_rt_sigaction	4
+	sys	sys_rt_sigprocmask	4	/* 4195 */
+	sys	sys_rt_sigpending	2
+	sys	sys_rt_sigtimedwait	4
+	sys	sys_rt_sigqueueinfo	3
+	sys	sys_rt_sigsuspend	0
+	sys	sys_pread64		6	/* 4200 */
+	sys	sys_pwrite64		6
+	sys	sys_chown		3
+	sys	sys_getcwd		2
+	sys	sys_capget		2
+	sys	sys_capset		2	/* 4205 */
+	sys	sys_sigaltstack		0
+	sys	sys_sendfile		4
+	sys	sys_ni_syscall		0
+	sys	sys_ni_syscall		0
+	sys	sys_mmap2		6	/* 4210 */
+	sys	sys_truncate64		4
+	sys	sys_ftruncate64		4
+	sys	sys_stat64		2
+	sys	sys_lstat64		2
+	sys	sys_fstat64		2	/* 4215 */
+	sys	sys_pivot_root		2
+	sys	sys_mincore		3
+	sys	sys_madvise		3
+	sys	sys_getdents64		3
+	sys	sys_fcntl64		3	/* 4220 */
+	sys	sys_ni_syscall		0
+	sys	sys_gettid		0
+	sys	sys_readahead		5
+	sys	sys_setxattr		5
+	sys	sys_lsetxattr		5	/* 4225 */
+	sys	sys_fsetxattr		5
+	sys	sys_getxattr		4
+	sys	sys_lgetxattr		4
+	sys	sys_fgetxattr		4
+	sys	sys_listxattr		3	/* 4230 */
+	sys	sys_llistxattr		3
+	sys	sys_flistxattr		3
+	sys	sys_removexattr		2
+	sys	sys_lremovexattr	2
+	sys	sys_fremovexattr	2	/* 4235 */
+	sys	sys_tkill		2
+	sys	sys_sendfile64		5
+	sys	sys_futex		2
+	sys	sys_sched_setaffinity	3
+	sys	sys_sched_getaffinity	3	/* 4240 */
+	sys	sys_io_setup		2
+	sys	sys_io_destroy		1
+	sys	sys_io_getevents	5
+	sys	sys_io_submit		3
+	sys	sys_io_cancel		3	/* 4245 */
+	sys	sys_exit_group		1
+	sys	sys_lookup_dcookie	3
+	sys	sys_epoll_create	1
+	sys	sys_epoll_ctl		4
+	sys	sys_epoll_wait		3	/* 4250 */
+	sys	sys_remap_file_pages	5
+	sys	sys_set_tid_address	1
+	sys	sys_restart_syscall	0
+	sys	sys_fadvise64_64	7
+	sys	sys_statfs64		3	/* 4255 */
+	sys	sys_fstatfs64		2
+	sys	sys_timer_create	3
+	sys	sys_timer_settime	4
+	sys	sys_timer_gettime	2
+	sys	sys_timer_getoverrun	1	/* 4260 */
+	sys	sys_timer_delete	1
+	sys	sys_clock_settime	2
+	sys	sys_clock_gettime	2
+	sys	sys_clock_getres	2
+	sys	sys_clock_nanosleep	4	/* 4265 */
+	sys	sys_tgkill		3
+	sys	sys_utimes		2
+	sys	sys_mbind		4
+	sys	sys_ni_syscall		0	/* sys_get_mempolicy */
+	sys	sys_ni_syscall		0	/* 4270 sys_set_mempolicy */
+	sys	sys_mq_open		4
+	sys	sys_mq_unlink		1
+	sys	sys_mq_timedsend	5
+	sys	sys_mq_timedreceive	5
+	sys	sys_mq_notify		2	/* 4275 */
+	sys	sys_mq_getsetattr	3
+	sys	sys_ni_syscall		0	/* sys_vserver */
+	sys	sys_waitid		4
+	sys	sys_ni_syscall		0	/* available, was setaltroot */
+	sys	sys_add_key		5
+	sys	sys_request_key		4
+	sys	sys_keyctl		5
+
+	.endm
+
+	/* We pre-compute the number of _instruction_ bytes needed to
+	   load or store the arguments 6-8. Negative values are ignored. */
+
+	.macro  sys function, nargs
+	PTR	\function
+	LONG	(\nargs << 2) - (5 << 2)
+	.endm
+
+	.align	3
+	.type	sys_call_table,@object
+EXPORT(sys_call_table)
+	syscalltable
+	.size	sys_call_table, . - sys_call_table
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
new file mode 100644
index 0000000..32efb88
--- /dev/null
+++ b/arch/mips/kernel/scall64-64.S
@@ -0,0 +1,451 @@
+/*
+ * 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, 96, 97, 98, 99, 2000, 01, 02 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <asm/asm.h>
+#include <asm/asmmacro.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/offset.h>
+#include <asm/sysmips.h>
+#include <asm/thread_info.h>
+#include <asm/unistd.h>
+#include <asm/war.h>
+
+#ifndef CONFIG_BINFMT_ELF32
+/* Neither O32 nor N32, so define handle_sys here */
+#define handle_sys64 handle_sys
+#endif
+
+	.align  5
+NESTED(handle_sys64, PT_SIZE, sp)
+#if !defined(CONFIG_MIPS32_O32) && !defined(CONFIG_MIPS32_N32)
+	/*
+	 * When 32-bit compatibility is configured scall_o32.S
+	 * already did this.
+	 */
+	.set	noat
+	SAVE_SOME
+	STI
+	.set	at
+#endif
+
+	dsubu	t0, v0, __NR_64_Linux	# check syscall number
+	sltiu	t0, t0,	__NR_64_Linux_syscalls + 1
+#if !defined(CONFIG_MIPS32_O32) && !defined(CONFIG_MIPS32_N32)
+	ld	t1, PT_EPC(sp)		# skip syscall on return
+	daddiu	t1, 4			# skip to next instruction
+	sd	t1, PT_EPC(sp)
+#endif
+	beqz	t0, illegal_syscall
+
+	dsll	t0, v0, 3		# offset into table
+	ld	t2, (sys_call_table - (__NR_64_Linux * 8))(t0)
+					# syscall routine
+
+	sd	a3, PT_R26(sp)		# save a3 for syscall restarting
+
+	li	t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+	LONG_L	t0, TI_FLAGS($28)	# syscall tracing enabled?
+	and	t0, t1, t0
+	bnez	t0, syscall_trace_entry
+
+	jalr	t2			# Do The Real Thing (TM)
+
+	li	t0, -EMAXERRNO - 1	# error?
+	sltu	t0, t0, v0
+	sd	t0, PT_R7(sp)		# set error flag
+	beqz	t0, 1f
+
+	dnegu	v0			# error
+	sd	v0, PT_R0(sp)		# set flag for syscall
+					# restarting
+1:	sd	v0, PT_R2(sp)		# result
+
+n64_syscall_exit:
+	local_irq_disable		# make sure need_resched and
+					# signals dont change between
+					# sampling and return
+	LONG_L	a2, TI_FLAGS($28)	# current->work
+	li	t0, _TIF_ALLWORK_MASK
+	and	t0, a2, t0
+	bnez	t0, n64_syscall_exit_work
+
+	j	restore_partial
+
+n64_syscall_exit_work:
+	j	syscall_exit_work_partial
+
+/* ------------------------------------------------------------------------ */
+
+syscall_trace_entry:
+	SAVE_STATIC
+	move	s0, t2
+	move	a0, sp
+	li	a1, 0
+	jal	do_syscall_trace
+
+	ld	a0, PT_R4(sp)		# Restore argument registers
+	ld	a1, PT_R5(sp)
+	ld	a2, PT_R6(sp)
+	ld	a3, PT_R7(sp)
+	ld	a4, PT_R8(sp)
+	ld	a5, PT_R9(sp)
+	jalr	s0
+
+	li	t0, -EMAXERRNO - 1	# error?
+	sltu	t0, t0, v0
+	sd	t0, PT_R7(sp)		# set error flag
+	beqz	t0, 1f
+
+	dnegu	v0			# error
+	sd	v0, PT_R0(sp)		# set flag for syscall restarting
+1:	sd	v0, PT_R2(sp)		# result
+
+	j	syscall_exit
+
+illegal_syscall:
+	/* This also isn't a 64-bit syscall, throw an error.  */
+	li	v0, -ENOSYS			# error
+	sd	v0, PT_R2(sp)
+	li	t0, 1				# set error flag
+	sd	t0, PT_R7(sp)
+	j	n64_syscall_exit
+	END(handle_sys64)
+
+	LEAF(mips_atomic_set)
+	andi	v0, a1, 3			# must be word aligned
+	bnez	v0, bad_alignment
+
+	LONG_L	v1, TI_ADDR_LIMIT($28)		# in legal address range?
+	LONG_ADDIU	a0, a1, 4
+	or	a0, a0, a1
+	and	a0, a0, v1
+	bltz	a0, bad_address
+
+#ifdef CONFIG_CPU_HAS_LLSC
+	/* Ok, this is the ll/sc case.  World is sane :-)  */
+1:	ll	v0, (a1)
+	move	a0, a2
+2:	sc	a0, (a1)
+#if R10000_LLSC_WAR
+	beqzl	a0, 1b
+#else
+	beqz	a0, 1b
+#endif
+
+	.section __ex_table,"a"
+	PTR	1b, bad_stack
+	PTR	2b, bad_stack
+	.previous
+#else
+	sw	a1, 16(sp)
+	sw	a2, 20(sp)
+
+	move	a0, sp
+	move	a2, a1
+	li	a1, 1
+	jal	do_page_fault
+
+	lw	a1, 16(sp)
+	lw	a2, 20(sp)
+
+	/*
+	 * At this point the page should be readable and writable unless
+	 * there was no more memory available.
+	 */
+1:	lw	v0, (a1)
+2:	sw	a2, (a1)
+
+	.section __ex_table,"a"
+	PTR	1b, no_mem
+	PTR	2b, no_mem
+	.previous
+#endif
+
+	sd	zero, PT_R7(sp)		# success
+	sd	v0, PT_R2(sp)		# result
+
+	/* Success, so skip usual error handling garbage.  */
+	li	t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+	LONG_L	a2, TI_FLAGS($28)	# syscall tracing enabled?
+	and	t0, a2, t0
+	bnez	t0, 1f
+
+	j	n64_syscall_exit
+
+1:	SAVE_STATIC
+	move	a0, sp
+	li	a1, 1
+	jal	do_syscall_trace
+	j	syscall_exit
+
+no_mem:	li	v0, -ENOMEM
+	jr	ra
+
+bad_address:
+	li	v0, -EFAULT
+	jr	ra
+
+bad_alignment:
+	li	v0, -EINVAL
+	jr	ra
+	END(mips_atomic_set)
+
+	LEAF(sys_sysmips)
+	beq	a0, MIPS_ATOMIC_SET, mips_atomic_set
+	j	_sys_sysmips
+	END(sys_sysmips)
+
+	.align	3
+sys_call_table:
+	PTR	sys_read			/* 5000 */
+	PTR	sys_write
+	PTR	sys_open
+	PTR	sys_close
+	PTR	sys_newstat
+	PTR	sys_newfstat			/* 5005 */
+	PTR	sys_newlstat
+	PTR	sys_poll
+	PTR	sys_lseek
+	PTR	old_mmap
+	PTR	sys_mprotect			/* 5010 */
+	PTR	sys_munmap
+	PTR	sys_brk
+	PTR	sys_rt_sigaction
+	PTR	sys_rt_sigprocmask
+	PTR	sys_ioctl			/* 5015 */
+	PTR	sys_pread64
+	PTR	sys_pwrite64
+	PTR	sys_readv
+	PTR	sys_writev
+	PTR	sys_access			/* 5020 */
+	PTR	sys_pipe
+	PTR	sys_select
+	PTR	sys_sched_yield
+	PTR	sys_mremap
+	PTR	sys_msync			/* 5025 */
+	PTR	sys_mincore
+	PTR	sys_madvise
+	PTR	sys_shmget
+	PTR	sys_shmat
+	PTR	sys_shmctl			/* 5030 */
+	PTR	sys_dup
+	PTR	sys_dup2
+	PTR	sys_pause
+	PTR	sys_nanosleep
+	PTR	sys_getitimer			/* 5035 */
+	PTR	sys_setitimer
+	PTR	sys_alarm
+	PTR	sys_getpid
+	PTR	sys_sendfile64
+	PTR	sys_socket			/* 5040 */
+	PTR	sys_connect
+	PTR	sys_accept
+	PTR	sys_sendto
+	PTR	sys_recvfrom
+	PTR	sys_sendmsg			/* 5045 */
+	PTR	sys_recvmsg
+	PTR	sys_shutdown
+	PTR	sys_bind
+	PTR	sys_listen
+	PTR	sys_getsockname			/* 5050 */
+	PTR	sys_getpeername
+	PTR	sys_socketpair
+	PTR	sys_setsockopt
+	PTR	sys_getsockopt
+	PTR	sys_clone			/* 5055 */
+	PTR	sys_fork
+	PTR	sys_execve
+	PTR	sys_exit
+	PTR	sys_wait4
+	PTR	sys_kill			/* 5060 */
+	PTR	sys_newuname
+	PTR	sys_semget
+	PTR	sys_semop
+	PTR	sys_semctl
+	PTR	sys_shmdt			/* 5065 */
+	PTR	sys_msgget
+	PTR	sys_msgsnd
+	PTR	sys_msgrcv
+	PTR	sys_msgctl
+	PTR	sys_fcntl			/* 5070 */
+	PTR	sys_flock
+	PTR	sys_fsync
+	PTR	sys_fdatasync
+	PTR	sys_truncate
+	PTR	sys_ftruncate			/* 5075 */
+	PTR	sys_getdents
+	PTR	sys_getcwd
+	PTR	sys_chdir
+	PTR	sys_fchdir
+	PTR	sys_rename			/* 5080 */
+	PTR	sys_mkdir
+	PTR	sys_rmdir
+	PTR	sys_creat
+	PTR	sys_link
+	PTR	sys_unlink			/* 5085 */
+	PTR	sys_symlink
+	PTR	sys_readlink
+	PTR	sys_chmod
+	PTR	sys_fchmod
+	PTR	sys_chown			/* 5090 */
+	PTR	sys_fchown
+	PTR	sys_lchown
+	PTR	sys_umask
+	PTR	sys_gettimeofday
+	PTR	sys_getrlimit			/* 5095 */
+	PTR	sys_getrusage
+	PTR	sys_sysinfo
+	PTR	sys_times
+	PTR	sys_ptrace
+	PTR	sys_getuid			/* 5100 */
+	PTR	sys_syslog
+	PTR	sys_getgid
+	PTR	sys_setuid
+	PTR	sys_setgid
+	PTR	sys_geteuid			/* 5105 */
+	PTR	sys_getegid
+	PTR	sys_setpgid
+	PTR	sys_getppid
+	PTR	sys_getpgrp
+	PTR	sys_setsid			/* 5110 */
+	PTR	sys_setreuid
+	PTR	sys_setregid
+	PTR	sys_getgroups
+	PTR	sys_setgroups
+	PTR	sys_setresuid			/* 5115 */
+	PTR	sys_getresuid
+	PTR	sys_setresgid
+	PTR	sys_getresgid
+	PTR	sys_getpgid
+	PTR	sys_setfsuid			/* 5120 */
+	PTR	sys_setfsgid
+	PTR	sys_getsid
+	PTR	sys_capget
+	PTR	sys_capset
+	PTR	sys_rt_sigpending		/* 5125 */
+	PTR	sys_rt_sigtimedwait
+	PTR	sys_rt_sigqueueinfo
+	PTR	sys_rt_sigsuspend
+	PTR	sys_sigaltstack
+	PTR	sys_utime			/* 5130 */
+	PTR	sys_mknod
+	PTR	sys_personality
+	PTR	sys_ustat
+	PTR	sys_statfs
+	PTR	sys_fstatfs			/* 5135 */
+	PTR	sys_sysfs
+	PTR	sys_getpriority
+	PTR	sys_setpriority
+	PTR	sys_sched_setparam
+	PTR	sys_sched_getparam		/* 5140 */
+	PTR	sys_sched_setscheduler
+	PTR	sys_sched_getscheduler
+	PTR	sys_sched_get_priority_max
+	PTR	sys_sched_get_priority_min
+	PTR	sys_sched_rr_get_interval	/* 5145 */
+	PTR	sys_mlock
+	PTR	sys_munlock
+	PTR	sys_mlockall
+	PTR	sys_munlockall
+	PTR	sys_vhangup			/* 5150 */
+	PTR	sys_pivot_root
+	PTR	sys_sysctl
+	PTR	sys_prctl
+	PTR	sys_adjtimex
+	PTR	sys_setrlimit			/* 5155 */
+	PTR	sys_chroot
+	PTR	sys_sync
+	PTR	sys_acct
+	PTR	sys_settimeofday
+	PTR	sys_mount			/* 5160 */
+	PTR	sys_umount
+	PTR	sys_swapon
+	PTR	sys_swapoff
+	PTR	sys_reboot
+	PTR	sys_sethostname			/* 5165 */
+	PTR	sys_setdomainname
+	PTR	sys_ni_syscall			/* was create_module */
+	PTR	sys_init_module
+	PTR	sys_delete_module
+	PTR	sys_ni_syscall			/* 5170, was get_kernel_syms */
+	PTR	sys_ni_syscall			/* was query_module */
+	PTR	sys_quotactl
+	PTR	sys_nfsservctl
+	PTR	sys_ni_syscall			/* res. for getpmsg */
+	PTR	sys_ni_syscall			/* 5175  for putpmsg */
+	PTR	sys_ni_syscall			/* res. for afs_syscall */
+	PTR	sys_ni_syscall			/* res. for security */
+	PTR	sys_gettid
+	PTR	sys_readahead
+	PTR	sys_setxattr			/* 5180 */
+	PTR	sys_lsetxattr
+	PTR	sys_fsetxattr
+	PTR	sys_getxattr
+	PTR	sys_lgetxattr
+	PTR	sys_fgetxattr			/* 5185 */
+	PTR	sys_listxattr
+	PTR	sys_llistxattr
+	PTR	sys_flistxattr
+	PTR	sys_removexattr
+	PTR	sys_lremovexattr		/* 5190 */
+	PTR	sys_fremovexattr
+	PTR	sys_tkill
+	PTR	sys_ni_syscall
+	PTR	sys_futex
+	PTR	sys_sched_setaffinity		/* 5195 */
+	PTR	sys_sched_getaffinity
+	PTR	sys_cacheflush
+	PTR	sys_cachectl
+	PTR	sys_sysmips
+	PTR	sys_io_setup			/* 5200 */
+	PTR	sys_io_destroy
+	PTR	sys_io_getevents
+	PTR	sys_io_submit
+	PTR	sys_io_cancel
+	PTR	sys_exit_group			/* 5205 */
+	PTR	sys_lookup_dcookie
+	PTR	sys_epoll_create
+	PTR	sys_epoll_ctl
+	PTR	sys_epoll_wait
+	PTR	sys_remap_file_pages		/* 5210 */
+	PTR	sys_rt_sigreturn
+	PTR	sys_set_tid_address
+	PTR	sys_restart_syscall
+	PTR	sys_semtimedop
+	PTR	sys_fadvise64_64		/* 5215 */
+	PTR	sys_timer_create
+	PTR	sys_timer_settime
+	PTR	sys_timer_gettime
+	PTR	sys_timer_getoverrun
+	PTR	sys_timer_delete		/* 5220 */
+	PTR	sys_clock_settime
+	PTR	sys_clock_gettime
+	PTR	sys_clock_getres
+	PTR	sys_clock_nanosleep
+	PTR	sys_tgkill			/* 5225 */
+	PTR	sys_utimes
+	PTR	sys_mbind
+	PTR	sys_ni_syscall			/* sys_get_mempolicy */
+	PTR	sys_ni_syscall			/* sys_set_mempolicy */
+	PTR	sys_mq_open			/* 5230 */
+	PTR	sys_mq_unlink
+	PTR	sys_mq_timedsend
+	PTR	sys_mq_timedreceive
+	PTR	sys_mq_notify
+	PTR	sys_mq_getsetattr		/* 5235 */
+	PTR	sys_ni_syscall			/* sys_vserver */
+	PTR	sys_waitid
+	PTR	sys_ni_syscall			/* available, was setaltroot */
+	PTR	sys_add_key
+	PTR	sys_request_key			/* 5240 */
+	PTR	sys_keyctl
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
new file mode 100644
index 0000000..e52049c
--- /dev/null
+++ b/arch/mips/kernel/scall64-n32.S
@@ -0,0 +1,365 @@
+/*
+ * 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, 96, 97, 98, 99, 2000, 01 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <asm/asm.h>
+#include <asm/asmmacro.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/thread_info.h>
+#include <asm/unistd.h>
+
+/* This duplicates the definition from <linux/sched.h> */
+#define PT_TRACESYS	0x00000002	/* tracing system calls */
+
+/* This duplicates the definition from <asm/signal.h> */
+#define SIGILL		4		/* Illegal instruction (ANSI).  */
+
+#ifndef CONFIG_MIPS32_O32
+/* No O32, so define handle_sys here */
+#define handle_sysn32 handle_sys
+#endif
+
+	.align  5
+NESTED(handle_sysn32, PT_SIZE, sp)
+#ifndef CONFIG_MIPS32_O32
+	.set	noat
+	SAVE_SOME
+	STI
+	.set	at
+#endif
+
+	dsubu	t0, v0, __NR_N32_Linux	# check syscall number
+	sltiu	t0, t0,	__NR_N32_Linux_syscalls + 1
+
+#ifndef CONFIG_MIPS32_O32
+	ld	t1, PT_EPC(sp)		# skip syscall on return
+	daddiu	t1, 4			# skip to next instruction
+	sd	t1, PT_EPC(sp)
+#endif
+	beqz	t0, not_n32_scall
+
+	dsll	t0, v0, 3		# offset into table
+	ld	t2, (sysn32_call_table - (__NR_N32_Linux * 8))(t0)
+
+	sd	a3, PT_R26(sp)		# save a3 for syscall restarting
+
+	li	t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+	LONG_L	t0, TI_FLAGS($28)	# syscall tracing enabled?
+	and	t0, t1, t0
+	bnez	t0, n32_syscall_trace_entry
+
+	jalr	t2			# Do The Real Thing (TM)
+
+	li	t0, -EMAXERRNO - 1	# error?
+	sltu	t0, t0, v0
+	sd	t0, PT_R7(sp)		# set error flag
+	beqz	t0, 1f
+
+	dnegu	v0			# error
+	sd	v0, PT_R0(sp)		# set flag for syscall restarting
+1:	sd	v0, PT_R2(sp)		# result
+
+	local_irq_disable		# make sure need_resched and
+					# signals dont change between
+					# sampling and return
+	LONG_L  a2, TI_FLAGS($28)	# current->work
+	li	t0, _TIF_ALLWORK_MASK
+	and	t0, a2, t0
+	bnez	t0, n32_syscall_exit_work
+
+	j	restore_partial
+
+n32_syscall_exit_work:
+	j	syscall_exit_work_partial
+
+/* ------------------------------------------------------------------------ */
+
+n32_syscall_trace_entry:
+	SAVE_STATIC
+	move	s0, t2
+	move	a0, sp
+	li	a1, 0
+	jal	do_syscall_trace
+
+	ld	a0, PT_R4(sp)		# Restore argument registers
+	ld	a1, PT_R5(sp)
+	ld	a2, PT_R6(sp)
+	ld	a3, PT_R7(sp)
+	ld	a4, PT_R8(sp)
+	ld	a5, PT_R9(sp)
+	jalr	s0
+
+	li	t0, -EMAXERRNO - 1	# error?
+	sltu	t0, t0, v0
+	sd	t0, PT_R7(sp)		# set error flag
+	beqz	t0, 1f
+
+	dnegu	v0			# error
+	sd	v0, PT_R0(sp)		# set flag for syscall restarting
+1:	sd	v0, PT_R2(sp)		# result
+
+	j	syscall_exit
+
+not_n32_scall:
+	/* This is not an n32 compatibility syscall, pass it on to
+	   the n64 syscall handlers.  */
+	j	handle_sys64
+
+	END(handle_sysn32)
+
+EXPORT(sysn32_call_table)
+	PTR	sys_read			/* 6000 */
+	PTR	sys_write
+	PTR	sys_open
+	PTR	sys_close
+	PTR	sys_newstat
+	PTR	sys_newfstat			/* 6005 */
+	PTR	sys_newlstat
+	PTR	sys_poll
+	PTR	sys_lseek
+	PTR	old_mmap
+	PTR	sys_mprotect			/* 6010 */
+	PTR	sys_munmap
+	PTR	sys_brk
+	PTR	sys32_rt_sigaction
+	PTR	sys32_rt_sigprocmask
+	PTR	compat_sys_ioctl		/* 6015 */
+	PTR	sys_pread64
+	PTR	sys_pwrite64
+	PTR	compat_sys_readv
+	PTR	compat_sys_writev
+	PTR	sys_access			/* 6020 */
+	PTR	sys_pipe
+	PTR	compat_sys_select
+	PTR	sys_sched_yield
+	PTR	sys_mremap
+	PTR	sys_msync			/* 6025 */
+	PTR	sys_mincore
+	PTR	sys_madvise
+	PTR	sys_shmget
+	PTR	sys32_shmat
+	PTR	sys_shmctl			/* 6030 */
+	PTR	sys_dup
+	PTR	sys_dup2
+	PTR	sys_pause
+	PTR	compat_sys_nanosleep
+	PTR	compat_sys_getitimer		/* 6035 */
+	PTR	compat_sys_setitimer
+	PTR	sys_alarm
+	PTR	sys_getpid
+	PTR	sys32_sendfile
+	PTR	sys_socket			/* 6040 */
+	PTR	sys_connect
+	PTR	sys_accept
+	PTR	sys_sendto
+	PTR	sys_recvfrom
+	PTR	compat_sys_sendmsg		/* 6045 */
+	PTR	compat_sys_recvmsg
+	PTR	sys_shutdown
+	PTR	sys_bind
+	PTR	sys_listen
+	PTR	sys_getsockname			/* 6050 */
+	PTR	sys_getpeername
+	PTR	sys_socketpair
+	PTR	compat_sys_setsockopt
+	PTR	sys_getsockopt
+	PTR	sys_clone			/* 6055 */
+	PTR	sys_fork
+	PTR	sys32_execve
+	PTR	sys_exit
+	PTR	sys32_wait4
+	PTR	sys_kill			/* 6060 */
+	PTR	sys32_newuname
+	PTR	sys_semget
+	PTR	sys_semop
+	PTR	sys_semctl
+	PTR	sys_shmdt			/* 6065 */
+	PTR	sys_msgget
+	PTR	sys_msgsnd
+	PTR	sys_msgrcv
+	PTR	sys_msgctl
+	PTR	compat_sys_fcntl		/* 6070 */
+	PTR	sys_flock
+	PTR	sys_fsync
+	PTR	sys_fdatasync
+	PTR	sys_truncate
+	PTR	sys_ftruncate			/* 6075 */
+	PTR	sys32_getdents
+	PTR	sys_getcwd
+	PTR	sys_chdir
+	PTR	sys_fchdir
+	PTR	sys_rename			/* 6080 */
+	PTR	sys_mkdir
+	PTR	sys_rmdir
+	PTR	sys_creat
+	PTR	sys_link
+	PTR	sys_unlink			/* 6085 */
+	PTR	sys_symlink
+	PTR	sys_readlink
+	PTR	sys_chmod
+	PTR	sys_fchmod
+	PTR	sys_chown			/* 6090 */
+	PTR	sys_fchown
+	PTR	sys_lchown
+	PTR	sys_umask
+	PTR	sys32_gettimeofday
+	PTR	compat_sys_getrlimit		/* 6095 */
+	PTR	compat_sys_getrusage
+	PTR	sys32_sysinfo
+	PTR	compat_sys_times
+	PTR	sys_ptrace
+	PTR	sys_getuid			/* 6100 */
+	PTR	sys_syslog
+	PTR	sys_getgid
+	PTR	sys_setuid
+	PTR	sys_setgid
+	PTR	sys_geteuid			/* 6105 */
+	PTR	sys_getegid
+	PTR	sys_setpgid
+	PTR	sys_getppid
+	PTR	sys_getpgrp
+	PTR	sys_setsid			/* 6110 */
+	PTR	sys_setreuid
+	PTR	sys_setregid
+	PTR	sys_getgroups
+	PTR	sys_setgroups
+	PTR	sys_setresuid			/* 6115 */
+	PTR	sys_getresuid
+	PTR	sys_setresgid
+	PTR	sys_getresgid
+	PTR	sys_getpgid
+	PTR	sys_setfsuid			/* 6120 */
+	PTR	sys_setfsgid
+	PTR	sys_getsid
+	PTR	sys_capget
+	PTR	sys_capset
+	PTR	sys32_rt_sigpending		/* 6125 */
+	PTR	compat_sys_rt_sigtimedwait
+	PTR	sys32_rt_sigqueueinfo
+	PTR	sys32_rt_sigsuspend
+	PTR	sys32_sigaltstack
+	PTR	compat_sys_utime		/* 6130 */
+	PTR	sys_mknod
+	PTR	sys32_personality
+	PTR	sys_ustat
+	PTR	compat_sys_statfs
+	PTR	compat_sys_fstatfs		/* 6135 */
+	PTR	sys_sysfs
+	PTR	sys_getpriority
+	PTR	sys_setpriority
+	PTR	sys_sched_setparam
+	PTR	sys_sched_getparam		/* 6140 */
+	PTR	sys_sched_setscheduler
+	PTR	sys_sched_getscheduler
+	PTR	sys_sched_get_priority_max
+	PTR	sys_sched_get_priority_min
+	PTR	sys32_sched_rr_get_interval	/* 6145 */
+	PTR	sys_mlock
+	PTR	sys_munlock
+	PTR	sys_mlockall
+	PTR	sys_munlockall
+	PTR	sys_vhangup			/* 6150 */
+	PTR	sys_pivot_root
+	PTR	sys32_sysctl
+	PTR	sys_prctl
+	PTR	sys32_adjtimex
+	PTR	compat_sys_setrlimit		/* 6155 */
+	PTR	sys_chroot
+	PTR	sys_sync
+	PTR	sys_acct
+	PTR	sys32_settimeofday
+	PTR	sys_mount			/* 6160 */
+	PTR	sys_umount
+	PTR	sys_swapon
+	PTR	sys_swapoff
+	PTR	sys_reboot
+	PTR	sys_sethostname			/* 6165 */
+	PTR	sys_setdomainname
+	PTR	sys_ni_syscall			/* was create_module */
+	PTR	sys_init_module
+	PTR	sys_delete_module
+	PTR	sys_ni_syscall			/* 6170, was get_kernel_syms */
+	PTR	sys_ni_syscall			/* was query_module */
+	PTR	sys_quotactl
+	PTR	sys_nfsservctl
+	PTR	sys_ni_syscall			/* res. for getpmsg */
+	PTR	sys_ni_syscall			/* 6175  for putpmsg */
+	PTR	sys_ni_syscall			/* res. for afs_syscall */
+	PTR	sys_ni_syscall			/* res. for security */
+	PTR	sys_gettid
+	PTR	sys32_readahead
+	PTR	sys_setxattr			/* 6180 */
+	PTR	sys_lsetxattr
+	PTR	sys_fsetxattr
+	PTR	sys_getxattr
+	PTR	sys_lgetxattr
+	PTR	sys_fgetxattr			/* 6185 */
+	PTR	sys_listxattr
+	PTR	sys_llistxattr
+	PTR	sys_flistxattr
+	PTR	sys_removexattr
+	PTR	sys_lremovexattr		/* 6190 */
+	PTR	sys_fremovexattr
+	PTR	sys_tkill
+	PTR	sys_ni_syscall
+	PTR	compat_sys_futex
+	PTR	compat_sys_sched_setaffinity	/* 6195 */
+	PTR	compat_sys_sched_getaffinity
+	PTR	sys_cacheflush
+	PTR	sys_cachectl
+	PTR	sys_sysmips
+	PTR	sys_io_setup			/* 6200 */
+	PTR	sys_io_destroy
+	PTR	sys_io_getevents
+	PTR	sys_io_submit
+	PTR	sys_io_cancel
+	PTR	sys_exit_group			/* 6205 */
+	PTR	sys_lookup_dcookie
+	PTR	sys_epoll_create
+	PTR	sys_epoll_ctl
+	PTR	sys_epoll_wait
+	PTR	sys_remap_file_pages		/* 6210 */
+	PTR	sysn32_rt_sigreturn
+	PTR	sys_fcntl
+	PTR	sys_set_tid_address
+	PTR	sys_restart_syscall
+	PTR	sys_semtimedop			/* 6215 */
+	PTR	sys_fadvise64_64
+	PTR	compat_sys_statfs64
+	PTR	compat_sys_fstatfs64
+	PTR	sys_sendfile64
+	PTR	sys_timer_create		/* 6220 */
+	PTR	sys_timer_settime
+	PTR	sys_timer_gettime
+	PTR	sys_timer_getoverrun
+	PTR	sys_timer_delete
+	PTR	sys_clock_settime		/* 6225 */
+	PTR	sys_clock_gettime
+	PTR	sys_clock_getres
+	PTR	sys_clock_nanosleep
+	PTR	sys_tgkill
+	PTR	compat_sys_utimes		/* 6230 */
+	PTR	sys_ni_syscall			/* sys_mbind */
+	PTR	sys_ni_syscall			/* sys_get_mempolicy */
+	PTR	sys_ni_syscall			/* sys_set_mempolicy */
+	PTR	compat_sys_mq_open
+	PTR	sys_mq_unlink			/* 6235 */
+	PTR	compat_sys_mq_timedsend
+	PTR	compat_sys_mq_timedreceive
+	PTR	compat_sys_mq_notify
+	PTR	compat_sys_mq_getsetattr
+	PTR	sys_ni_syscall			/* 6240, sys_vserver */
+	PTR	sys_waitid
+	PTR	sys_ni_syscall			/* available, was setaltroot */
+	PTR	sys_add_key
+	PTR	sys_request_key
+	PTR	sys_keyctl			/* 6245 */
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
new file mode 100644
index 0000000..739f399
--- /dev/null
+++ b/arch/mips/kernel/scall64-o32.S
@@ -0,0 +1,488 @@
+/*
+ * 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 - 2000, 2001 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ * Copyright (C) 2004 Thiemo Seufer
+ *
+ * Hairy, the userspace application uses a different argument passing
+ * convention than the kernel, so we have to translate things from o32
+ * to ABI64 calling convention.  64-bit syscalls are also processed
+ * here for now.
+ */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <asm/asm.h>
+#include <asm/asmmacro.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/thread_info.h>
+#include <asm/unistd.h>
+#include <asm/sysmips.h>
+
+	.align  5
+NESTED(handle_sys, PT_SIZE, sp)
+	.set	noat
+	SAVE_SOME
+	STI
+	.set	at
+	ld	t1, PT_EPC(sp)		# skip syscall on return
+
+	dsubu	t0, v0, __NR_O32_Linux	# check syscall number
+	sltiu	t0, t0, __NR_O32_Linux_syscalls + 1
+	daddiu	t1, 4			# skip to next instruction
+	sd	t1, PT_EPC(sp)
+	beqz	t0, not_o32_scall
+#if 0
+ SAVE_ALL
+ move a1, v0
+ PRINT("Scall %ld\n")
+ RESTORE_ALL
+#endif
+
+	/* We don't want to stumble over broken sign extensions from
+	   userland. O32 does never use the upper half. */
+	sll	a0, a0, 0
+	sll	a1, a1, 0
+	sll	a2, a2, 0
+	sll	a3, a3, 0
+
+	dsll	t0, v0, 3		# offset into table
+	ld	t2, (sys_call_table - (__NR_O32_Linux * 8))(t0)
+
+	sd	a3, PT_R26(sp)		# save a3 for syscall restarting
+
+	/*
+	 * More than four arguments.  Try to deal with it by copying the
+	 * stack arguments from the user stack to the kernel stack.
+	 * This Sucks (TM).
+	 *
+	 * We intentionally keep the kernel stack a little below the top of
+	 * userspace so we don't have to do a slower byte accurate check here.
+	 */
+	ld	t0, PT_R29(sp)		# get old user stack pointer
+	daddu	t1, t0, 32
+	bltz	t1, bad_stack
+
+1:	lw	a4, 16(t0)		# argument #5 from usp
+2:	lw	a5, 20(t0)		# argument #6 from usp
+3:	lw	a6, 24(t0)		# argument #7 from usp
+4:	lw	a7, 28(t0)		# argument #8 from usp (for indirect syscalls)
+
+	.section __ex_table,"a"
+	PTR	1b, bad_stack
+	PTR	2b, bad_stack
+	PTR	3b, bad_stack
+	PTR	4b, bad_stack
+	.previous
+
+	li	t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+	LONG_L	t0, TI_FLAGS($28)	# syscall tracing enabled?
+	and	t0, t1, t0
+	bnez	t0, trace_a_syscall
+
+	jalr	t2			# Do The Real Thing (TM)
+
+	li	t0, -EMAXERRNO - 1	# error?
+	sltu	t0, t0, v0
+	sd	t0, PT_R7(sp)		# set error flag
+	beqz	t0, 1f
+
+	dnegu	v0			# error
+	sd	v0, PT_R0(sp)		# flag for syscall restarting
+1:	sd	v0, PT_R2(sp)		# result
+
+o32_syscall_exit:
+	local_irq_disable		# make need_resched and
+					# signals dont change between
+					# sampling and return
+	LONG_L	a2, TI_FLAGS($28)
+	li	t0, _TIF_ALLWORK_MASK
+	and	t0, a2, t0
+	bnez	t0, o32_syscall_exit_work
+
+	j	restore_partial
+
+o32_syscall_exit_work:
+	j	syscall_exit_work_partial
+
+/* ------------------------------------------------------------------------ */
+
+trace_a_syscall:
+	SAVE_STATIC
+	sd	a4, PT_R8(sp)		# Save argument registers
+	sd	a5, PT_R9(sp)
+	sd	a6, PT_R10(sp)
+	sd	a7, PT_R11(sp)		# For indirect syscalls
+
+	move	s0, t2			# Save syscall pointer
+	move	a0, sp
+	li	a1, 0
+	jal	do_syscall_trace
+
+	ld	a0, PT_R4(sp)		# Restore argument registers
+	ld	a1, PT_R5(sp)
+	ld	a2, PT_R6(sp)
+	ld	a3, PT_R7(sp)
+	ld	a4, PT_R8(sp)
+	ld	a5, PT_R9(sp)
+	ld	a6, PT_R10(sp)
+	ld	a7, PT_R11(sp)		# For indirect syscalls
+	jalr	s0
+
+	li	t0, -EMAXERRNO - 1	# error?
+	sltu	t0, t0, v0
+	sd	t0, PT_R7(sp)		# set error flag
+	beqz	t0, 1f
+
+	dnegu	v0			# error
+	sd	v0, PT_R0(sp)		# set flag for syscall restarting
+1:	sd	v0, PT_R2(sp)		# result
+
+	j	syscall_exit
+
+/* ------------------------------------------------------------------------ */
+
+	/*
+	 * The stackpointer for a call with more than 4 arguments is bad.
+	 */
+bad_stack:
+	dnegu	v0			# error
+	sd	v0, PT_R0(sp)
+	sd	v0, PT_R2(sp)
+	li	t0, 1			# set error flag
+	sd	t0, PT_R7(sp)
+	j	o32_syscall_exit
+
+not_o32_scall:
+	/*
+	 * This is not an o32 compatibility syscall, pass it on
+	 * to the 64-bit syscall handlers.
+	 */
+#ifdef CONFIG_MIPS32_N32
+	j	handle_sysn32
+#else
+	j	handle_sys64
+#endif
+	END(handle_sys)
+
+LEAF(sys32_syscall)
+	sltu	v0, a0, __NR_O32_Linux + __NR_O32_Linux_syscalls + 1
+	beqz	v0, einval
+
+	dsll	v0, a0, 3
+	ld	t2, (sys_call_table - (__NR_O32_Linux * 8))(v0)
+
+	li	v1, 4000		# indirect syscall number
+	beq	a0, v1, einval		# do not recurse
+
+	move	a0, a1			# shift argument registers
+	move	a1, a2
+	move	a2, a3
+	move	a3, a4
+	move	a4, a5
+	move	a5, a6
+	move	a6, a7
+	sd	a0, PT_R4(sp)		# ... and push back a0 - a3, some
+	sd	a1, PT_R5(sp)		# syscalls expect them there
+	sd	a2, PT_R6(sp)
+	sd	a3, PT_R7(sp)
+	sd	a3, PT_R26(sp)		# update a3 for syscall restarting
+	jr	t2
+	/* Unreached */
+
+einval:	li	v0, -EINVAL
+	jr	ra
+	END(sys32_syscall)
+
+	.align	3
+	.type	sys_call_table,@object
+sys_call_table:
+	PTR	sys32_syscall			/* 4000 */
+	PTR	sys_exit
+	PTR	sys_fork
+	PTR	sys_read
+	PTR	sys_write
+	PTR	sys_open			/* 4005 */
+	PTR	sys_close
+	PTR	sys_waitpid
+	PTR	sys_creat
+	PTR	sys_link
+	PTR	sys_unlink			/* 4010 */
+	PTR	sys32_execve
+	PTR	sys_chdir
+	PTR	compat_sys_time
+	PTR	sys_mknod
+	PTR	sys_chmod			/* 4015 */
+	PTR	sys_lchown
+	PTR	sys_ni_syscall
+	PTR	sys_ni_syscall			/* was sys_stat */
+	PTR	sys_lseek
+	PTR	sys_getpid			/* 4020 */
+	PTR	sys_mount
+	PTR	sys_oldumount
+	PTR	sys_setuid
+	PTR	sys_getuid
+	PTR	compat_sys_stime		/* 4025 */
+	PTR	sys32_ptrace
+	PTR	sys_alarm
+	PTR	sys_ni_syscall			/* was sys_fstat */
+	PTR	sys_pause
+	PTR	compat_sys_utime		/* 4030 */
+	PTR	sys_ni_syscall
+	PTR	sys_ni_syscall
+	PTR	sys_access
+	PTR	sys_nice
+	PTR	sys_ni_syscall			/* 4035 */
+	PTR	sys_sync
+	PTR	sys_kill
+	PTR	sys_rename
+	PTR	sys_mkdir
+	PTR	sys_rmdir			/* 4040 */
+	PTR	sys_dup
+	PTR	sys_pipe
+	PTR	compat_sys_times
+	PTR	sys_ni_syscall
+	PTR	sys_brk				/* 4045 */
+	PTR	sys_setgid
+	PTR	sys_getgid
+	PTR	sys_ni_syscall			/* was signal	2 */
+	PTR	sys_geteuid
+	PTR	sys_getegid			/* 4050 */
+	PTR	sys_acct
+	PTR	sys_umount
+	PTR	sys_ni_syscall
+	PTR	compat_sys_ioctl
+	PTR	compat_sys_fcntl		/* 4055 */
+	PTR	sys_ni_syscall
+	PTR	sys_setpgid
+	PTR	sys_ni_syscall
+	PTR	sys_olduname
+	PTR	sys_umask			/* 4060 */
+	PTR	sys_chroot
+	PTR	sys32_ustat
+	PTR	sys_dup2
+	PTR	sys_getppid
+	PTR	sys_getpgrp			/* 4065 */
+	PTR	sys_setsid
+	PTR	sys32_sigaction
+	PTR	sys_sgetmask
+	PTR	sys_ssetmask
+	PTR	sys_setreuid			/* 4070 */
+	PTR	sys_setregid
+	PTR	sys32_sigsuspend
+	PTR	compat_sys_sigpending
+	PTR	sys_sethostname
+	PTR	compat_sys_setrlimit		/* 4075 */
+	PTR	compat_sys_getrlimit
+	PTR	compat_sys_getrusage
+	PTR	sys32_gettimeofday
+	PTR	sys32_settimeofday
+	PTR	sys_getgroups			/* 4080 */
+	PTR	sys_setgroups
+	PTR	sys_ni_syscall			/* old_select */
+	PTR	sys_symlink
+	PTR	sys_ni_syscall			/* was sys_lstat */
+	PTR	sys_readlink			/* 4085 */
+	PTR	sys_uselib
+	PTR	sys_swapon
+	PTR	sys_reboot
+	PTR	sys32_readdir
+	PTR	old_mmap			/* 4090 */
+	PTR	sys_munmap
+	PTR	sys_truncate
+	PTR	sys_ftruncate
+	PTR	sys_fchmod
+	PTR	sys_fchown			/* 4095 */
+	PTR	sys_getpriority
+	PTR	sys_setpriority
+	PTR	sys_ni_syscall
+	PTR	compat_sys_statfs
+	PTR	compat_sys_fstatfs		/* 4100 */
+	PTR	sys_ni_syscall			/* sys_ioperm */
+	PTR	sys32_socketcall
+	PTR	sys_syslog
+	PTR	compat_sys_setitimer
+	PTR	compat_sys_getitimer		/* 4105 */
+	PTR	compat_sys_newstat
+	PTR	compat_sys_newlstat
+	PTR	compat_sys_newfstat
+	PTR	sys_uname
+	PTR	sys_ni_syscall			/* sys_ioperm  *//* 4110 */
+	PTR	sys_vhangup
+	PTR	sys_ni_syscall			/* was sys_idle	 */
+	PTR	sys_ni_syscall			/* sys_vm86 */
+	PTR	sys32_wait4
+	PTR	sys_swapoff			/* 4115 */
+	PTR	sys32_sysinfo
+	PTR	sys32_ipc
+	PTR	sys_fsync
+	PTR	sys32_sigreturn
+	PTR	sys_clone			/* 4120 */
+	PTR	sys_setdomainname
+	PTR	sys32_newuname
+	PTR	sys_ni_syscall			/* sys_modify_ldt */
+	PTR	sys32_adjtimex
+	PTR	sys_mprotect			/* 4125 */
+	PTR	compat_sys_sigprocmask
+	PTR	sys_ni_syscall			/* was creat_module */
+	PTR	sys_init_module
+	PTR	sys_delete_module
+	PTR	sys_ni_syscall			/* 4130, get_kernel_syms */
+	PTR	sys_quotactl
+	PTR	sys_getpgid
+	PTR	sys_fchdir
+	PTR	sys_bdflush
+	PTR	sys_sysfs			/* 4135 */
+	PTR	sys32_personality
+	PTR	sys_ni_syscall	 		/* for afs_syscall */
+	PTR	sys_setfsuid
+	PTR	sys_setfsgid
+	PTR	sys32_llseek			/* 4140 */
+	PTR	sys32_getdents
+	PTR	compat_sys_select
+	PTR	sys_flock
+	PTR	sys_msync
+	PTR	compat_sys_readv		/* 4145 */
+	PTR	compat_sys_writev
+	PTR	sys_cacheflush
+	PTR	sys_cachectl
+	PTR	sys_sysmips
+	PTR	sys_ni_syscall			/* 4150 */
+	PTR	sys_getsid
+	PTR	sys_fdatasync
+	PTR	sys32_sysctl
+	PTR	sys_mlock
+	PTR	sys_munlock			/* 4155 */
+	PTR	sys_mlockall
+	PTR	sys_munlockall
+	PTR	sys_sched_setparam
+	PTR	sys_sched_getparam
+	PTR	sys_sched_setscheduler 		/* 4160 */
+	PTR	sys_sched_getscheduler
+	PTR	sys_sched_yield
+	PTR	sys_sched_get_priority_max
+	PTR	sys_sched_get_priority_min
+	PTR	sys32_sched_rr_get_interval 	/* 4165 */
+	PTR	compat_sys_nanosleep
+	PTR	sys_mremap
+	PTR	sys_accept
+	PTR	sys_bind
+	PTR	sys_connect			/* 4170 */
+	PTR	sys_getpeername
+	PTR	sys_getsockname
+	PTR	sys_getsockopt
+	PTR	sys_listen
+	PTR	sys_recv			/* 4175 */
+	PTR	sys_recvfrom
+	PTR	compat_sys_recvmsg
+	PTR	sys_send
+	PTR	compat_sys_sendmsg
+	PTR	sys_sendto			/* 4180 */
+	PTR	compat_sys_setsockopt
+	PTR	sys_shutdown
+	PTR	sys_socket
+	PTR	sys_socketpair
+	PTR	sys_setresuid			/* 4185 */
+	PTR	sys_getresuid
+	PTR	sys_ni_syscall			/* was query_module */
+	PTR	sys_poll
+	PTR	sys_nfsservctl
+	PTR	sys_setresgid			/* 4190 */
+	PTR	sys_getresgid
+	PTR	sys_prctl
+	PTR	sys32_rt_sigreturn
+	PTR	sys32_rt_sigaction
+	PTR	sys32_rt_sigprocmask 		/* 4195 */
+	PTR	sys32_rt_sigpending
+	PTR	compat_sys_rt_sigtimedwait
+	PTR	sys32_rt_sigqueueinfo
+	PTR	sys32_rt_sigsuspend
+	PTR	sys32_pread			/* 4200 */
+	PTR	sys32_pwrite
+	PTR	sys_chown
+	PTR	sys_getcwd
+	PTR	sys_capget
+	PTR	sys_capset			/* 4205 */
+	PTR	sys32_sigaltstack
+	PTR	sys32_sendfile
+	PTR	sys_ni_syscall
+	PTR	sys_ni_syscall
+	PTR	sys32_mmap2			/* 4210 */
+	PTR	sys32_truncate64
+	PTR	sys32_ftruncate64
+	PTR	sys_newstat
+	PTR	sys_newlstat
+	PTR	sys_newfstat			/* 4215 */
+	PTR	sys_pivot_root
+	PTR	sys_mincore
+	PTR	sys_madvise
+	PTR	sys_getdents64
+	PTR	compat_sys_fcntl64		/* 4220 */
+	PTR	sys_ni_syscall
+	PTR	sys_gettid
+	PTR	sys32_readahead
+	PTR	sys_setxattr
+	PTR	sys_lsetxattr			/* 4225 */
+	PTR	sys_fsetxattr
+	PTR	sys_getxattr
+	PTR	sys_lgetxattr
+	PTR	sys_fgetxattr
+	PTR	sys_listxattr			/* 4230 */
+	PTR	sys_llistxattr
+	PTR	sys_flistxattr
+	PTR	sys_removexattr
+	PTR	sys_lremovexattr
+	PTR	sys_fremovexattr		/* 4235 */
+	PTR	sys_tkill
+	PTR	sys_sendfile64
+	PTR	compat_sys_futex
+	PTR	compat_sys_sched_setaffinity
+	PTR	compat_sys_sched_getaffinity	/* 4240 */
+	PTR	sys_io_setup
+	PTR	sys_io_destroy
+	PTR	sys_io_getevents
+	PTR	sys_io_submit
+	PTR	sys_io_cancel			/* 4245 */
+	PTR	sys_exit_group
+	PTR	sys_lookup_dcookie
+	PTR	sys_epoll_create
+	PTR	sys_epoll_ctl
+	PTR	sys_epoll_wait			/* 4250 */
+	PTR	sys_remap_file_pages
+	PTR	sys_set_tid_address
+	PTR	sys_restart_syscall
+	PTR	sys_fadvise64_64
+	PTR	compat_sys_statfs64		/* 4255 */
+	PTR	compat_sys_fstatfs64
+	PTR	sys_timer_create
+	PTR	compat_sys_timer_settime
+	PTR	compat_sys_timer_gettime
+	PTR	sys_timer_getoverrun		/* 4260 */
+	PTR	sys_timer_delete
+	PTR	compat_sys_clock_settime
+	PTR	compat_sys_clock_gettime
+	PTR	compat_sys_clock_getres
+	PTR	compat_sys_clock_nanosleep	/* 4265 */
+	PTR	sys_tgkill
+	PTR	compat_sys_utimes
+	PTR	sys_ni_syscall			/* sys_mbind */
+	PTR	sys_ni_syscall			/* sys_get_mempolicy */
+	PTR	sys_ni_syscall			/* 4270 sys_set_mempolicy */
+	PTR	compat_sys_mq_open
+	PTR	sys_mq_unlink
+	PTR	compat_sys_mq_timedsend
+	PTR	compat_sys_mq_timedreceive
+	PTR	compat_sys_mq_notify		/* 4275 */
+	PTR	compat_sys_mq_getsetattr
+	PTR	sys_ni_syscall			/* sys_vserver */
+	PTR	sys_waitid
+	PTR	sys_ni_syscall			/* available, was setaltroot */
+	PTR	sys_add_key			/* 4280 */
+	PTR	sys_request_key
+	PTR	sys_keyctl
+	.size	sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/semaphore.c b/arch/mips/kernel/semaphore.c
new file mode 100644
index 0000000..9c40fe5
--- /dev/null
+++ b/arch/mips/kernel/semaphore.c
@@ -0,0 +1,164 @@
+/*
+ * MIPS-specific semaphore code.
+ *
+ * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
+ * Copyright (C) 2004 Ralf Baechle <ralf@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * April 2001 - Reworked by Paul Mackerras <paulus@samba.org>
+ * to eliminate the SMP races in the old version between the updates
+ * of `count' and `waking'.  Now we use negative `count' values to
+ * indicate that some process(es) are waiting for the semaphore.
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <asm/atomic.h>
+#include <asm/cpu-features.h>
+#include <asm/errno.h>
+#include <asm/semaphore.h>
+#include <asm/war.h>
+/*
+ * Atomically update sem->count.
+ * This does the equivalent of the following:
+ *
+ *	old_count = sem->count;
+ *	tmp = MAX(old_count, 0) + incr;
+ *	sem->count = tmp;
+ *	return old_count;
+ *
+ * On machines without lld/scd we need a spinlock to make the manipulation of
+ * sem->count and sem->waking atomic.  Scalability isn't an issue because
+ * this lock is used on UP only so it's just an empty variable.
+ */
+static inline int __sem_update_count(struct semaphore *sem, int incr)
+{
+	int old_count, tmp;
+
+	if (cpu_has_llsc && R10000_LLSC_WAR) {
+		__asm__ __volatile__(
+		"1:	ll	%0, %2					\n"
+		"	sra	%1, %0, 31				\n"
+		"	not	%1					\n"
+		"	and	%1, %0, %1				\n"
+		"	add	%1, %1, %3				\n"
+		"	sc	%1, %2					\n"
+		"	beqzl	%1, 1b					\n"
+		: "=&r" (old_count), "=&r" (tmp), "=m" (sem->count)
+		: "r" (incr), "m" (sem->count));
+	} else if (cpu_has_llsc) {
+		__asm__ __volatile__(
+		"1:	ll	%0, %2					\n"
+		"	sra	%1, %0, 31				\n"
+		"	not	%1					\n"
+		"	and	%1, %0, %1				\n"
+		"	add	%1, %1, %3				\n"
+		"	sc	%1, %2					\n"
+		"	beqz	%1, 1b					\n"
+		: "=&r" (old_count), "=&r" (tmp), "=m" (sem->count)
+		: "r" (incr), "m" (sem->count));
+	} else {
+		static DEFINE_SPINLOCK(semaphore_lock);
+		unsigned long flags;
+
+		spin_lock_irqsave(&semaphore_lock, flags);
+		old_count = atomic_read(&sem->count);
+		tmp = max_t(int, old_count, 0) + incr;
+		atomic_set(&sem->count, tmp);
+		spin_unlock_irqrestore(&semaphore_lock, flags);
+	}
+
+	return old_count;
+}
+
+void __up(struct semaphore *sem)
+{
+	/*
+	 * Note that we incremented count in up() before we came here,
+	 * but that was ineffective since the result was <= 0, and
+	 * any negative value of count is equivalent to 0.
+	 * This ends up setting count to 1, unless count is now > 0
+	 * (i.e. because some other cpu has called up() in the meantime),
+	 * in which case we just increment count.
+	 */
+	__sem_update_count(sem, 1);
+	wake_up(&sem->wait);
+}
+
+EXPORT_SYMBOL(__up);
+
+/*
+ * Note that when we come in to __down or __down_interruptible,
+ * we have already decremented count, but that decrement was
+ * ineffective since the result was < 0, and any negative value
+ * of count is equivalent to 0.
+ * Thus it is only when we decrement count from some value > 0
+ * that we have actually got the semaphore.
+ */
+void __sched __down(struct semaphore *sem)
+{
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+
+	__set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+	add_wait_queue_exclusive(&sem->wait, &wait);
+
+	/*
+	 * Try to get the semaphore.  If the count is > 0, then we've
+	 * got the semaphore; we decrement count and exit the loop.
+	 * If the count is 0 or negative, we set it to -1, indicating
+	 * that we are asleep, and then sleep.
+	 */
+	while (__sem_update_count(sem, -1) <= 0) {
+		schedule();
+		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+	}
+	remove_wait_queue(&sem->wait, &wait);
+	__set_task_state(tsk, TASK_RUNNING);
+
+	/*
+	 * If there are any more sleepers, wake one of them up so
+	 * that it can either get the semaphore, or set count to -1
+	 * indicating that there are still processes sleeping.
+	 */
+	wake_up(&sem->wait);
+}
+
+EXPORT_SYMBOL(__down);
+
+int __sched __down_interruptible(struct semaphore * sem)
+{
+	int retval = 0;
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+
+	__set_task_state(tsk, TASK_INTERRUPTIBLE);
+	add_wait_queue_exclusive(&sem->wait, &wait);
+
+	while (__sem_update_count(sem, -1) <= 0) {
+		if (signal_pending(current)) {
+			/*
+			 * A signal is pending - give up trying.
+			 * Set sem->count to 0 if it is negative,
+			 * since we are no longer sleeping.
+			 */
+			__sem_update_count(sem, 0);
+			retval = -EINTR;
+			break;
+		}
+		schedule();
+		set_task_state(tsk, TASK_INTERRUPTIBLE);
+	}
+	remove_wait_queue(&sem->wait, &wait);
+	__set_task_state(tsk, TASK_RUNNING);
+
+	wake_up(&sem->wait);
+	return retval;
+}
+
+EXPORT_SYMBOL(__down_interruptible);
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
new file mode 100644
index 0000000..6018ca2
--- /dev/null
+++ b/arch/mips/kernel/setup.c
@@ -0,0 +1,571 @@
+/*
+ * 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 Linus Torvalds
+ * Copyright (C) 1995 Waldorf Electronics
+ * Copyright (C) 1994, 95, 96, 97, 98, 99, 2000, 01, 02, 03  Ralf Baechle
+ * Copyright (C) 1996 Stoned Elipot
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 2000 2001, 2002  Maciej W. Rozycki
+ */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/stddef.h>
+#include <linux/string.h>
+#include <linux/unistd.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/utsname.h>
+#include <linux/a.out.h>
+#include <linux/tty.h>
+#include <linux/bootmem.h>
+#include <linux/initrd.h>
+#include <linux/major.h>
+#include <linux/kdev_t.h>
+#include <linux/root_dev.h>
+#include <linux/highmem.h>
+#include <linux/console.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/sections.h>
+#include <asm/setup.h>
+#include <asm/system.h>
+
+struct cpuinfo_mips cpu_data[NR_CPUS];
+
+EXPORT_SYMBOL(cpu_data);
+
+#ifdef CONFIG_VT
+struct screen_info screen_info;
+#endif
+
+/*
+ * Despite it's name this variable is even if we don't have PCI
+ */
+unsigned int PCI_DMA_BUS_IS_PHYS;
+
+EXPORT_SYMBOL(PCI_DMA_BUS_IS_PHYS);
+
+/*
+ * Setup information
+ *
+ * These are initialized so they are in the .data section
+ */
+unsigned long mips_machtype = MACH_UNKNOWN;
+unsigned long mips_machgroup = MACH_GROUP_UNKNOWN;
+
+EXPORT_SYMBOL(mips_machtype);
+EXPORT_SYMBOL(mips_machgroup);
+
+struct boot_mem_map boot_mem_map;
+
+static char command_line[CL_SIZE];
+       char arcs_cmdline[CL_SIZE]=CONFIG_CMDLINE;
+
+/*
+ * mips_io_port_base is the begin of the address space to which x86 style
+ * I/O ports are mapped.
+ */
+const unsigned long mips_io_port_base = -1;
+EXPORT_SYMBOL(mips_io_port_base);
+
+/*
+ * isa_slot_offset is the address where E(ISA) busaddress 0 is mapped
+ * for the processor.
+ */
+unsigned long isa_slot_offset;
+EXPORT_SYMBOL(isa_slot_offset);
+
+static struct resource code_resource = { .name = "Kernel code", };
+static struct resource data_resource = { .name = "Kernel data", };
+
+void __init add_memory_region(phys_t start, phys_t size, long type)
+{
+	int x = boot_mem_map.nr_map;
+	struct boot_mem_map_entry *prev = boot_mem_map.map + x - 1;
+
+	/*
+	 * Try to merge with previous entry if any.  This is far less than
+	 * perfect but is sufficient for most real world cases.
+	 */
+	if (x && prev->addr + prev->size == start && prev->type == type) {
+		prev->size += size;
+		return;
+	}
+
+	if (x == BOOT_MEM_MAP_MAX) {
+		printk("Ooops! Too many entries in the memory map!\n");
+		return;
+	}
+
+	boot_mem_map.map[x].addr = start;
+	boot_mem_map.map[x].size = size;
+	boot_mem_map.map[x].type = type;
+	boot_mem_map.nr_map++;
+}
+
+static void __init print_memory_map(void)
+{
+	int i;
+	const int field = 2 * sizeof(unsigned long);
+
+	for (i = 0; i < boot_mem_map.nr_map; i++) {
+		printk(" memory: %0*Lx @ %0*Lx ",
+		       field, (unsigned long long) boot_mem_map.map[i].size,
+		       field, (unsigned long long) boot_mem_map.map[i].addr);
+
+		switch (boot_mem_map.map[i].type) {
+		case BOOT_MEM_RAM:
+			printk("(usable)\n");
+			break;
+		case BOOT_MEM_ROM_DATA:
+			printk("(ROM data)\n");
+			break;
+		case BOOT_MEM_RESERVED:
+			printk("(reserved)\n");
+			break;
+		default:
+			printk("type %lu\n", boot_mem_map.map[i].type);
+			break;
+		}
+	}
+}
+
+static inline void parse_cmdline_early(void)
+{
+	char c = ' ', *to = command_line, *from = saved_command_line;
+	unsigned long start_at, mem_size;
+	int len = 0;
+	int usermem = 0;
+
+	printk("Determined physical RAM map:\n");
+	print_memory_map();
+
+	for (;;) {
+		/*
+		 * "mem=XXX[kKmM]" defines a memory region from
+		 * 0 to <XXX>, overriding the determined size.
+		 * "mem=XXX[KkmM]@YYY[KkmM]" defines a memory region from
+		 * <YYY> to <YYY>+<XXX>, overriding the determined size.
+		 */
+		if (c == ' ' && !memcmp(from, "mem=", 4)) {
+			if (to != command_line)
+				to--;
+			/*
+			 * If a user specifies memory size, we
+			 * blow away any automatically generated
+			 * size.
+			 */
+			if (usermem == 0) {
+				boot_mem_map.nr_map = 0;
+				usermem = 1;
+			}
+			mem_size = memparse(from + 4, &from);
+			if (*from == '@')
+				start_at = memparse(from + 1, &from);
+			else
+				start_at = 0;
+			add_memory_region(start_at, mem_size, BOOT_MEM_RAM);
+		}
+		c = *(from++);
+		if (!c)
+			break;
+		if (CL_SIZE <= ++len)
+			break;
+		*(to++) = c;
+	}
+	*to = '\0';
+
+	if (usermem) {
+		printk("User-defined physical RAM map:\n");
+		print_memory_map();
+	}
+}
+
+static inline int parse_rd_cmdline(unsigned long* rd_start, unsigned long* rd_end)
+{
+	/*
+	 * "rd_start=0xNNNNNNNN" defines the memory address of an initrd
+	 * "rd_size=0xNN" it's size
+	 */
+	unsigned long start = 0;
+	unsigned long size = 0;
+	unsigned long end;
+	char cmd_line[CL_SIZE];
+	char *start_str;
+	char *size_str;
+	char *tmp;
+
+	strcpy(cmd_line, command_line);
+	*command_line = 0;
+	tmp = cmd_line;
+	/* Ignore "rd_start=" strings in other parameters. */
+	start_str = strstr(cmd_line, "rd_start=");
+	if (start_str && start_str != cmd_line && *(start_str - 1) != ' ')
+		start_str = strstr(start_str, " rd_start=");
+	while (start_str) {
+		if (start_str != cmd_line)
+			strncat(command_line, tmp, start_str - tmp);
+		start = memparse(start_str + 9, &start_str);
+		tmp = start_str + 1;
+		start_str = strstr(start_str, " rd_start=");
+	}
+	if (*tmp)
+		strcat(command_line, tmp);
+
+	strcpy(cmd_line, command_line);
+	*command_line = 0;
+	tmp = cmd_line;
+	/* Ignore "rd_size" strings in other parameters. */
+	size_str = strstr(cmd_line, "rd_size=");
+	if (size_str && size_str != cmd_line && *(size_str - 1) != ' ')
+		size_str = strstr(size_str, " rd_size=");
+	while (size_str) {
+		if (size_str != cmd_line)
+			strncat(command_line, tmp, size_str - tmp);
+		size = memparse(size_str + 8, &size_str);
+		tmp = size_str + 1;
+		size_str = strstr(size_str, " rd_size=");
+	}
+	if (*tmp)
+		strcat(command_line, tmp);
+
+#ifdef CONFIG_MIPS64
+	/* HACK: Guess if the sign extension was forgotten */
+	if (start > 0x0000000080000000 && start < 0x00000000ffffffff)
+		start |= 0xffffffff00000000;
+#endif
+
+	end = start + size;
+	if (start && end) {
+		*rd_start = start;
+		*rd_end = end;
+		return 1;
+	}
+	return 0;
+}
+
+#define PFN_UP(x)	(((x) + PAGE_SIZE - 1) >> PAGE_SHIFT)
+#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
+#define PFN_PHYS(x)	((x) << PAGE_SHIFT)
+
+#define MAXMEM		HIGHMEM_START
+#define MAXMEM_PFN	PFN_DOWN(MAXMEM)
+
+static inline void bootmem_init(void)
+{
+	unsigned long start_pfn;
+	unsigned long reserved_end = (unsigned long)&_end;
+#ifndef CONFIG_SGI_IP27
+	unsigned long first_usable_pfn;
+	unsigned long bootmap_size;
+	int i;
+#endif
+#ifdef CONFIG_BLK_DEV_INITRD
+	int initrd_reserve_bootmem = 0;
+
+	/* Board specific code should have set up initrd_start and initrd_end */
+ 	ROOT_DEV = Root_RAM0;
+	if (parse_rd_cmdline(&initrd_start, &initrd_end)) {
+		reserved_end = max(reserved_end, initrd_end);
+		initrd_reserve_bootmem = 1;
+	} else {
+		unsigned long tmp;
+		u32 *initrd_header;
+
+		tmp = ((reserved_end + PAGE_SIZE-1) & PAGE_MASK) - sizeof(u32) * 2;
+		if (tmp < reserved_end)
+			tmp += PAGE_SIZE;
+		initrd_header = (u32 *)tmp;
+		if (initrd_header[0] == 0x494E5244) {
+			initrd_start = (unsigned long)&initrd_header[2];
+			initrd_end = initrd_start + initrd_header[1];
+			reserved_end = max(reserved_end, initrd_end);
+			initrd_reserve_bootmem = 1;
+		}
+	}
+#endif	/* CONFIG_BLK_DEV_INITRD */
+
+	/*
+	 * Partially used pages are not usable - thus
+	 * we are rounding upwards.
+	 */
+	start_pfn = PFN_UP(CPHYSADDR(reserved_end));
+
+#ifndef CONFIG_SGI_IP27
+	/* Find the highest page frame number we have available.  */
+	max_pfn = 0;
+	first_usable_pfn = -1UL;
+	for (i = 0; i < boot_mem_map.nr_map; i++) {
+		unsigned long start, end;
+
+		if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
+			continue;
+
+		start = PFN_UP(boot_mem_map.map[i].addr);
+		end = PFN_DOWN(boot_mem_map.map[i].addr
+		      + boot_mem_map.map[i].size);
+
+		if (start >= end)
+			continue;
+		if (end > max_pfn)
+			max_pfn = end;
+		if (start < first_usable_pfn) {
+			if (start > start_pfn) {
+				first_usable_pfn = start;
+			} else if (end > start_pfn) {
+				first_usable_pfn = start_pfn;
+			}
+		}
+	}
+
+	/*
+	 * Determine low and high memory ranges
+	 */
+	max_low_pfn = max_pfn;
+	if (max_low_pfn > MAXMEM_PFN) {
+		max_low_pfn = MAXMEM_PFN;
+#ifndef CONFIG_HIGHMEM
+		/* Maximum memory usable is what is directly addressable */
+		printk(KERN_WARNING "Warning only %ldMB will be used.\n",
+		       MAXMEM >> 20);
+		printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n");
+#endif
+	}
+
+#ifdef CONFIG_HIGHMEM
+	/*
+	 * Crude, we really should make a better attempt at detecting
+	 * highstart_pfn
+	 */
+	highstart_pfn = highend_pfn = max_pfn;
+	if (max_pfn > MAXMEM_PFN) {
+		highstart_pfn = MAXMEM_PFN;
+		printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
+		       (highend_pfn - highstart_pfn) >> (20 - PAGE_SHIFT));
+	}
+#endif
+
+	/* Initialize the boot-time allocator with low memory only.  */
+	bootmap_size = init_bootmem(first_usable_pfn, max_low_pfn);
+
+	/*
+	 * Register fully available low RAM pages with the bootmem allocator.
+	 */
+	for (i = 0; i < boot_mem_map.nr_map; i++) {
+		unsigned long curr_pfn, last_pfn, size;
+
+		/*
+		 * Reserve usable memory.
+		 */
+		if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
+			continue;
+
+		/*
+		 * We are rounding up the start address of usable memory:
+		 */
+		curr_pfn = PFN_UP(boot_mem_map.map[i].addr);
+		if (curr_pfn >= max_low_pfn)
+			continue;
+		if (curr_pfn < start_pfn)
+			curr_pfn = start_pfn;
+
+		/*
+		 * ... and at the end of the usable range downwards:
+		 */
+		last_pfn = PFN_DOWN(boot_mem_map.map[i].addr
+				    + boot_mem_map.map[i].size);
+
+		if (last_pfn > max_low_pfn)
+			last_pfn = max_low_pfn;
+
+		/*
+		 * Only register lowmem part of lowmem segment with bootmem.
+		 */
+		size = last_pfn - curr_pfn;
+		if (curr_pfn > PFN_DOWN(HIGHMEM_START))
+			continue;
+		if (curr_pfn + size - 1 > PFN_DOWN(HIGHMEM_START))
+			size = PFN_DOWN(HIGHMEM_START) - curr_pfn;
+		if (!size)
+			continue;
+
+		/*
+		 * ... finally, did all the rounding and playing
+		 * around just make the area go away?
+		 */
+		if (last_pfn <= curr_pfn)
+			continue;
+
+		/* Register lowmem ranges */
+		free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size));
+	}
+
+	/* Reserve the bootmap memory.  */
+	reserve_bootmem(PFN_PHYS(first_usable_pfn), bootmap_size);
+#endif /* CONFIG_SGI_IP27 */
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	initrd_below_start_ok = 1;
+	if (initrd_start) {
+		unsigned long initrd_size = ((unsigned char *)initrd_end) - ((unsigned char *)initrd_start);
+		printk("Initial ramdisk at: 0x%p (%lu bytes)\n",
+		       (void *)initrd_start, initrd_size);
+
+		if (CPHYSADDR(initrd_end) > PFN_PHYS(max_low_pfn)) {
+			printk("initrd extends beyond end of memory "
+			       "(0x%0*Lx > 0x%0*Lx)\ndisabling initrd\n",
+			       sizeof(long) * 2,
+			       (unsigned long long)CPHYSADDR(initrd_end),
+			       sizeof(long) * 2,
+			       (unsigned long long)PFN_PHYS(max_low_pfn));
+			initrd_start = initrd_end = 0;
+			initrd_reserve_bootmem = 0;
+		}
+
+		if (initrd_reserve_bootmem)
+			reserve_bootmem(CPHYSADDR(initrd_start), initrd_size);
+	}
+#endif /* CONFIG_BLK_DEV_INITRD  */
+}
+
+static inline void resource_init(void)
+{
+	int i;
+
+#if defined(CONFIG_MIPS64) && !defined(CONFIG_BUILD_ELF64)
+	/*
+	 * The 64bit code in 32bit object format trick can't represent
+	 * 64bit wide relocations for linker script symbols.
+	 */
+	code_resource.start = CPHYSADDR(&_text);
+	code_resource.end = CPHYSADDR(&_etext) - 1;
+	data_resource.start = CPHYSADDR(&_etext);
+	data_resource.end = CPHYSADDR(&_edata) - 1;
+#else
+	code_resource.start = virt_to_phys(&_text);
+	code_resource.end = virt_to_phys(&_etext) - 1;
+	data_resource.start = virt_to_phys(&_etext);
+	data_resource.end = virt_to_phys(&_edata) - 1;
+#endif
+
+	/*
+	 * Request address space for all standard RAM.
+	 */
+	for (i = 0; i < boot_mem_map.nr_map; i++) {
+		struct resource *res;
+		unsigned long start, end;
+
+		start = boot_mem_map.map[i].addr;
+		end = boot_mem_map.map[i].addr + boot_mem_map.map[i].size - 1;
+		if (start >= MAXMEM)
+			continue;
+		if (end >= MAXMEM)
+			end = MAXMEM - 1;
+
+		res = alloc_bootmem(sizeof(struct resource));
+		switch (boot_mem_map.map[i].type) {
+		case BOOT_MEM_RAM:
+		case BOOT_MEM_ROM_DATA:
+			res->name = "System RAM";
+			break;
+		case BOOT_MEM_RESERVED:
+		default:
+			res->name = "reserved";
+		}
+
+		res->start = start;
+		res->end = end;
+
+		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+		request_resource(&iomem_resource, res);
+
+		/*
+		 *  We don't know which RAM region contains kernel data,
+		 *  so we try it repeatedly and let the resource manager
+		 *  test it.
+		 */
+		request_resource(res, &code_resource);
+		request_resource(res, &data_resource);
+	}
+}
+
+#undef PFN_UP
+#undef PFN_DOWN
+#undef PFN_PHYS
+
+#undef MAXMEM
+#undef MAXMEM_PFN
+
+static int __initdata earlyinit_debug;
+
+static int __init earlyinit_debug_setup(char *str)
+{
+	earlyinit_debug = 1;
+	return 1;
+}
+__setup("earlyinit_debug", earlyinit_debug_setup);
+
+extern initcall_t __earlyinitcall_start, __earlyinitcall_end;
+
+static void __init do_earlyinitcalls(void)
+{
+	initcall_t *call, *start, *end;
+
+	start = &__earlyinitcall_start;
+	end = &__earlyinitcall_end;
+
+	for (call = start; call < end; call++) {
+		if (earlyinit_debug)
+			printk("calling earlyinitcall 0x%p\n", *call);
+
+		(*call)();
+	}
+}
+
+void __init setup_arch(char **cmdline_p)
+{
+	cpu_probe();
+	prom_init();
+	cpu_report();
+
+#if defined(CONFIG_VT)
+#if defined(CONFIG_VGA_CONSOLE)
+        conswitchp = &vga_con;
+#elif defined(CONFIG_DUMMY_CONSOLE)
+        conswitchp = &dummy_con;
+#endif
+#endif
+
+	/* call board setup routine */
+	do_earlyinitcalls();
+
+	strlcpy(command_line, arcs_cmdline, sizeof(command_line));
+	strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
+
+	*cmdline_p = command_line;
+
+	parse_cmdline_early();
+	bootmem_init();
+	paging_init();
+	resource_init();
+}
+
+int __init fpu_disable(char *s)
+{
+	cpu_data[0].options &= ~MIPS_CPU_FPU;
+
+	return 1;
+}
+
+__setup("nofpu", fpu_disable);
diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h
new file mode 100644
index 0000000..f9234df
--- /dev/null
+++ b/arch/mips/kernel/signal-common.h
@@ -0,0 +1,137 @@
+/*
+ * 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) 1991, 1992  Linus Torvalds
+ * Copyright (C) 1994 - 2000  Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+
+static inline int
+setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+{
+	int err = 0;
+
+	err |= __put_user(regs->cp0_epc, &sc->sc_pc);
+	err |= __put_user(regs->cp0_status, &sc->sc_status);
+
+#define save_gp_reg(i) do {						\
+	err |= __put_user(regs->regs[i], &sc->sc_regs[i]);		\
+} while(0)
+	__put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
+	save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
+	save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
+	save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
+	save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
+	save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
+	save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
+	save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
+	save_gp_reg(31);
+#undef save_gp_reg
+
+	err |= __put_user(regs->hi, &sc->sc_mdhi);
+	err |= __put_user(regs->lo, &sc->sc_mdlo);
+	err |= __put_user(regs->cp0_cause, &sc->sc_cause);
+	err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
+
+	err |= __put_user(!!used_math(), &sc->sc_used_math);
+
+	if (!used_math())
+		goto out;
+
+	/*
+	 * Save FPU state to signal context.  Signal handler will "inherit"
+	 * current FPU state.
+	 */
+	preempt_disable();
+
+	if (!is_fpu_owner()) {
+		own_fpu();
+		restore_fp(current);
+	}
+	err |= save_fp_context(sc);
+
+	preempt_enable();
+
+out:
+	return err;
+}
+
+static inline int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+{
+	int err = 0;
+	unsigned int used_math;
+
+	/* Always make any pending restarted system calls return -EINTR */
+	current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
+	err |= __get_user(regs->cp0_epc, &sc->sc_pc);
+	err |= __get_user(regs->hi, &sc->sc_mdhi);
+	err |= __get_user(regs->lo, &sc->sc_mdlo);
+
+#define restore_gp_reg(i) do {						\
+	err |= __get_user(regs->regs[i], &sc->sc_regs[i]);		\
+} while(0)
+	restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
+	restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
+	restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
+	restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
+	restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
+	restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
+	restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
+	restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
+	restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
+	restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
+	restore_gp_reg(31);
+#undef restore_gp_reg
+
+	err |= __get_user(used_math, &sc->sc_used_math);
+	conditional_used_math(used_math);
+
+	preempt_disable();
+
+	if (used_math()) {
+		/* restore fpu context if we have used it before */
+		own_fpu();
+		err |= restore_fp_context(sc);
+	} else {
+		/* signal handler may have used FPU.  Give it up. */
+		lose_fpu();
+	}
+
+	preempt_enable();
+
+	return err;
+}
+
+/*
+ * Determine which stack to use..
+ */
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+{
+	unsigned long sp, almask;
+
+	/* Default to using normal stack */
+	sp = regs->regs[29];
+
+	/*
+ 	 * FPU emulator may have it's own trampoline active just
+ 	 * above the user stack, 16-bytes before the next lowest
+ 	 * 16 byte boundary.  Try to avoid trashing it.
+ 	 */
+ 	sp -= 32;
+
+	/* This is the X/Open sanctioned signal stack switching.  */
+	if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
+		sp = current->sas_ss_sp + current->sas_ss_size;
+
+	if (PLAT_TRAMPOLINE_STUFF_LINE)
+		almask = ~(PLAT_TRAMPOLINE_STUFF_LINE - 1);
+	else
+		almask = ALMASK;
+
+	return (void *)((sp - frame_size) & almask);
+}
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
new file mode 100644
index 0000000..508026a
--- /dev/null
+++ b/arch/mips/kernel/signal.c
@@ -0,0 +1,517 @@
+/*
+ * 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) 1991, 1992  Linus Torvalds
+ * Copyright (C) 1994 - 2000  Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/personality.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/compiler.h>
+
+#include <asm/asm.h>
+#include <linux/bitops.h>
+#include <asm/cacheflush.h>
+#include <asm/fpu.h>
+#include <asm/sim.h>
+#include <asm/uaccess.h>
+#include <asm/ucontext.h>
+#include <asm/cpu-features.h>
+
+#include "signal-common.h"
+
+#define DEBUG_SIG 0
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+static int do_signal(sigset_t *oldset, struct pt_regs *regs);
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+
+#ifdef CONFIG_TRAD_SIGNALS
+save_static_function(sys_sigsuspend);
+__attribute_used__ noinline static int
+_sys_sigsuspend(nabi_no_regargs struct pt_regs regs)
+{
+	sigset_t *uset, saveset, newset;
+
+	uset = (sigset_t *) regs.regs[4];
+	if (copy_from_user(&newset, uset, sizeof(sigset_t)))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sighand->siglock);
+	saveset = current->blocked;
+	current->blocked = newset;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	regs.regs[2] = EINTR;
+	regs.regs[7] = 1;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, &regs))
+			return -EINTR;
+	}
+}
+#endif
+
+save_static_function(sys_rt_sigsuspend);
+__attribute_used__ noinline static int
+_sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
+{
+	sigset_t *unewset, saveset, newset;
+	size_t sigsetsize;
+
+	/* XXX Don't preclude handling different sized sigset_t's.  */
+	sigsetsize = regs.regs[5];
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	unewset = (sigset_t *) regs.regs[4];
+	if (copy_from_user(&newset, unewset, sizeof(newset)))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sighand->siglock);
+	saveset = current->blocked;
+	current->blocked = newset;
+        recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	regs.regs[2] = EINTR;
+	regs.regs[7] = 1;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, &regs))
+			return -EINTR;
+	}
+}
+
+#ifdef CONFIG_TRAD_SIGNALS
+asmlinkage int sys_sigaction(int sig, const struct sigaction *act,
+	struct sigaction *oact)
+{
+	struct k_sigaction new_ka, old_ka;
+	int ret;
+	int err = 0;
+
+	if (act) {
+		old_sigset_t mask;
+
+		if (!access_ok(VERIFY_READ, act, sizeof(*act)))
+			return -EFAULT;
+		err |= __get_user(new_ka.sa.sa_handler, &act->sa_handler);
+		err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
+		err |= __get_user(mask, &act->sa_mask.sig[0]);
+		if (err)
+			return -EFAULT;
+
+		siginitset(&new_ka.sa.sa_mask, mask);
+	}
+
+	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+	if (!ret && oact) {
+		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
+                        return -EFAULT;
+		err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+		err |= __put_user(old_ka.sa.sa_handler, &oact->sa_handler);
+		err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
+		err |= __put_user(0, &oact->sa_mask.sig[1]);
+		err |= __put_user(0, &oact->sa_mask.sig[2]);
+		err |= __put_user(0, &oact->sa_mask.sig[3]);
+		if (err)
+			return -EFAULT;
+	}
+
+	return ret;
+}
+#endif
+
+asmlinkage int sys_sigaltstack(nabi_no_regargs struct pt_regs regs)
+{
+	const stack_t *uss = (const stack_t *) regs.regs[4];
+	stack_t *uoss = (stack_t *) regs.regs[5];
+	unsigned long usp = regs.regs[29];
+
+	return do_sigaltstack(uss, uoss, usp);
+}
+
+#if PLAT_TRAMPOLINE_STUFF_LINE
+#define __tramp __attribute__((aligned(PLAT_TRAMPOLINE_STUFF_LINE)))
+#else
+#define __tramp
+#endif
+
+#ifdef CONFIG_TRAD_SIGNALS
+struct sigframe {
+	u32 sf_ass[4];			/* argument save space for o32 */
+	u32 sf_code[2] __tramp;		/* signal trampoline */
+	struct sigcontext sf_sc __tramp;
+	sigset_t sf_mask;
+};
+#endif
+
+struct rt_sigframe {
+	u32 rs_ass[4];			/* argument save space for o32 */
+	u32 rs_code[2] __tramp;		/* signal trampoline */
+	struct siginfo rs_info __tramp;
+	struct ucontext rs_uc;
+};
+
+#ifdef CONFIG_TRAD_SIGNALS
+save_static_function(sys_sigreturn);
+__attribute_used__ noinline static void
+_sys_sigreturn(nabi_no_regargs struct pt_regs regs)
+{
+	struct sigframe *frame;
+	sigset_t blocked;
+
+	frame = (struct sigframe *) regs.regs[29];
+	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked)))
+		goto badframe;
+
+	sigdelsetmask(&blocked, ~_BLOCKABLE);
+	spin_lock_irq(&current->sighand->siglock);
+	current->blocked = blocked;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	if (restore_sigcontext(&regs, &frame->sf_sc))
+		goto badframe;
+
+	/*
+	 * Don't let your children do this ...
+	 */
+	if (current_thread_info()->flags & TIF_SYSCALL_TRACE)
+		do_syscall_trace(&regs, 1);
+	__asm__ __volatile__(
+		"move\t$29, %0\n\t"
+		"j\tsyscall_exit"
+		:/* no outputs */
+		:"r" (&regs));
+	/* Unreached */
+
+badframe:
+	force_sig(SIGSEGV, current);
+}
+#endif
+
+save_static_function(sys_rt_sigreturn);
+__attribute_used__ noinline static void
+_sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
+{
+	struct rt_sigframe *frame;
+	sigset_t set;
+	stack_t st;
+
+	frame = (struct rt_sigframe *) regs.regs[29];
+	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sighand->siglock);
+	current->blocked = set;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	if (restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext))
+		goto badframe;
+
+	if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st)))
+		goto badframe;
+	/* It is more difficult to avoid calling this function than to
+	   call it and ignore errors.  */
+	do_sigaltstack(&st, NULL, regs.regs[29]);
+
+	/*
+	 * Don't let your children do this ...
+	 */
+	__asm__ __volatile__(
+		"move\t$29, %0\n\t"
+		"j\tsyscall_exit"
+		:/* no outputs */
+		:"r" (&regs));
+	/* Unreached */
+
+badframe:
+	force_sig(SIGSEGV, current);
+}
+
+#ifdef CONFIG_TRAD_SIGNALS
+static void inline setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
+	int signr, sigset_t *set)
+{
+	struct sigframe *frame;
+	int err = 0;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+		goto give_sigsegv;
+
+	/*
+	 * Set up the return code ...
+	 *
+	 *         li      v0, __NR_sigreturn
+	 *         syscall
+	 */
+	if (PLAT_TRAMPOLINE_STUFF_LINE)
+		__clear_user(frame->sf_code, PLAT_TRAMPOLINE_STUFF_LINE);
+	err |= __put_user(0x24020000 + __NR_sigreturn, frame->sf_code + 0);
+	err |= __put_user(0x0000000c                 , frame->sf_code + 1);
+	flush_cache_sigtramp((unsigned long) frame->sf_code);
+
+	err |= setup_sigcontext(regs, &frame->sf_sc);
+	err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
+	if (err)
+		goto give_sigsegv;
+
+	/*
+	 * Arguments to signal handler:
+	 *
+	 *   a0 = signal number
+	 *   a1 = 0 (should be cause)
+	 *   a2 = pointer to struct sigcontext
+	 *
+	 * $25 and c0_epc point to the signal handler, $29 points to the
+	 * struct sigframe.
+	 */
+	regs->regs[ 4] = signr;
+	regs->regs[ 5] = 0;
+	regs->regs[ 6] = (unsigned long) &frame->sf_sc;
+	regs->regs[29] = (unsigned long) frame;
+	regs->regs[31] = (unsigned long) frame->sf_code;
+	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
+
+#if DEBUG_SIG
+	printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
+	       current->comm, current->pid,
+	       frame, regs->cp0_epc, frame->regs[31]);
+#endif
+        return;
+
+give_sigsegv:
+	force_sigsegv(signr, current);
+}
+#endif
+
+static void inline setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
+	int signr, sigset_t *set, siginfo_t *info)
+{
+	struct rt_sigframe *frame;
+	int err = 0;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+		goto give_sigsegv;
+
+	/*
+	 * Set up the return code ...
+	 *
+	 *         li      v0, __NR_rt_sigreturn
+	 *         syscall
+	 */
+	if (PLAT_TRAMPOLINE_STUFF_LINE)
+		__clear_user(frame->rs_code, PLAT_TRAMPOLINE_STUFF_LINE);
+	err |= __put_user(0x24020000 + __NR_rt_sigreturn, frame->rs_code + 0);
+	err |= __put_user(0x0000000c                    , frame->rs_code + 1);
+	flush_cache_sigtramp((unsigned long) frame->rs_code);
+
+	/* Create siginfo.  */
+	err |= copy_siginfo_to_user(&frame->rs_info, info);
+
+	/* Create the ucontext.  */
+	err |= __put_user(0, &frame->rs_uc.uc_flags);
+	err |= __put_user(0, &frame->rs_uc.uc_link);
+	err |= __put_user((void *)current->sas_ss_sp,
+	                  &frame->rs_uc.uc_stack.ss_sp);
+	err |= __put_user(sas_ss_flags(regs->regs[29]),
+	                  &frame->rs_uc.uc_stack.ss_flags);
+	err |= __put_user(current->sas_ss_size,
+	                  &frame->rs_uc.uc_stack.ss_size);
+	err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext);
+	err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
+
+	if (err)
+		goto give_sigsegv;
+
+	/*
+	 * Arguments to signal handler:
+	 *
+	 *   a0 = signal number
+	 *   a1 = 0 (should be cause)
+	 *   a2 = pointer to ucontext
+	 *
+	 * $25 and c0_epc point to the signal handler, $29 points to
+	 * the struct rt_sigframe.
+	 */
+	regs->regs[ 4] = signr;
+	regs->regs[ 5] = (unsigned long) &frame->rs_info;
+	regs->regs[ 6] = (unsigned long) &frame->rs_uc;
+	regs->regs[29] = (unsigned long) frame;
+	regs->regs[31] = (unsigned long) frame->rs_code;
+	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
+
+#if DEBUG_SIG
+	printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
+	       current->comm, current->pid,
+	       frame, regs->cp0_epc, regs->regs[31]);
+#endif
+	return;
+
+give_sigsegv:
+	force_sigsegv(signr, current);
+}
+
+extern void setup_rt_frame_n32(struct k_sigaction * ka,
+	struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info);
+
+static inline void handle_signal(unsigned long sig, siginfo_t *info,
+	struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
+{
+	switch(regs->regs[0]) {
+	case ERESTART_RESTARTBLOCK:
+	case ERESTARTNOHAND:
+		regs->regs[2] = EINTR;
+		break;
+	case ERESTARTSYS:
+		if(!(ka->sa.sa_flags & SA_RESTART)) {
+			regs->regs[2] = EINTR;
+			break;
+		}
+	/* fallthrough */
+	case ERESTARTNOINTR:		/* Userland will reload $v0.  */
+		regs->regs[7] = regs->regs[26];
+		regs->cp0_epc -= 8;
+	}
+
+	regs->regs[0] = 0;		/* Don't deal with this again.  */
+
+#ifdef CONFIG_TRAD_SIGNALS
+	if (ka->sa.sa_flags & SA_SIGINFO) {
+#else
+	if (1) {
+#endif
+#ifdef CONFIG_MIPS32_N32
+		if ((current->thread.mflags & MF_ABI_MASK) == MF_N32)
+			setup_rt_frame_n32 (ka, regs, sig, oldset, info);
+		else
+#endif
+			setup_rt_frame(ka, regs, sig, oldset, info);
+	}
+#ifdef CONFIG_TRAD_SIGNALS
+	else
+		setup_frame(ka, regs, sig, oldset);
+#endif
+
+	if (!(ka->sa.sa_flags & SA_NODEFER)) {
+		spin_lock_irq(&current->sighand->siglock);
+		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+		sigaddset(&current->blocked,sig);
+		recalc_sigpending();
+		spin_unlock_irq(&current->sighand->siglock);
+	}
+}
+
+extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
+extern int do_irix_signal(sigset_t *oldset, struct pt_regs *regs);
+
+static int do_signal(sigset_t *oldset, struct pt_regs *regs)
+{
+	struct k_sigaction ka;
+	siginfo_t info;
+	int signr;
+
+#ifdef CONFIG_BINFMT_ELF32
+	if ((current->thread.mflags & MF_ABI_MASK) == MF_O32) {
+		return do_signal32(oldset, regs);
+	}
+#endif
+
+	/*
+	 * We want the common case to go fast, which is why we may in certain
+	 * cases get here from kernel mode. Just return without doing anything
+	 * if so.
+	 */
+	if (!user_mode(regs))
+		return 1;
+
+	if (try_to_freeze(0))
+		goto no_signal;
+
+	if (!oldset)
+		oldset = &current->blocked;
+
+	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+	if (signr > 0) {
+		handle_signal(signr, &info, &ka, oldset, regs);
+		return 1;
+	}
+
+no_signal:
+	/*
+	 * Who's code doesn't conform to the restartable syscall convention
+	 * dies here!!!  The li instruction, a single machine instruction,
+	 * must directly be followed by the syscall instruction.
+	 */
+	if (regs->regs[0]) {
+		if (regs->regs[2] == ERESTARTNOHAND ||
+		    regs->regs[2] == ERESTARTSYS ||
+		    regs->regs[2] == ERESTARTNOINTR) {
+			regs->regs[7] = regs->regs[26];
+			regs->cp0_epc -= 8;
+		}
+		if (regs->regs[2] == ERESTART_RESTARTBLOCK) {
+			regs->regs[2] = __NR_restart_syscall;
+			regs->regs[7] = regs->regs[26];
+			regs->cp0_epc -= 4;
+		}
+	}
+	return 0;
+}
+
+/*
+ * notification of userspace execution resumption
+ * - triggered by current->work.notify_resume
+ */
+asmlinkage void do_notify_resume(struct pt_regs *regs, sigset_t *oldset,
+	__u32 thread_info_flags)
+{
+	/* deal with pending signal delivery */
+	if (thread_info_flags & _TIF_SIGPENDING) {
+#ifdef CONFIG_BINFMT_ELF32
+		if (likely((current->thread.mflags & MF_ABI_MASK) == MF_O32)) {
+			do_signal32(oldset, regs);
+			return;
+		}
+#endif
+#ifdef CONFIG_BINFMT_IRIX
+		if (unlikely(current->personality != PER_LINUX)) {
+			do_irix_signal(oldset, regs);
+			return;
+		}
+#endif
+		do_signal(oldset, regs);
+	}
+}
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
new file mode 100644
index 0000000..1f3b191
--- /dev/null
+++ b/arch/mips/kernel/signal32.c
@@ -0,0 +1,905 @@
+/*
+ * 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) 1991, 1992  Linus Torvalds
+ * Copyright (C) 1994 - 2000  Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/syscalls.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/compat.h>
+#include <linux/suspend.h>
+#include <linux/compiler.h>
+
+#include <asm/asm.h>
+#include <linux/bitops.h>
+#include <asm/cacheflush.h>
+#include <asm/sim.h>
+#include <asm/uaccess.h>
+#include <asm/ucontext.h>
+#include <asm/system.h>
+#include <asm/fpu.h>
+
+#define SI_PAD_SIZE32   ((SI_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct compat_siginfo {
+	int si_signo;
+	int si_code;
+	int si_errno;
+
+	union {
+		int _pad[SI_PAD_SIZE32];
+
+		/* kill() */
+		struct {
+			compat_pid_t _pid;	/* sender's pid */
+			compat_uid_t _uid;	/* sender's uid */
+		} _kill;
+
+		/* SIGCHLD */
+		struct {
+			compat_pid_t _pid;	/* which child */
+			compat_uid_t _uid;	/* sender's uid */
+			int _status;		/* exit code */
+			compat_clock_t _utime;
+			compat_clock_t _stime;
+		} _sigchld;
+
+		/* IRIX SIGCHLD */
+		struct {
+			compat_pid_t _pid;	/* which child */
+			compat_clock_t _utime;
+			int _status;		/* exit code */
+			compat_clock_t _stime;
+		} _irix_sigchld;
+
+		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+		struct {
+			s32 _addr; /* faulting insn/memory ref. */
+		} _sigfault;
+
+		/* SIGPOLL, SIGXFSZ (To do ...)  */
+		struct {
+			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			int _fd;
+		} _sigpoll;
+
+		/* POSIX.1b timers */
+		struct {
+			unsigned int _timer1;
+			unsigned int _timer2;
+		} _timer;
+
+		/* POSIX.1b signals */
+		struct {
+			compat_pid_t _pid;	/* sender's pid */
+			compat_uid_t _uid;	/* sender's uid */
+			compat_sigval_t _sigval;
+		} _rt;
+
+	} _sifields;
+} compat_siginfo_t;
+
+/*
+ * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
+ */
+#define __NR_O32_sigreturn		4119
+#define __NR_O32_rt_sigreturn		4193
+#define __NR_O32_restart_syscall	4253
+
+#define DEBUG_SIG 0
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
+
+/* 32-bit compatibility types */
+
+#define _NSIG_BPW32	32
+#define _NSIG_WORDS32	(_NSIG / _NSIG_BPW32)
+
+typedef struct {
+	unsigned int sig[_NSIG_WORDS32];
+} sigset_t32;
+
+typedef unsigned int __sighandler32_t;
+typedef void (*vfptr_t)(void);
+
+struct sigaction32 {
+	unsigned int		sa_flags;
+	__sighandler32_t	sa_handler;
+	compat_sigset_t		sa_mask;
+};
+
+/* IRIX compatible stack_t  */
+typedef struct sigaltstack32 {
+	s32 ss_sp;
+	compat_size_t ss_size;
+	int ss_flags;
+} stack32_t;
+
+struct ucontext32 {
+	u32                 uc_flags;
+	s32                 uc_link;
+	stack32_t           uc_stack;
+	struct sigcontext32 uc_mcontext;
+	sigset_t32          uc_sigmask;   /* mask last for extensibility */
+};
+
+extern void __put_sigset_unknown_nsig(void);
+extern void __get_sigset_unknown_nsig(void);
+
+static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t *ubuf)
+{
+	int err = 0;
+
+	if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)))
+		return -EFAULT;
+
+	switch (_NSIG_WORDS) {
+	default:
+		__put_sigset_unknown_nsig();
+	case 2:
+		err |= __put_user (kbuf->sig[1] >> 32, &ubuf->sig[3]);
+		err |= __put_user (kbuf->sig[1] & 0xffffffff, &ubuf->sig[2]);
+	case 1:
+		err |= __put_user (kbuf->sig[0] >> 32, &ubuf->sig[1]);
+		err |= __put_user (kbuf->sig[0] & 0xffffffff, &ubuf->sig[0]);
+	}
+
+	return err;
+}
+
+static inline int get_sigset(sigset_t *kbuf, const compat_sigset_t *ubuf)
+{
+	int err = 0;
+	unsigned long sig[4];
+
+	if (!access_ok(VERIFY_READ, ubuf, sizeof(*ubuf)))
+		return -EFAULT;
+
+	switch (_NSIG_WORDS) {
+	default:
+		__get_sigset_unknown_nsig();
+	case 2:
+		err |= __get_user (sig[3], &ubuf->sig[3]);
+		err |= __get_user (sig[2], &ubuf->sig[2]);
+		kbuf->sig[1] = sig[2] | (sig[3] << 32);
+	case 1:
+		err |= __get_user (sig[1], &ubuf->sig[1]);
+		err |= __get_user (sig[0], &ubuf->sig[0]);
+		kbuf->sig[0] = sig[0] | (sig[1] << 32);
+	}
+
+	return err;
+}
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+
+save_static_function(sys32_sigsuspend);
+__attribute_used__ noinline static int
+_sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
+{
+	compat_sigset_t *uset;
+	sigset_t newset, saveset;
+
+	uset = (compat_sigset_t *) regs.regs[4];
+	if (get_sigset(&newset, uset))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sighand->siglock);
+	saveset = current->blocked;
+	current->blocked = newset;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	regs.regs[2] = EINTR;
+	regs.regs[7] = 1;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal32(&saveset, &regs))
+			return -EINTR;
+	}
+}
+
+save_static_function(sys32_rt_sigsuspend);
+__attribute_used__ noinline static int
+_sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
+{
+	compat_sigset_t *uset;
+	sigset_t newset, saveset;
+        size_t sigsetsize;
+
+	/* XXX Don't preclude handling different sized sigset_t's.  */
+	sigsetsize = regs.regs[5];
+	if (sigsetsize != sizeof(compat_sigset_t))
+		return -EINVAL;
+
+	uset = (compat_sigset_t *) regs.regs[4];
+	if (get_sigset(&newset, uset))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sighand->siglock);
+	saveset = current->blocked;
+	current->blocked = newset;
+        recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	regs.regs[2] = EINTR;
+	regs.regs[7] = 1;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal32(&saveset, &regs))
+			return -EINTR;
+	}
+}
+
+asmlinkage int sys32_sigaction(int sig, const struct sigaction32 *act,
+                               struct sigaction32 *oact)
+{
+	struct k_sigaction new_ka, old_ka;
+	int ret;
+	int err = 0;
+
+	if (act) {
+		old_sigset_t mask;
+
+		if (!access_ok(VERIFY_READ, act, sizeof(*act)))
+			return -EFAULT;
+		err |= __get_user((u32)(u64)new_ka.sa.sa_handler,
+		                  &act->sa_handler);
+		err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
+		err |= __get_user(mask, &act->sa_mask.sig[0]);
+		if (err)
+			return -EFAULT;
+
+		siginitset(&new_ka.sa.sa_mask, mask);
+	}
+
+	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+	if (!ret && oact) {
+		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
+                        return -EFAULT;
+		err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+		err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
+		                  &oact->sa_handler);
+		err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
+                err |= __put_user(0, &oact->sa_mask.sig[1]);
+                err |= __put_user(0, &oact->sa_mask.sig[2]);
+                err |= __put_user(0, &oact->sa_mask.sig[3]);
+                if (err)
+			return -EFAULT;
+	}
+
+	return ret;
+}
+
+asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
+{
+	const stack32_t *uss = (const stack32_t *) regs.regs[4];
+	stack32_t *uoss = (stack32_t *) regs.regs[5];
+	unsigned long usp = regs.regs[29];
+	stack_t kss, koss;
+	int ret, err = 0;
+	mm_segment_t old_fs = get_fs();
+	s32 sp;
+
+	if (uss) {
+		if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
+			return -EFAULT;
+		err |= __get_user(sp, &uss->ss_sp);
+		kss.ss_sp = (void *) (long) sp;
+		err |= __get_user(kss.ss_size, &uss->ss_size);
+		err |= __get_user(kss.ss_flags, &uss->ss_flags);
+		if (err)
+			return -EFAULT;
+	}
+
+	set_fs (KERNEL_DS);
+	ret = do_sigaltstack(uss ? &kss : NULL , uoss ? &koss : NULL, usp);
+	set_fs (old_fs);
+
+	if (!ret && uoss) {
+		if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)))
+			return -EFAULT;
+		sp = (int) (long) koss.ss_sp;
+		err |= __put_user(sp, &uoss->ss_sp);
+		err |= __put_user(koss.ss_size, &uoss->ss_size);
+		err |= __put_user(koss.ss_flags, &uoss->ss_flags);
+		if (err)
+			return -EFAULT;
+	}
+	return ret;
+}
+
+static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc)
+{
+	int err = 0;
+	__u32 used_math;
+
+	/* Always make any pending restarted system calls return -EINTR */
+	current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
+	err |= __get_user(regs->cp0_epc, &sc->sc_pc);
+	err |= __get_user(regs->hi, &sc->sc_mdhi);
+	err |= __get_user(regs->lo, &sc->sc_mdlo);
+
+#define restore_gp_reg(i) do {						\
+	err |= __get_user(regs->regs[i], &sc->sc_regs[i]);		\
+} while(0)
+	restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
+	restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
+	restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
+	restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
+	restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
+	restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
+	restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
+	restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
+	restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
+	restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
+	restore_gp_reg(31);
+#undef restore_gp_reg
+
+	err |= __get_user(used_math, &sc->sc_used_math);
+	conditional_used_math(used_math);
+
+	preempt_disable();
+
+	if (used_math()) {
+		/* restore fpu context if we have used it before */
+		own_fpu();
+		err |= restore_fp_context32(sc);
+	} else {
+		/* signal handler may have used FPU.  Give it up. */
+		lose_fpu();
+	}
+
+	preempt_enable();
+
+	return err;
+}
+
+struct sigframe {
+	u32 sf_ass[4];			/* argument save space for o32 */
+	u32 sf_code[2];			/* signal trampoline */
+	struct sigcontext32 sf_sc;
+	sigset_t sf_mask;
+};
+
+struct rt_sigframe32 {
+	u32 rs_ass[4];			/* argument save space for o32 */
+	u32 rs_code[2];			/* signal trampoline */
+	compat_siginfo_t rs_info;
+	struct ucontext32 rs_uc;
+};
+
+int copy_siginfo_to_user32(compat_siginfo_t *to, siginfo_t *from)
+{
+	int err;
+
+	if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
+		return -EFAULT;
+
+	/* If you change siginfo_t structure, please be sure
+	   this code is fixed accordingly.
+	   It should never copy any pad contained in the structure
+	   to avoid security leaks, but must copy the generic
+	   3 ints plus the relevant union member.
+	   This routine must convert siginfo from 64bit to 32bit as well
+	   at the same time.  */
+	err = __put_user(from->si_signo, &to->si_signo);
+	err |= __put_user(from->si_errno, &to->si_errno);
+	err |= __put_user((short)from->si_code, &to->si_code);
+	if (from->si_code < 0)
+		err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
+	else {
+		switch (from->si_code >> 16) {
+		case __SI_CHLD >> 16:
+			err |= __put_user(from->si_utime, &to->si_utime);
+			err |= __put_user(from->si_stime, &to->si_stime);
+			err |= __put_user(from->si_status, &to->si_status);
+		default:
+			err |= __put_user(from->si_pid, &to->si_pid);
+			err |= __put_user(from->si_uid, &to->si_uid);
+			break;
+		case __SI_FAULT >> 16:
+			err |= __put_user((long)from->si_addr, &to->si_addr);
+			break;
+		case __SI_POLL >> 16:
+			err |= __put_user(from->si_band, &to->si_band);
+			err |= __put_user(from->si_fd, &to->si_fd);
+			break;
+		case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
+		case __SI_MESGQ >> 16:
+			err |= __put_user(from->si_pid, &to->si_pid);
+			err |= __put_user(from->si_uid, &to->si_uid);
+			err |= __put_user(from->si_int, &to->si_int);
+			break;
+		}
+	}
+	return err;
+}
+
+save_static_function(sys32_sigreturn);
+__attribute_used__ noinline static void
+_sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
+{
+	struct sigframe *frame;
+	sigset_t blocked;
+
+	frame = (struct sigframe *) regs.regs[29];
+	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked)))
+		goto badframe;
+
+	sigdelsetmask(&blocked, ~_BLOCKABLE);
+	spin_lock_irq(&current->sighand->siglock);
+	current->blocked = blocked;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	if (restore_sigcontext32(&regs, &frame->sf_sc))
+		goto badframe;
+
+	/*
+	 * Don't let your children do this ...
+	 */
+	if (current_thread_info()->flags & TIF_SYSCALL_TRACE)
+		do_syscall_trace(&regs, 1);
+	__asm__ __volatile__(
+		"move\t$29, %0\n\t"
+		"j\tsyscall_exit"
+		:/* no outputs */
+		:"r" (&regs));
+	/* Unreached */
+
+badframe:
+	force_sig(SIGSEGV, current);
+}
+
+save_static_function(sys32_rt_sigreturn);
+__attribute_used__ noinline static void
+_sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
+{
+	struct rt_sigframe32 *frame;
+	sigset_t set;
+	stack_t st;
+	s32 sp;
+
+	frame = (struct rt_sigframe32 *) regs.regs[29];
+	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sighand->siglock);
+	current->blocked = set;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	if (restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext))
+		goto badframe;
+
+	/* The ucontext contains a stack32_t, so we must convert!  */
+	if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
+		goto badframe;
+	st.ss_size = (long) sp;
+	if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
+		goto badframe;
+	if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
+		goto badframe;
+
+	/* It is more difficult to avoid calling this function than to
+	   call it and ignore errors.  */
+	do_sigaltstack(&st, NULL, regs.regs[29]);
+
+	/*
+	 * Don't let your children do this ...
+	 */
+	__asm__ __volatile__(
+		"move\t$29, %0\n\t"
+		"j\tsyscall_exit"
+		:/* no outputs */
+		:"r" (&regs));
+	/* Unreached */
+
+badframe:
+	force_sig(SIGSEGV, current);
+}
+
+static inline int setup_sigcontext32(struct pt_regs *regs,
+				     struct sigcontext32 *sc)
+{
+	int err = 0;
+
+	err |= __put_user(regs->cp0_epc, &sc->sc_pc);
+	err |= __put_user(regs->cp0_status, &sc->sc_status);
+
+#define save_gp_reg(i) {						\
+	err |= __put_user(regs->regs[i], &sc->sc_regs[i]);		\
+} while(0)
+	__put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
+	save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
+	save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
+	save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
+	save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
+	save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
+	save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
+	save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
+	save_gp_reg(31);
+#undef save_gp_reg
+
+	err |= __put_user(regs->hi, &sc->sc_mdhi);
+	err |= __put_user(regs->lo, &sc->sc_mdlo);
+	err |= __put_user(regs->cp0_cause, &sc->sc_cause);
+	err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
+
+	err |= __put_user(!!used_math(), &sc->sc_used_math);
+
+	if (!used_math())
+		goto out;
+
+	/* 
+	 * Save FPU state to signal context.  Signal handler will "inherit"
+	 * current FPU state.
+	 */
+	preempt_disable();
+
+	if (!is_fpu_owner()) {
+		own_fpu();
+		restore_fp(current);
+	}
+	err |= save_fp_context32(sc);
+
+	preempt_enable();
+
+out:
+	return err;
+}
+
+/*
+ * Determine which stack to use..
+ */
+static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+				 size_t frame_size)
+{
+	unsigned long sp;
+
+	/* Default to using normal stack */
+	sp = regs->regs[29];
+
+	/*
+ 	 * FPU emulator may have it's own trampoline active just
+ 	 * above the user stack, 16-bytes before the next lowest
+ 	 * 16 byte boundary.  Try to avoid trashing it.
+ 	 */
+ 	sp -= 32;
+
+	/* This is the X/Open sanctioned signal stack switching.  */
+	if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
+		sp = current->sas_ss_sp + current->sas_ss_size;
+
+	return (void *)((sp - frame_size) & ALMASK);
+}
+
+static inline void setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
+			       int signr, sigset_t *set)
+{
+	struct sigframe *frame;
+	int err = 0;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+		goto give_sigsegv;
+
+	/*
+	 * Set up the return code ...
+	 *
+	 *         li      v0, __NR_O32_sigreturn
+	 *         syscall
+	 */
+	err |= __put_user(0x24020000 + __NR_O32_sigreturn, frame->sf_code + 0);
+	err |= __put_user(0x0000000c                     , frame->sf_code + 1);
+	flush_cache_sigtramp((unsigned long) frame->sf_code);
+
+	err |= setup_sigcontext32(regs, &frame->sf_sc);
+	err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
+	if (err)
+		goto give_sigsegv;
+
+	/*
+	 * Arguments to signal handler:
+	 *
+	 *   a0 = signal number
+	 *   a1 = 0 (should be cause)
+	 *   a2 = pointer to struct sigcontext
+	 *
+	 * $25 and c0_epc point to the signal handler, $29 points to the
+	 * struct sigframe.
+	 */
+	regs->regs[ 4] = signr;
+	regs->regs[ 5] = 0;
+	regs->regs[ 6] = (unsigned long) &frame->sf_sc;
+	regs->regs[29] = (unsigned long) frame;
+	regs->regs[31] = (unsigned long) frame->sf_code;
+	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
+
+#if DEBUG_SIG
+	printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
+	       current->comm, current->pid,
+	       frame, regs->cp0_epc, frame->sf_code);
+#endif
+        return;
+
+give_sigsegv:
+	force_sigsegv(signr, current);
+}
+
+static inline void setup_rt_frame(struct k_sigaction * ka,
+				  struct pt_regs *regs, int signr,
+				  sigset_t *set, siginfo_t *info)
+{
+	struct rt_sigframe32 *frame;
+	int err = 0;
+	s32 sp;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+		goto give_sigsegv;
+
+	/* Set up to return from userspace.  If provided, use a stub already
+	   in userspace.  */
+	/*
+	 * Set up the return code ...
+	 *
+	 *         li      v0, __NR_O32_rt_sigreturn
+	 *         syscall
+	 */
+	err |= __put_user(0x24020000 + __NR_O32_rt_sigreturn, frame->rs_code + 0);
+	err |= __put_user(0x0000000c                      , frame->rs_code + 1);
+	flush_cache_sigtramp((unsigned long) frame->rs_code);
+
+	/* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
+	err |= copy_siginfo_to_user32(&frame->rs_info, info);
+
+	/* Create the ucontext.  */
+	err |= __put_user(0, &frame->rs_uc.uc_flags);
+	err |= __put_user(0, &frame->rs_uc.uc_link);
+	sp = (int) (long) current->sas_ss_sp;
+	err |= __put_user(sp,
+	                  &frame->rs_uc.uc_stack.ss_sp);
+	err |= __put_user(sas_ss_flags(regs->regs[29]),
+	                  &frame->rs_uc.uc_stack.ss_flags);
+	err |= __put_user(current->sas_ss_size,
+	                  &frame->rs_uc.uc_stack.ss_size);
+	err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
+	err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
+
+	if (err)
+		goto give_sigsegv;
+
+	/*
+	 * Arguments to signal handler:
+	 *
+	 *   a0 = signal number
+	 *   a1 = 0 (should be cause)
+	 *   a2 = pointer to ucontext
+	 *
+	 * $25 and c0_epc point to the signal handler, $29 points to
+	 * the struct rt_sigframe32.
+	 */
+	regs->regs[ 4] = signr;
+	regs->regs[ 5] = (unsigned long) &frame->rs_info;
+	regs->regs[ 6] = (unsigned long) &frame->rs_uc;
+	regs->regs[29] = (unsigned long) frame;
+	regs->regs[31] = (unsigned long) frame->rs_code;
+	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
+
+#if DEBUG_SIG
+	printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
+	       current->comm, current->pid,
+	       frame, regs->cp0_epc, frame->rs_code);
+#endif
+	return;
+
+give_sigsegv:
+	force_sigsegv(signr, current);
+}
+
+static inline void handle_signal(unsigned long sig, siginfo_t *info,
+	struct k_sigaction *ka, sigset_t *oldset, struct pt_regs * regs)
+{
+	switch (regs->regs[0]) {
+	case ERESTART_RESTARTBLOCK:
+	case ERESTARTNOHAND:
+		regs->regs[2] = EINTR;
+		break;
+	case ERESTARTSYS:
+		if(!(ka->sa.sa_flags & SA_RESTART)) {
+			regs->regs[2] = EINTR;
+			break;
+		}
+	/* fallthrough */
+	case ERESTARTNOINTR:		/* Userland will reload $v0.  */
+		regs->regs[7] = regs->regs[26];
+		regs->cp0_epc -= 8;
+	}
+
+	regs->regs[0] = 0;		/* Don't deal with this again.  */
+
+	if (ka->sa.sa_flags & SA_SIGINFO)
+		setup_rt_frame(ka, regs, sig, oldset, info);
+	else
+		setup_frame(ka, regs, sig, oldset);
+
+	if (!(ka->sa.sa_flags & SA_NODEFER)) {
+		spin_lock_irq(&current->sighand->siglock);
+		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+		sigaddset(&current->blocked,sig);
+		recalc_sigpending();
+		spin_unlock_irq(&current->sighand->siglock);
+	}
+}
+
+int do_signal32(sigset_t *oldset, struct pt_regs *regs)
+{
+	struct k_sigaction ka;
+	siginfo_t info;
+	int signr;
+
+	/*
+	 * We want the common case to go fast, which is why we may in certain
+	 * cases get here from kernel mode. Just return without doing anything
+	 * if so.
+	 */
+	if (!user_mode(regs))
+		return 1;
+
+	if (try_to_freeze(0))
+		goto no_signal;
+
+	if (!oldset)
+		oldset = &current->blocked;
+
+	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+	if (signr > 0) {
+		handle_signal(signr, &info, &ka, oldset, regs);
+		return 1;
+	}
+
+no_signal:
+	/*
+	 * Who's code doesn't conform to the restartable syscall convention
+	 * dies here!!!  The li instruction, a single machine instruction,
+	 * must directly be followed by the syscall instruction.
+	 */
+	if (regs->regs[0]) {
+		if (regs->regs[2] == ERESTARTNOHAND ||
+		    regs->regs[2] == ERESTARTSYS ||
+		    regs->regs[2] == ERESTARTNOINTR) {
+			regs->regs[7] = regs->regs[26];
+			regs->cp0_epc -= 8;
+		}
+		if (regs->regs[2] == ERESTART_RESTARTBLOCK) {
+			regs->regs[2] = __NR_O32_restart_syscall;
+			regs->regs[7] = regs->regs[26];
+			regs->cp0_epc -= 4;
+		}
+	}
+	return 0;
+}
+
+asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 *act,
+				  struct sigaction32 *oact,
+				  unsigned int sigsetsize)
+{
+	struct k_sigaction new_sa, old_sa;
+	int ret = -EINVAL;
+
+	/* XXX: Don't preclude handling different sized sigset_t's.  */
+	if (sigsetsize != sizeof(sigset_t))
+		goto out;
+
+	if (act) {
+		int err = 0;
+
+		if (!access_ok(VERIFY_READ, act, sizeof(*act)))
+			return -EFAULT;
+		err |= __get_user((u32)(u64)new_sa.sa.sa_handler,
+		                  &act->sa_handler);
+		err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags);
+		err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask);
+		if (err)
+			return -EFAULT;
+	}
+
+	ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
+
+	if (!ret && oact) {
+		int err = 0;
+
+		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
+			return -EFAULT;
+
+		err |= __put_user((u32)(u64)old_sa.sa.sa_handler,
+		                   &oact->sa_handler);
+		err |= __put_user(old_sa.sa.sa_flags, &oact->sa_flags);
+		err |= put_sigset(&old_sa.sa.sa_mask, &oact->sa_mask);
+		if (err)
+			return -EFAULT;
+	}
+out:
+	return ret;
+}
+
+asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t *set,
+	compat_sigset_t *oset, unsigned int sigsetsize)
+{
+	sigset_t old_set, new_set;
+	int ret;
+	mm_segment_t old_fs = get_fs();
+
+	if (set && get_sigset(&new_set, set))
+		return -EFAULT;
+
+	set_fs (KERNEL_DS);
+	ret = sys_rt_sigprocmask(how, set ? &new_set : NULL,
+				 oset ? &old_set : NULL, sigsetsize);
+	set_fs (old_fs);
+
+	if (!ret && oset && put_sigset(&old_set, oset))
+		return -EFAULT;
+
+	return ret;
+}
+
+asmlinkage int sys32_rt_sigpending(compat_sigset_t *uset,
+	unsigned int sigsetsize)
+{
+	int ret;
+	sigset_t set;
+	mm_segment_t old_fs = get_fs();
+
+	set_fs (KERNEL_DS);
+	ret = sys_rt_sigpending(&set, sigsetsize);
+	set_fs (old_fs);
+
+	if (!ret && put_sigset(&set, uset))
+		return -EFAULT;
+
+	return ret;
+}
+
+asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t *uinfo)
+{
+	siginfo_t info;
+	int ret;
+	mm_segment_t old_fs = get_fs();
+
+	if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
+	    copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
+		return -EFAULT;
+	set_fs (KERNEL_DS);
+	ret = sys_rt_sigqueueinfo(pid, sig, &info);
+	set_fs (old_fs);
+	return ret;
+}
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
new file mode 100644
index 0000000..3544208
--- /dev/null
+++ b/arch/mips/kernel/signal_n32.c
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2003 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/compat.h>
+#include <linux/bitops.h>
+
+#include <asm/asm.h>
+#include <asm/cacheflush.h>
+#include <asm/sim.h>
+#include <asm/uaccess.h>
+#include <asm/ucontext.h>
+#include <asm/system.h>
+#include <asm/fpu.h>
+#include <asm/cpu-features.h>
+
+#include "signal-common.h"
+
+/*
+ * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
+ */
+#define __NR_N32_rt_sigreturn		6211
+#define __NR_N32_restart_syscall	6214
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+/* IRIX compatible stack_t  */
+typedef struct sigaltstack32 {
+	s32 ss_sp;
+	compat_size_t ss_size;
+	int ss_flags;
+} stack32_t;
+
+struct ucontextn32 {
+	u32                 uc_flags;
+	s32                 uc_link;
+	stack32_t           uc_stack;
+	struct sigcontext   uc_mcontext;
+	sigset_t            uc_sigmask;   /* mask last for extensibility */
+};
+
+#if PLAT_TRAMPOLINE_STUFF_LINE
+#define __tramp __attribute__((aligned(PLAT_TRAMPOLINE_STUFF_LINE)))
+#else
+#define __tramp
+#endif
+
+struct rt_sigframe_n32 {
+	u32 rs_ass[4];			/* argument save space for o32 */
+	u32 rs_code[2] __tramp;		/* signal trampoline */
+	struct siginfo rs_info __tramp;
+	struct ucontextn32 rs_uc;
+};
+
+save_static_function(sysn32_rt_sigreturn);
+__attribute_used__ noinline static void
+_sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
+{
+	struct rt_sigframe_n32 *frame;
+	sigset_t set;
+	stack_t st;
+	s32 sp;
+
+	frame = (struct rt_sigframe_n32 *) regs.regs[29];
+	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sighand->siglock);
+	current->blocked = set;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	if (restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext))
+		goto badframe;
+
+	/* The ucontext contains a stack32_t, so we must convert!  */
+	if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
+		goto badframe;
+	st.ss_size = (long) sp;
+	if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
+		goto badframe;
+	if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
+		goto badframe;
+
+	/* It is more difficult to avoid calling this function than to
+	   call it and ignore errors.  */
+	do_sigaltstack(&st, NULL, regs.regs[29]);
+
+	/*
+	 * Don't let your children do this ...
+	 */
+	__asm__ __volatile__(
+		"move\t$29, %0\n\t"
+		"j\tsyscall_exit"
+		:/* no outputs */
+		:"r" (&regs));
+	/* Unreached */
+
+badframe:
+	force_sig(SIGSEGV, current);
+}
+
+void setup_rt_frame_n32(struct k_sigaction * ka,
+	struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
+{
+	struct rt_sigframe_n32 *frame;
+	int err = 0;
+	s32 sp;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+		goto give_sigsegv;
+
+	/*
+	 * Set up the return code ...
+	 *
+	 *         li      v0, __NR_rt_sigreturn
+	 *         syscall
+	 */
+	if (PLAT_TRAMPOLINE_STUFF_LINE)
+		__clear_user(frame->rs_code, PLAT_TRAMPOLINE_STUFF_LINE);
+	err |= __put_user(0x24020000 + __NR_N32_rt_sigreturn, frame->rs_code + 0);
+	err |= __put_user(0x0000000c                        , frame->rs_code + 1);
+	flush_cache_sigtramp((unsigned long) frame->rs_code);
+
+	/* Create siginfo.  */
+	err |= copy_siginfo_to_user(&frame->rs_info, info);
+
+	/* Create the ucontext.  */
+	err |= __put_user(0, &frame->rs_uc.uc_flags);
+	err |= __put_user(0, &frame->rs_uc.uc_link);
+        sp = (int) (long) current->sas_ss_sp;
+	err |= __put_user(sp,
+	                  &frame->rs_uc.uc_stack.ss_sp);
+	err |= __put_user(sas_ss_flags(regs->regs[29]),
+	                  &frame->rs_uc.uc_stack.ss_flags);
+	err |= __put_user(current->sas_ss_size,
+	                  &frame->rs_uc.uc_stack.ss_size);
+	err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext);
+	err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
+
+	if (err)
+		goto give_sigsegv;
+
+	/*
+	 * Arguments to signal handler:
+	 *
+	 *   a0 = signal number
+	 *   a1 = 0 (should be cause)
+	 *   a2 = pointer to ucontext
+	 *
+	 * $25 and c0_epc point to the signal handler, $29 points to
+	 * the struct rt_sigframe.
+	 */
+	regs->regs[ 4] = signr;
+	regs->regs[ 5] = (unsigned long) &frame->rs_info;
+	regs->regs[ 6] = (unsigned long) &frame->rs_uc;
+	regs->regs[29] = (unsigned long) frame;
+	regs->regs[31] = (unsigned long) frame->rs_code;
+	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
+
+#if DEBUG_SIG
+	printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
+	       current->comm, current->pid,
+	       frame, regs->cp0_epc, regs->regs[31]);
+#endif
+	return;
+
+give_sigsegv:
+	force_sigsegv(signr, current);
+}
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
new file mode 100644
index 0000000..af5cd3b
--- /dev/null
+++ b/arch/mips/kernel/smp.c
@@ -0,0 +1,425 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Copyright (C) 2000, 2001 Kanoj Sarcar
+ * Copyright (C) 2000, 2001 Ralf Baechle
+ * Copyright (C) 2000, 2001 Silicon Graphics, Inc.
+ * Copyright (C) 2000, 2001, 2003 Broadcom Corporation
+ */
+#include <linux/cache.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/threads.h>
+#include <linux/module.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/sched.h>
+#include <linux/cpumask.h>
+
+#include <asm/atomic.h>
+#include <asm/cpu.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+#include <asm/smp.h>
+
+cpumask_t phys_cpu_present_map;		/* Bitmask of available CPUs */
+volatile cpumask_t cpu_callin_map;	/* Bitmask of started secondaries */
+cpumask_t cpu_online_map;		/* Bitmask of currently online CPUs */
+int __cpu_number_map[NR_CPUS];		/* Map physical to logical */
+int __cpu_logical_map[NR_CPUS];		/* Map logical to physical */
+
+EXPORT_SYMBOL(phys_cpu_present_map);
+EXPORT_SYMBOL(cpu_online_map);
+
+static void smp_tune_scheduling (void)
+{
+	struct cache_desc *cd = &current_cpu_data.scache;
+	unsigned long cachesize;       /* kB   */
+	unsigned long bandwidth = 350; /* MB/s */
+	unsigned long cpu_khz;
+
+	/*
+	 * Crude estimate until we actually meassure ...
+	 */
+	cpu_khz = loops_per_jiffy * 2 * HZ / 1000;
+
+	/*
+	 * Rough estimation for SMP scheduling, this is the number of
+	 * cycles it takes for a fully memory-limited process to flush
+	 * the SMP-local cache.
+	 *
+	 * (For a P5 this pretty much means we will choose another idle
+	 *  CPU almost always at wakeup time (this is due to the small
+	 *  L1 cache), on PIIs it's around 50-100 usecs, depending on
+	 *  the cache size)
+	 */
+	if (!cpu_khz)
+		return;
+
+	cachesize = cd->linesz * cd->sets * cd->ways;
+}
+
+extern void __init calibrate_delay(void);
+extern ATTRIB_NORET void cpu_idle(void);
+
+/*
+ * First C code run on the secondary CPUs after being started up by
+ * the master.
+ */
+asmlinkage void start_secondary(void)
+{
+	unsigned int cpu = smp_processor_id();
+
+	cpu_probe();
+	cpu_report();
+	per_cpu_trap_init();
+	prom_init_secondary();
+
+	/*
+	 * XXX parity protection should be folded in here when it's converted
+	 * to an option instead of something based on .cputype
+	 */
+
+	calibrate_delay();
+	cpu_data[cpu].udelay_val = loops_per_jiffy;
+
+	prom_smp_finish();
+
+	cpu_set(cpu, cpu_callin_map);
+
+	cpu_idle();
+}
+
+DEFINE_SPINLOCK(smp_call_lock);
+
+struct call_data_struct *call_data;
+
+/*
+ * Run a function on all other CPUs.
+ *  <func>      The function to run. This must be fast and non-blocking.
+ *  <info>      An arbitrary pointer to pass to the function.
+ *  <retry>     If true, keep retrying until ready.
+ *  <wait>      If true, wait until function has completed on other CPUs.
+ *  [RETURNS]   0 on success, else a negative status code.
+ *
+ * Does not return until remote CPUs are nearly ready to execute <func>
+ * or are or have executed.
+ *
+ * You must not call this function with disabled interrupts or from a
+ * hardware interrupt handler or from a bottom half handler.
+ */
+int smp_call_function (void (*func) (void *info), void *info, int retry,
+								int wait)
+{
+	struct call_data_struct data;
+	int i, cpus = num_online_cpus() - 1;
+	int cpu = smp_processor_id();
+
+	if (!cpus)
+		return 0;
+
+	/* Can deadlock when called with interrupts disabled */
+	WARN_ON(irqs_disabled());
+
+	data.func = func;
+	data.info = info;
+	atomic_set(&data.started, 0);
+	data.wait = wait;
+	if (wait)
+		atomic_set(&data.finished, 0);
+
+	spin_lock(&smp_call_lock);
+	call_data = &data;
+	mb();
+
+	/* Send a message to all other CPUs and wait for them to respond */
+	for (i = 0; i < NR_CPUS; i++)
+		if (cpu_online(i) && i != cpu)
+			core_send_ipi(i, SMP_CALL_FUNCTION);
+
+	/* Wait for response */
+	/* FIXME: lock-up detection, backtrace on lock-up */
+	while (atomic_read(&data.started) != cpus)
+		barrier();
+
+	if (wait)
+		while (atomic_read(&data.finished) != cpus)
+			barrier();
+	spin_unlock(&smp_call_lock);
+
+	return 0;
+}
+
+void smp_call_function_interrupt(void)
+{
+	void (*func) (void *info) = call_data->func;
+	void *info = call_data->info;
+	int wait = call_data->wait;
+
+	/*
+	 * Notify initiating CPU that I've grabbed the data and am
+	 * about to execute the function.
+	 */
+	mb();
+	atomic_inc(&call_data->started);
+
+	/*
+	 * At this point the info structure may be out of scope unless wait==1.
+	 */
+	irq_enter();
+	(*func)(info);
+	irq_exit();
+
+	if (wait) {
+		mb();
+		atomic_inc(&call_data->finished);
+	}
+}
+
+static void stop_this_cpu(void *dummy)
+{
+	/*
+	 * Remove this CPU:
+	 */
+	cpu_clear(smp_processor_id(), cpu_online_map);
+	local_irq_enable();	/* May need to service _machine_restart IPI */
+	for (;;);		/* Wait if available. */
+}
+
+void smp_send_stop(void)
+{
+	smp_call_function(stop_this_cpu, NULL, 1, 0);
+}
+
+void __init smp_cpus_done(unsigned int max_cpus)
+{
+	prom_cpus_done();
+}
+
+/* called from main before smp_init() */
+void __init smp_prepare_cpus(unsigned int max_cpus)
+{
+	cpu_data[0].udelay_val = loops_per_jiffy;
+	init_new_context(current, &init_mm);
+	current_thread_info()->cpu = 0;
+	smp_tune_scheduling();
+	prom_prepare_cpus(max_cpus);
+}
+
+/* preload SMP state for boot cpu */
+void __devinit smp_prepare_boot_cpu(void)
+{
+	/*
+	 * This assumes that bootup is always handled by the processor
+	 * with the logic and physical number 0.
+	 */
+	__cpu_number_map[0] = 0;
+	__cpu_logical_map[0] = 0;
+	cpu_set(0, phys_cpu_present_map);
+	cpu_set(0, cpu_online_map);
+	cpu_set(0, cpu_callin_map);
+}
+
+/*
+ * Startup the CPU with this logical number
+ */
+static int __init do_boot_cpu(int cpu)
+{
+	struct task_struct *idle;
+
+	/*
+	 * The following code is purely to make sure
+	 * Linux can schedule processes on this slave.
+	 */
+	idle = fork_idle(cpu);
+	if (IS_ERR(idle))
+		panic("failed fork for CPU %d\n", cpu);
+
+	prom_boot_secondary(cpu, idle);
+
+	/* XXXKW timeout */
+	while (!cpu_isset(cpu, cpu_callin_map))
+		udelay(100);
+
+	cpu_set(cpu, cpu_online_map);
+
+	return 0;
+}
+
+/*
+ * Called once for each "cpu_possible(cpu)".  Needs to spin up the cpu
+ * and keep control until "cpu_online(cpu)" is set.  Note: cpu is
+ * physical, not logical.
+ */
+int __devinit __cpu_up(unsigned int cpu)
+{
+	int ret;
+
+	/* Processor goes to start_secondary(), sets online flag */
+	ret = do_boot_cpu(cpu);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+/* Not really SMP stuff ... */
+int setup_profiling_timer(unsigned int multiplier)
+{
+	return 0;
+}
+
+static void flush_tlb_all_ipi(void *info)
+{
+	local_flush_tlb_all();
+}
+
+void flush_tlb_all(void)
+{
+	on_each_cpu(flush_tlb_all_ipi, 0, 1, 1);
+}
+
+static void flush_tlb_mm_ipi(void *mm)
+{
+	local_flush_tlb_mm((struct mm_struct *)mm);
+}
+
+/*
+ * The following tlb flush calls are invoked when old translations are
+ * being torn down, or pte attributes are changing. For single threaded
+ * address spaces, a new context is obtained on the current cpu, and tlb
+ * context on other cpus are invalidated to force a new context allocation
+ * at switch_mm time, should the mm ever be used on other cpus. For
+ * multithreaded address spaces, intercpu interrupts have to be sent.
+ * Another case where intercpu interrupts are required is when the target
+ * mm might be active on another cpu (eg debuggers doing the flushes on
+ * behalf of debugees, kswapd stealing pages from another process etc).
+ * Kanoj 07/00.
+ */
+
+void flush_tlb_mm(struct mm_struct *mm)
+{
+	preempt_disable();
+
+	if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) {
+		smp_call_function(flush_tlb_mm_ipi, (void *)mm, 1, 1);
+	} else {
+		int i;
+		for (i = 0; i < num_online_cpus(); i++)
+			if (smp_processor_id() != i)
+				cpu_context(i, mm) = 0;
+	}
+	local_flush_tlb_mm(mm);
+
+	preempt_enable();
+}
+
+struct flush_tlb_data {
+	struct vm_area_struct *vma;
+	unsigned long addr1;
+	unsigned long addr2;
+};
+
+static void flush_tlb_range_ipi(void *info)
+{
+	struct flush_tlb_data *fd = (struct flush_tlb_data *)info;
+
+	local_flush_tlb_range(fd->vma, fd->addr1, fd->addr2);
+}
+
+void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
+{
+	struct mm_struct *mm = vma->vm_mm;
+
+	preempt_disable();
+	if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) {
+		struct flush_tlb_data fd;
+
+		fd.vma = vma;
+		fd.addr1 = start;
+		fd.addr2 = end;
+		smp_call_function(flush_tlb_range_ipi, (void *)&fd, 1, 1);
+	} else {
+		int i;
+		for (i = 0; i < num_online_cpus(); i++)
+			if (smp_processor_id() != i)
+				cpu_context(i, mm) = 0;
+	}
+	local_flush_tlb_range(vma, start, end);
+	preempt_enable();
+}
+
+static void flush_tlb_kernel_range_ipi(void *info)
+{
+	struct flush_tlb_data *fd = (struct flush_tlb_data *)info;
+
+	local_flush_tlb_kernel_range(fd->addr1, fd->addr2);
+}
+
+void flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+	struct flush_tlb_data fd;
+
+	fd.addr1 = start;
+	fd.addr2 = end;
+	on_each_cpu(flush_tlb_kernel_range_ipi, (void *)&fd, 1, 1);
+}
+
+static void flush_tlb_page_ipi(void *info)
+{
+	struct flush_tlb_data *fd = (struct flush_tlb_data *)info;
+
+	local_flush_tlb_page(fd->vma, fd->addr1);
+}
+
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+	preempt_disable();
+	if ((atomic_read(&vma->vm_mm->mm_users) != 1) || (current->mm != vma->vm_mm)) {
+		struct flush_tlb_data fd;
+
+		fd.vma = vma;
+		fd.addr1 = page;
+		smp_call_function(flush_tlb_page_ipi, (void *)&fd, 1, 1);
+	} else {
+		int i;
+		for (i = 0; i < num_online_cpus(); i++)
+			if (smp_processor_id() != i)
+				cpu_context(i, vma->vm_mm) = 0;
+	}
+	local_flush_tlb_page(vma, page);
+	preempt_enable();
+}
+
+static void flush_tlb_one_ipi(void *info)
+{
+	unsigned long vaddr = (unsigned long) info;
+
+	local_flush_tlb_one(vaddr);
+}
+
+void flush_tlb_one(unsigned long vaddr)
+{
+	smp_call_function(flush_tlb_one_ipi, (void *) vaddr, 1, 1);
+	local_flush_tlb_one(vaddr);
+}
+
+EXPORT_SYMBOL(flush_tlb_page);
+EXPORT_SYMBOL(flush_tlb_one);
+EXPORT_SYMBOL(cpu_data);
+EXPORT_SYMBOL(synchronize_irq);
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
new file mode 100644
index 0000000..598bfe7
--- /dev/null
+++ b/arch/mips/kernel/syscall.c
@@ -0,0 +1,407 @@
+/*
+ * 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, 1996, 1997, 2000, 2001, 05 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ */
+#include <linux/a.out.h>
+#include <linux/errno.h>
+#include <linux/linkage.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/mman.h>
+#include <linux/ptrace.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/syscalls.h>
+#include <linux/file.h>
+#include <linux/slab.h>
+#include <linux/utsname.h>
+#include <linux/unistd.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/compiler.h>
+
+#include <asm/branch.h>
+#include <asm/cachectl.h>
+#include <asm/cacheflush.h>
+#include <asm/ipc.h>
+#include <asm/offset.h>
+#include <asm/signal.h>
+#include <asm/sim.h>
+#include <asm/shmparam.h>
+#include <asm/sysmips.h>
+#include <asm/uaccess.h>
+
+asmlinkage int sys_pipe(nabi_no_regargs volatile struct pt_regs regs)
+{
+	int fd[2];
+	int error, res;
+
+	error = do_pipe(fd);
+	if (error) {
+		res = error;
+		goto out;
+	}
+	regs.regs[3] = fd[1];
+	res = fd[0];
+out:
+	return res;
+}
+
+unsigned long shm_align_mask = PAGE_SIZE - 1;	/* Sane caches */
+
+#define COLOUR_ALIGN(addr,pgoff)				\
+	((((addr) + shm_align_mask) & ~shm_align_mask) +	\
+	 (((pgoff) << PAGE_SHIFT) & shm_align_mask))
+
+unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+	unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+	struct vm_area_struct * vmm;
+	int do_color_align;
+	unsigned long task_size;
+
+	task_size = STACK_TOP;
+
+	if (flags & MAP_FIXED) {
+		/*
+		 * We do not accept a shared mapping if it would violate
+		 * cache aliasing constraints.
+		 */
+		if ((flags & MAP_SHARED) && (addr & shm_align_mask))
+			return -EINVAL;
+		return addr;
+	}
+
+	if (len > task_size)
+		return -ENOMEM;
+	do_color_align = 0;
+	if (filp || (flags & MAP_SHARED))
+		do_color_align = 1;
+	if (addr) {
+		if (do_color_align)
+			addr = COLOUR_ALIGN(addr, pgoff);
+		else
+			addr = PAGE_ALIGN(addr);
+		vmm = find_vma(current->mm, addr);
+		if (task_size - len >= addr &&
+		    (!vmm || addr + len <= vmm->vm_start))
+			return addr;
+	}
+	addr = TASK_UNMAPPED_BASE;
+	if (do_color_align)
+		addr = COLOUR_ALIGN(addr, pgoff);
+	else
+		addr = PAGE_ALIGN(addr);
+
+	for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
+		/* At this point:  (!vmm || addr < vmm->vm_end). */
+		if (task_size - len < addr)
+			return -ENOMEM;
+		if (!vmm || addr + len <= vmm->vm_start)
+			return addr;
+		addr = vmm->vm_end;
+		if (do_color_align)
+			addr = COLOUR_ALIGN(addr, pgoff);
+	}
+}
+
+/* common code for old and new mmaps */
+static inline unsigned long
+do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
+        unsigned long flags, unsigned long fd, unsigned long pgoff)
+{
+	unsigned long error = -EBADF;
+	struct file * file = NULL;
+
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+	if (!(flags & MAP_ANONYMOUS)) {
+		file = fget(fd);
+		if (!file)
+			goto out;
+	}
+
+	down_write(&current->mm->mmap_sem);
+	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+	up_write(&current->mm->mmap_sem);
+
+	if (file)
+		fput(file);
+out:
+	return error;
+}
+
+asmlinkage unsigned long
+old_mmap(unsigned long addr, unsigned long len, int prot,
+	int flags, int fd, off_t offset)
+{
+	unsigned long result;
+
+	result = -EINVAL;
+	if (offset & ~PAGE_MASK)
+		goto out;
+
+	result = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+
+out:
+	return result;
+}
+
+asmlinkage unsigned long
+sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
+          unsigned long flags, unsigned long fd, unsigned long pgoff)
+{
+	return do_mmap2(addr, len, prot, flags, fd, pgoff);
+}
+
+save_static_function(sys_fork);
+__attribute_used__ noinline static int
+_sys_fork(nabi_no_regargs struct pt_regs regs)
+{
+	return do_fork(SIGCHLD, regs.regs[29], &regs, 0, NULL, NULL);
+}
+
+save_static_function(sys_clone);
+__attribute_used__ noinline static int
+_sys_clone(nabi_no_regargs struct pt_regs regs)
+{
+	unsigned long clone_flags;
+	unsigned long newsp;
+	int *parent_tidptr, *child_tidptr;
+
+	clone_flags = regs.regs[4];
+	newsp = regs.regs[5];
+	if (!newsp)
+		newsp = regs.regs[29];
+	parent_tidptr = (int *) regs.regs[6];
+	child_tidptr = (int *) regs.regs[7];
+	return do_fork(clone_flags, newsp, &regs, 0,
+	               parent_tidptr, child_tidptr);
+}
+
+/*
+ * sys_execve() executes a new program.
+ */
+asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs)
+{
+	int error;
+	char * filename;
+
+	filename = getname((char *) (long)regs.regs[4]);
+	error = PTR_ERR(filename);
+	if (IS_ERR(filename))
+		goto out;
+	error = do_execve(filename, (char **) (long)regs.regs[5],
+	                  (char **) (long)regs.regs[6], &regs);
+	putname(filename);
+
+out:
+	return error;
+}
+
+/*
+ * Compacrapability ...
+ */
+asmlinkage int sys_uname(struct old_utsname * name)
+{
+	if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
+		return 0;
+	return -EFAULT;
+}
+
+/*
+ * Compacrapability ...
+ */
+asmlinkage int sys_olduname(struct oldold_utsname * name)
+{
+	int error;
+
+	if (!name)
+		return -EFAULT;
+	if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
+		return -EFAULT;
+
+	error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
+	error -= __put_user(0,name->sysname+__OLD_UTS_LEN);
+	error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
+	error -= __put_user(0,name->nodename+__OLD_UTS_LEN);
+	error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
+	error -= __put_user(0,name->release+__OLD_UTS_LEN);
+	error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
+	error -= __put_user(0,name->version+__OLD_UTS_LEN);
+	error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
+	error = __put_user(0,name->machine+__OLD_UTS_LEN);
+	error = error ? -EFAULT : 0;
+
+	return error;
+}
+
+asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3)
+{
+	int	tmp, len;
+	char	*name;
+
+	switch(cmd) {
+	case SETNAME: {
+		char nodename[__NEW_UTS_LEN + 1];
+
+		if (!capable(CAP_SYS_ADMIN))
+			return -EPERM;
+
+		name = (char *) arg1;
+
+		len = strncpy_from_user(nodename, name, __NEW_UTS_LEN);
+		if (len < 0)
+			return -EFAULT;
+
+		down_write(&uts_sem);
+		strncpy(system_utsname.nodename, nodename, len);
+		nodename[__NEW_UTS_LEN] = '\0';
+		strlcpy(system_utsname.nodename, nodename,
+		        sizeof(system_utsname.nodename));
+		up_write(&uts_sem);
+		return 0;
+	}
+
+	case MIPS_ATOMIC_SET:
+		printk(KERN_CRIT "How did I get here?\n");
+		return -EINVAL;
+
+	case MIPS_FIXADE:
+		tmp = current->thread.mflags & ~3;
+		current->thread.mflags = tmp | (arg1 & 3);
+		return 0;
+
+	case FLUSH_CACHE:
+		__flush_cache_all();
+		return 0;
+
+	case MIPS_RDNVRAM:
+		return -EIO;
+	}
+
+	return -EINVAL;
+}
+
+/*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+ * This is really horribly ugly.
+ */
+asmlinkage int sys_ipc (uint call, int first, int second,
+			unsigned long third, void *ptr, long fifth)
+{
+	int version, ret;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	switch (call) {
+	case SEMOP:
+		return sys_semtimedop (first, (struct sembuf *)ptr, second,
+		                       NULL);
+	case SEMTIMEDOP:
+		return sys_semtimedop (first, (struct sembuf *)ptr, second,
+		                       (const struct timespec __user *)fifth);
+	case SEMGET:
+		return sys_semget (first, second, third);
+	case SEMCTL: {
+		union semun fourth;
+		if (!ptr)
+			return -EINVAL;
+		if (get_user(fourth.__pad, (void **) ptr))
+			return -EFAULT;
+		return sys_semctl (first, second, third, fourth);
+	}
+
+	case MSGSND:
+		return sys_msgsnd (first, (struct msgbuf *) ptr,
+				   second, third);
+	case MSGRCV:
+		switch (version) {
+		case 0: {
+			struct ipc_kludge tmp;
+			if (!ptr)
+				return -EINVAL;
+
+			if (copy_from_user(&tmp,
+					   (struct ipc_kludge *) ptr,
+					   sizeof (tmp)))
+				return -EFAULT;
+			return sys_msgrcv (first, tmp.msgp, second,
+					   tmp.msgtyp, third);
+		}
+		default:
+			return sys_msgrcv (first,
+					   (struct msgbuf *) ptr,
+					   second, fifth, third);
+		}
+	case MSGGET:
+		return sys_msgget ((key_t) first, second);
+	case MSGCTL:
+		return sys_msgctl (first, second, (struct msqid_ds *) ptr);
+
+	case SHMAT:
+		switch (version) {
+		default: {
+			ulong raddr;
+			ret = do_shmat (first, (char *) ptr, second, &raddr);
+			if (ret)
+				return ret;
+			return put_user (raddr, (ulong *) third);
+		}
+		case 1:	/* iBCS2 emulator entry point */
+			if (!segment_eq(get_fs(), get_ds()))
+				return -EINVAL;
+			return do_shmat (first, (char *) ptr, second, (ulong *) third);
+		}
+	case SHMDT:
+		return sys_shmdt ((char *)ptr);
+	case SHMGET:
+		return sys_shmget (first, second, third);
+	case SHMCTL:
+		return sys_shmctl (first, second,
+				   (struct shmid_ds *) ptr);
+	default:
+		return -ENOSYS;
+	}
+}
+
+/*
+ * Native ABI that is O32 or N64 version
+ */
+asmlinkage long sys_shmat(int shmid, char __user *shmaddr,
+                          int shmflg, unsigned long *addr)
+{
+	unsigned long raddr;
+	int err;
+
+	err = do_shmat(shmid, shmaddr, shmflg, &raddr);
+	if (err)
+		return err;
+
+	return put_user(raddr, addr);
+}
+
+/*
+ * No implemented yet ...
+ */
+asmlinkage int sys_cachectl(char *addr, int nbytes, int op)
+{
+	return -ENOSYS;
+}
+
+/*
+ * If we ever come here the user sp is bad.  Zap the process right away.
+ * Due to the bad stack signaling wouldn't work.
+ */
+asmlinkage void bad_stack(void)
+{
+	do_exit(SIGSEGV);
+}
diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c
new file mode 100644
index 0000000..f3bf0e4
--- /dev/null
+++ b/arch/mips/kernel/sysirix.c
@@ -0,0 +1,2179 @@
+/*
+ * sysirix.c: IRIX system call emulation.
+ *
+ * Copyright (C) 1996 David S. Miller
+ * Copyright (C) 1997 Miguel de Icaza
+ * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/binfmts.h>
+#include <linux/highuid.h>
+#include <linux/pagemap.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/slab.h>
+#include <linux/swap.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/times.h>
+#include <linux/elf.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/utsname.h>
+#include <linux/file.h>
+#include <linux/vfs.h>
+#include <linux/namei.h>
+#include <linux/socket.h>
+#include <linux/security.h>
+#include <linux/syscalls.h>
+
+#include <asm/ptrace.h>
+#include <asm/page.h>
+#include <asm/uaccess.h>
+#include <asm/inventory.h>
+
+/* 2,191 lines of complete and utter shit coming up... */
+
+extern int max_threads;
+
+/* The sysmp commands supported thus far. */
+#define MP_NPROCS       	1 /* # processor in complex */
+#define MP_NAPROCS      	2 /* # active processors in complex */
+#define MP_PGSIZE           	14 /* Return system page size in v1. */
+
+asmlinkage int irix_sysmp(struct pt_regs *regs)
+{
+	unsigned long cmd;
+	int base = 0;
+	int error = 0;
+
+	if(regs->regs[2] == 1000)
+		base = 1;
+	cmd = regs->regs[base + 4];
+	switch(cmd) {
+	case MP_PGSIZE:
+		error = PAGE_SIZE;
+		break;
+	case MP_NPROCS:
+	case MP_NAPROCS:
+		error = num_online_cpus();
+		break;
+	default:
+		printk("SYSMP[%s:%d]: Unsupported opcode %d\n",
+		       current->comm, current->pid, (int)cmd);
+		error = -EINVAL;
+		break;
+	}
+
+	return error;
+}
+
+/* The prctl commands. */
+#define PR_MAXPROCS          1 /* Tasks/user. */
+#define PR_ISBLOCKED         2 /* If blocked, return 1. */
+#define PR_SETSTACKSIZE      3 /* Set largest task stack size. */
+#define PR_GETSTACKSIZE      4 /* Get largest task stack size. */
+#define PR_MAXPPROCS         5 /* Num parallel tasks. */
+#define PR_UNBLKONEXEC       6 /* When task exec/exit's, unblock. */
+#define PR_SETEXITSIG        8 /* When task exit's, set signal. */
+#define PR_RESIDENT          9 /* Make task unswappable. */
+#define PR_ATTACHADDR       10 /* (Re-)Connect a vma to a task. */
+#define PR_DETACHADDR       11 /* Disconnect a vma from a task. */
+#define PR_TERMCHILD        12 /* When parent sleeps with fishes, kill child. */
+#define PR_GETSHMASK        13 /* Get the sproc() share mask. */
+#define PR_GETNSHARE        14 /* Number of share group members. */
+#define PR_COREPID          15 /* Add task pid to name when it core. */
+#define	PR_ATTACHADDRPERM   16 /* (Re-)Connect vma, with specified prot. */
+#define PR_PTHREADEXIT      17 /* Kill a pthread without prejudice. */
+
+asmlinkage int irix_prctl(struct pt_regs *regs)
+{
+	unsigned long cmd;
+	int error = 0, base = 0;
+
+	if (regs->regs[2] == 1000)
+		base = 1;
+	cmd = regs->regs[base + 4];
+	switch (cmd) {
+	case PR_MAXPROCS:
+		printk("irix_prctl[%s:%d]: Wants PR_MAXPROCS\n",
+		       current->comm, current->pid);
+		error = max_threads;
+		break;
+
+	case PR_ISBLOCKED: {
+		struct task_struct *task;
+
+		printk("irix_prctl[%s:%d]: Wants PR_ISBLOCKED\n",
+		       current->comm, current->pid);
+		read_lock(&tasklist_lock);
+		task = find_task_by_pid(regs->regs[base + 5]);
+		error = -ESRCH;
+		if (error)
+			error = (task->run_list.next != NULL);
+		read_unlock(&tasklist_lock);
+		/* Can _your_ OS find this out that fast? */
+		break;
+	}
+
+	case PR_SETSTACKSIZE: {
+		long value = regs->regs[base + 5];
+
+		printk("irix_prctl[%s:%d]: Wants PR_SETSTACKSIZE<%08lx>\n",
+		       current->comm, current->pid, (unsigned long) value);
+		if (value > RLIM_INFINITY)
+			value = RLIM_INFINITY;
+		if (capable(CAP_SYS_ADMIN)) {
+			task_lock(current->group_leader);
+			current->signal->rlim[RLIMIT_STACK].rlim_max =
+				current->signal->rlim[RLIMIT_STACK].rlim_cur = value;
+			task_unlock(current->group_leader);
+			error = value;
+			break;
+		}
+		task_lock(current->group_leader);
+		if (value > current->signal->rlim[RLIMIT_STACK].rlim_max) {
+			error = -EINVAL;
+			task_unlock(current->group_leader);
+			break;
+		}
+		current->signal->rlim[RLIMIT_STACK].rlim_cur = value;
+		task_unlock(current->group_leader);
+		error = value;
+		break;
+	}
+
+	case PR_GETSTACKSIZE:
+		printk("irix_prctl[%s:%d]: Wants PR_GETSTACKSIZE\n",
+		       current->comm, current->pid);
+		error = current->signal->rlim[RLIMIT_STACK].rlim_cur;
+		break;
+
+	case PR_MAXPPROCS:
+		printk("irix_prctl[%s:%d]: Wants PR_MAXPROCS\n",
+		       current->comm, current->pid);
+		error = 1;
+		break;
+
+	case PR_UNBLKONEXEC:
+		printk("irix_prctl[%s:%d]: Wants PR_UNBLKONEXEC\n",
+		       current->comm, current->pid);
+		error = -EINVAL;
+		break;
+
+	case PR_SETEXITSIG:
+		printk("irix_prctl[%s:%d]: Wants PR_SETEXITSIG\n",
+		       current->comm, current->pid);
+
+		/* We can probably play some game where we set the task
+		 * exit_code to some non-zero value when this is requested,
+		 * and check whether exit_code is already set in do_exit().
+		 */
+		error = -EINVAL;
+		break;
+
+	case PR_RESIDENT:
+		printk("irix_prctl[%s:%d]: Wants PR_RESIDENT\n",
+		       current->comm, current->pid);
+		error = 0; /* Compatibility indeed. */
+		break;
+
+	case PR_ATTACHADDR:
+		printk("irix_prctl[%s:%d]: Wants PR_ATTACHADDR\n",
+		       current->comm, current->pid);
+		error = -EINVAL;
+		break;
+
+	case PR_DETACHADDR:
+		printk("irix_prctl[%s:%d]: Wants PR_DETACHADDR\n",
+		       current->comm, current->pid);
+		error = -EINVAL;
+		break;
+
+	case PR_TERMCHILD:
+		printk("irix_prctl[%s:%d]: Wants PR_TERMCHILD\n",
+		       current->comm, current->pid);
+		error = -EINVAL;
+		break;
+
+	case PR_GETSHMASK:
+		printk("irix_prctl[%s:%d]: Wants PR_GETSHMASK\n",
+		       current->comm, current->pid);
+		error = -EINVAL; /* Until I have the sproc() stuff in. */
+		break;
+
+	case PR_GETNSHARE:
+		error = 0;       /* Until I have the sproc() stuff in. */
+		break;
+
+	case PR_COREPID:
+		printk("irix_prctl[%s:%d]: Wants PR_COREPID\n",
+		       current->comm, current->pid);
+		error = -EINVAL;
+		break;
+
+	case PR_ATTACHADDRPERM:
+		printk("irix_prctl[%s:%d]: Wants PR_ATTACHADDRPERM\n",
+		       current->comm, current->pid);
+		error = -EINVAL;
+		break;
+
+	case PR_PTHREADEXIT:
+		printk("irix_prctl[%s:%d]: Wants PR_PTHREADEXIT\n",
+		       current->comm, current->pid);
+		do_exit(regs->regs[base + 5]);
+
+	default:
+		printk("irix_prctl[%s:%d]: Non-existant opcode %d\n",
+		       current->comm, current->pid, (int)cmd);
+		error = -EINVAL;
+		break;
+	}
+
+	return error;
+}
+
+#undef DEBUG_PROCGRPS
+
+extern unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt);
+extern int getrusage(struct task_struct *p, int who, struct rusage __user *ru);
+extern char *prom_getenv(char *name);
+extern long prom_setenv(char *name, char *value);
+
+/* The syssgi commands supported thus far. */
+#define SGI_SYSID         1       /* Return unique per-machine identifier. */
+#define SGI_INVENT        5       /* Fetch inventory  */
+#   define SGI_INV_SIZEOF 1
+#   define SGI_INV_READ   2
+#define SGI_RDNAME        6       /* Return string name of a process. */
+#define SGI_SETNVRAM	  8	  /* Set PROM variable. */
+#define SGI_GETNVRAM	  9	  /* Get PROM variable. */
+#define SGI_SETPGID      21       /* Set process group id. */
+#define SGI_SYSCONF      22       /* POSIX sysconf garbage. */
+#define SGI_PATHCONF     24       /* POSIX sysconf garbage. */
+#define SGI_SETGROUPS    40       /* POSIX sysconf garbage. */
+#define SGI_GETGROUPS    41       /* POSIX sysconf garbage. */
+#define SGI_RUSAGE       56       /* BSD style rusage(). */
+#define SGI_SSYNC        62       /* Synchronous fs sync. */
+#define SGI_GETSID       65       /* SysVr4 get session id. */
+#define SGI_ELFMAP       68       /* Map an elf image. */
+#define SGI_TOSSTSAVE   108       /* Toss saved vma's. */
+#define SGI_FP_BCOPY    129       /* Should FPU bcopy be used on this machine? */
+#define SGI_PHYSP      1011       /* Translate virtual into physical page. */
+
+asmlinkage int irix_syssgi(struct pt_regs *regs)
+{
+	unsigned long cmd;
+	int retval, base = 0;
+
+	if (regs->regs[2] == 1000)
+		base = 1;
+
+	cmd = regs->regs[base + 4];
+	switch(cmd) {
+	case SGI_SYSID: {
+		char *buf = (char *) regs->regs[base + 5];
+
+		/* XXX Use ethernet addr.... */
+		retval = clear_user(buf, 64);
+		break;
+	}
+#if 0
+	case SGI_RDNAME: {
+		int pid = (int) regs->regs[base + 5];
+		char *buf = (char *) regs->regs[base + 6];
+		struct task_struct *p;
+		char tcomm[sizeof(current->comm)];
+
+		if (!access_ok(VERIFY_WRITE, buf, sizeof(tcomm))) {
+			retval = -EFAULT;
+			break;
+		}
+		read_lock(&tasklist_lock);
+		p = find_task_by_pid(pid);
+		if (!p) {
+			read_unlock(&tasklist_lock);
+			retval = -ESRCH;
+			break;
+		}
+		get_task_comm(tcomm, p);
+		read_unlock(&tasklist_lock);
+
+		/* XXX Need to check sizes. */
+		copy_to_user(buf, tcomm, sizeof(tcomm));
+		retval = 0;
+		break;
+	}
+
+	case SGI_GETNVRAM: {
+		char *name = (char *) regs->regs[base+5];
+		char *buf = (char *) regs->regs[base+6];
+		char *value;
+		return -EINVAL;	/* til I fix it */
+		if (!access_ok(VERIFY_WRITE, buf, 128)) {
+			retval = -EFAULT;
+			break;
+		}
+		value = prom_getenv(name);	/* PROM lock?  */
+		if (!value) {
+			retval = -EINVAL;
+			break;
+		}
+		/* Do I strlen() for the length? */
+		copy_to_user(buf, value, 128);
+		retval = 0;
+		break;
+	}
+
+	case SGI_SETNVRAM: {
+		char *name = (char *) regs->regs[base+5];
+		char *value = (char *) regs->regs[base+6];
+		return -EINVAL;	/* til I fix it */
+		retval = prom_setenv(name, value);
+		/* XXX make sure retval conforms to syssgi(2) */
+		printk("[%s:%d] setnvram(\"%s\", \"%s\"): retval %d",
+		       current->comm, current->pid, name, value, retval);
+/*		if (retval == PROM_ENOENT)
+		  	retval = -ENOENT; */
+		break;
+	}
+#endif
+
+	case SGI_SETPGID: {
+#ifdef DEBUG_PROCGRPS
+		printk("[%s:%d] setpgid(%d, %d) ",
+		       current->comm, current->pid,
+		       (int) regs->regs[base + 5], (int)regs->regs[base + 6]);
+#endif
+		retval = sys_setpgid(regs->regs[base + 5], regs->regs[base + 6]);
+
+#ifdef DEBUG_PROCGRPS
+		printk("retval=%d\n", retval);
+#endif
+	}
+
+	case SGI_SYSCONF: {
+		switch(regs->regs[base + 5]) {
+		case 1:
+			retval = (MAX_ARG_PAGES >> 4); /* XXX estimate... */
+			goto out;
+		case 2:
+			retval = max_threads;
+			goto out;
+		case 3:
+			retval = HZ;
+			goto out;
+		case 4:
+			retval = NGROUPS_MAX;
+			goto out;
+		case 5:
+			retval = NR_OPEN;
+			goto out;
+		case 6:
+			retval = 1;
+			goto out;
+		case 7:
+			retval = 1;
+			goto out;
+		case 8:
+			retval = 199009;
+			goto out;
+		case 11:
+			retval = PAGE_SIZE;
+			goto out;
+		case 12:
+			retval = 4;
+			goto out;
+		case 25:
+		case 26:
+		case 27:
+		case 28:
+		case 29:
+		case 30:
+			retval = 0;
+			goto out;
+		case 31:
+			retval = 32;
+			goto out;
+		default:
+			retval = -EINVAL;
+			goto out;
+		};
+	}
+
+	case SGI_SETGROUPS:
+		retval = sys_setgroups((int) regs->regs[base + 5],
+		                       (gid_t *) regs->regs[base + 6]);
+		break;
+
+	case SGI_GETGROUPS:
+		retval = sys_getgroups((int) regs->regs[base + 5],
+		                       (gid_t *) regs->regs[base + 6]);
+		break;
+
+	case SGI_RUSAGE: {
+		struct rusage *ru = (struct rusage *) regs->regs[base + 6];
+
+		switch((int) regs->regs[base + 5]) {
+		case 0:
+			/* rusage self */
+			retval = getrusage(current, RUSAGE_SELF, ru);
+			goto out;
+
+		case -1:
+			/* rusage children */
+			retval = getrusage(current, RUSAGE_CHILDREN, ru);
+			goto out;
+
+		default:
+			retval = -EINVAL;
+			goto out;
+		};
+	}
+
+	case SGI_SSYNC:
+		sys_sync();
+		retval = 0;
+		break;
+
+	case SGI_GETSID:
+#ifdef DEBUG_PROCGRPS
+		printk("[%s:%d] getsid(%d) ", current->comm, current->pid,
+		       (int) regs->regs[base + 5]);
+#endif
+		retval = sys_getsid(regs->regs[base + 5]);
+#ifdef DEBUG_PROCGRPS
+		printk("retval=%d\n", retval);
+#endif
+		break;
+
+	case SGI_ELFMAP:
+		retval = irix_mapelf((int) regs->regs[base + 5],
+				     (struct elf_phdr *) regs->regs[base + 6],
+				     (int) regs->regs[base + 7]);
+		break;
+
+	case SGI_TOSSTSAVE:
+		/* XXX We don't need to do anything? */
+		retval = 0;
+		break;
+
+	case SGI_FP_BCOPY:
+		retval = 0;
+		break;
+
+	case SGI_PHYSP: {
+		unsigned long addr = regs->regs[base + 5];
+		int *pageno = (int *) (regs->regs[base + 6]);
+		struct mm_struct *mm = current->mm;
+		pgd_t *pgdp;
+		pmd_t *pmdp;
+		pte_t *ptep;
+
+		if (!access_ok(VERIFY_WRITE, pageno, sizeof(int)))
+			return -EFAULT;
+
+		down_read(&mm->mmap_sem);
+		pgdp = pgd_offset(mm, addr);
+		pmdp = pmd_offset(pgdp, addr);
+		ptep = pte_offset(pmdp, addr);
+		retval = -EINVAL;
+		if (ptep) {
+			pte_t pte = *ptep;
+
+			if (pte_val(pte) & (_PAGE_VALID | _PAGE_PRESENT)) {
+				retval =  put_user((pte_val(pte) & PAGE_MASK) >>
+				                   PAGE_SHIFT, pageno);
+			}
+		}
+		up_read(&mm->mmap_sem);
+		break;
+	}
+
+	case SGI_INVENT: {
+		int  arg1    = (int)    regs->regs [base + 5];
+		void *buffer = (void *) regs->regs [base + 6];
+		int  count   = (int)    regs->regs [base + 7];
+
+		switch (arg1) {
+		case SGI_INV_SIZEOF:
+			retval = sizeof (inventory_t);
+			break;
+		case SGI_INV_READ:
+			retval = dump_inventory_to_user (buffer, count);
+			break;
+		default:
+			retval = -EINVAL;
+		}
+		break;
+	}
+
+	default:
+		printk("irix_syssgi: Unsupported command %d\n", (int)cmd);
+		retval = -EINVAL;
+		break;
+	};
+
+out:
+	return retval;
+}
+
+asmlinkage int irix_gtime(struct pt_regs *regs)
+{
+	return get_seconds();
+}
+
+/*
+ * IRIX is completely broken... it returns 0 on success, otherwise
+ * ENOMEM.
+ */
+asmlinkage int irix_brk(unsigned long brk)
+{
+	unsigned long rlim;
+	unsigned long newbrk, oldbrk;
+	struct mm_struct *mm = current->mm;
+	int ret;
+
+	down_write(&mm->mmap_sem);
+	if (brk < mm->end_code) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	newbrk = PAGE_ALIGN(brk);
+	oldbrk = PAGE_ALIGN(mm->brk);
+	if (oldbrk == newbrk) {
+		mm->brk = brk;
+		ret = 0;
+		goto out;
+	}
+
+	/*
+	 * Always allow shrinking brk
+	 */
+	if (brk <= mm->brk) {
+		mm->brk = brk;
+		do_munmap(mm, newbrk, oldbrk-newbrk);
+		ret = 0;
+		goto out;
+	}
+	/*
+	 * Check against rlimit and stack..
+	 */
+	rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
+	if (rlim >= RLIM_INFINITY)
+		rlim = ~0;
+	if (brk - mm->end_code > rlim) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/*
+	 * Check against existing mmap mappings.
+	 */
+	if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE)) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/*
+	 * Check if we have enough memory..
+	 */
+	if (security_vm_enough_memory((newbrk-oldbrk) >> PAGE_SHIFT)) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/*
+	 * Ok, looks good - let it rip.
+	 */
+	mm->brk = brk;
+	do_brk(oldbrk, newbrk-oldbrk);
+	ret = 0;
+
+out:
+	up_write(&mm->mmap_sem);
+	return ret;
+}
+
+asmlinkage int irix_getpid(struct pt_regs *regs)
+{
+	regs->regs[3] = current->real_parent->pid;
+	return current->pid;
+}
+
+asmlinkage int irix_getuid(struct pt_regs *regs)
+{
+	regs->regs[3] = current->euid;
+	return current->uid;
+}
+
+asmlinkage int irix_getgid(struct pt_regs *regs)
+{
+	regs->regs[3] = current->egid;
+	return current->gid;
+}
+
+asmlinkage int irix_stime(int value)
+{
+	int err;
+	struct timespec tv;
+
+	tv.tv_sec = value;
+	tv.tv_nsec = 0;
+	err = security_settime(&tv, NULL);
+	if (err)
+		return err;
+
+	write_seqlock_irq(&xtime_lock);
+	xtime.tv_sec = value;
+	xtime.tv_nsec = 0;
+	time_adjust = 0;			/* stop active adjtime() */
+	time_status |= STA_UNSYNC;
+	time_maxerror = NTP_PHASE_LIMIT;
+	time_esterror = NTP_PHASE_LIMIT;
+	write_sequnlock_irq(&xtime_lock);
+
+	return 0;
+}
+
+static inline void jiffiestotv(unsigned long jiffies, struct timeval *value)
+{
+	value->tv_usec = (jiffies % HZ) * (1000000 / HZ);
+	value->tv_sec = jiffies / HZ;
+}
+
+static inline void getitimer_real(struct itimerval *value)
+{
+	register unsigned long val, interval;
+
+	interval = current->it_real_incr;
+	val = 0;
+	if (del_timer(&current->real_timer)) {
+		unsigned long now = jiffies;
+		val = current->real_timer.expires;
+		add_timer(&current->real_timer);
+		/* look out for negative/zero itimer.. */
+		if (val <= now)
+			val = now+1;
+		val -= now;
+	}
+	jiffiestotv(val, &value->it_value);
+	jiffiestotv(interval, &value->it_interval);
+}
+
+asmlinkage unsigned int irix_alarm(unsigned int seconds)
+{
+	struct itimerval it_new, it_old;
+	unsigned int oldalarm;
+
+	if (!seconds) {
+		getitimer_real(&it_old);
+		del_timer(&current->real_timer);
+	} else {
+		it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0;
+		it_new.it_value.tv_sec = seconds;
+		it_new.it_value.tv_usec = 0;
+		do_setitimer(ITIMER_REAL, &it_new, &it_old);
+	}
+	oldalarm = it_old.it_value.tv_sec;
+	/*
+	 * ehhh.. We can't return 0 if we have an alarm pending ...
+	 * And we'd better return too much than too little anyway
+	 */
+	if (it_old.it_value.tv_usec)
+		oldalarm++;
+
+	return oldalarm;
+}
+
+asmlinkage int irix_pause(void)
+{
+	current->state = TASK_INTERRUPTIBLE;
+	schedule();
+
+	return -EINTR;
+}
+
+/* XXX need more than this... */
+asmlinkage int irix_mount(char *dev_name, char *dir_name, unsigned long flags,
+			  char *type, void *data, int datalen)
+{
+	printk("[%s:%d] irix_mount(%p,%p,%08lx,%p,%p,%d)\n",
+	       current->comm, current->pid,
+	       dev_name, dir_name, flags, type, data, datalen);
+
+	return sys_mount(dev_name, dir_name, type, flags, data);
+}
+
+struct irix_statfs {
+	short f_type;
+        long  f_bsize, f_frsize, f_blocks, f_bfree, f_files, f_ffree;
+	char  f_fname[6], f_fpack[6];
+};
+
+asmlinkage int irix_statfs(const char *path, struct irix_statfs *buf,
+			   int len, int fs_type)
+{
+	struct nameidata nd;
+	struct kstatfs kbuf;
+	int error, i;
+
+	/* We don't support this feature yet. */
+	if (fs_type) {
+		error = -EINVAL;
+		goto out;
+	}
+	if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statfs))) {
+		error = -EFAULT;
+		goto out;
+	}
+	error = user_path_walk(path, &nd);
+	if (error)
+		goto out;
+
+	error = vfs_statfs(nd.dentry->d_inode->i_sb, &kbuf);
+	if (error)
+		goto dput_and_out;
+
+	__put_user(kbuf.f_type, &buf->f_type);
+	__put_user(kbuf.f_bsize, &buf->f_bsize);
+	__put_user(kbuf.f_frsize, &buf->f_frsize);
+	__put_user(kbuf.f_blocks, &buf->f_blocks);
+	__put_user(kbuf.f_bfree, &buf->f_bfree);
+	__put_user(kbuf.f_files, &buf->f_files);
+	__put_user(kbuf.f_ffree, &buf->f_ffree);
+	for (i = 0; i < 6; i++) {
+		__put_user(0, &buf->f_fname[i]);
+		__put_user(0, &buf->f_fpack[i]);
+	}
+	error = 0;
+
+dput_and_out:
+	path_release(&nd);
+out:
+	return error;
+}
+
+asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf)
+{
+	struct kstatfs kbuf;
+	struct file *file;
+	int error, i;
+
+	if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statfs))) {
+		error = -EFAULT;
+		goto out;
+	}
+	if (!(file = fget(fd))) {
+		error = -EBADF;
+		goto out;
+	}
+
+	error = vfs_statfs(file->f_dentry->d_inode->i_sb, &kbuf);
+	if (error)
+		goto out_f;
+
+	__put_user(kbuf.f_type, &buf->f_type);
+	__put_user(kbuf.f_bsize, &buf->f_bsize);
+	__put_user(kbuf.f_frsize, &buf->f_frsize);
+	__put_user(kbuf.f_blocks, &buf->f_blocks);
+	__put_user(kbuf.f_bfree, &buf->f_bfree);
+	__put_user(kbuf.f_files, &buf->f_files);
+	__put_user(kbuf.f_ffree, &buf->f_ffree);
+	for(i = 0; i < 6; i++) {
+		__put_user(0, &buf->f_fname[i]);
+		__put_user(0, &buf->f_fpack[i]);
+	}
+
+out_f:
+	fput(file);
+out:
+	return error;
+}
+
+asmlinkage int irix_setpgrp(int flags)
+{
+	int error;
+
+#ifdef DEBUG_PROCGRPS
+	printk("[%s:%d] setpgrp(%d) ", current->comm, current->pid, flags);
+#endif
+	if(!flags)
+		error = process_group(current);
+	else
+		error = sys_setsid();
+#ifdef DEBUG_PROCGRPS
+	printk("returning %d\n", process_group(current));
+#endif
+
+	return error;
+}
+
+asmlinkage int irix_times(struct tms * tbuf)
+{
+	int err = 0;
+
+	if (tbuf) {
+		if (!access_ok(VERIFY_WRITE,tbuf,sizeof *tbuf))
+			return -EFAULT;
+		err |= __put_user(current->utime, &tbuf->tms_utime);
+		err |= __put_user(current->stime, &tbuf->tms_stime);
+		err |= __put_user(current->signal->cutime, &tbuf->tms_cutime);
+		err |= __put_user(current->signal->cstime, &tbuf->tms_cstime);
+	}
+
+	return err;
+}
+
+asmlinkage int irix_exec(struct pt_regs *regs)
+{
+	int error, base = 0;
+	char *filename;
+
+	if(regs->regs[2] == 1000)
+		base = 1;
+	filename = getname((char *) (long)regs->regs[base + 4]);
+	error = PTR_ERR(filename);
+	if (IS_ERR(filename))
+		return error;
+
+	error = do_execve(filename, (char **) (long)regs->regs[base + 5],
+	                  (char **) 0, regs);
+	putname(filename);
+
+	return error;
+}
+
+asmlinkage int irix_exece(struct pt_regs *regs)
+{
+	int error, base = 0;
+	char *filename;
+
+	if (regs->regs[2] == 1000)
+		base = 1;
+	filename = getname((char *) (long)regs->regs[base + 4]);
+	error = PTR_ERR(filename);
+	if (IS_ERR(filename))
+		return error;
+	error = do_execve(filename, (char **) (long)regs->regs[base + 5],
+	                  (char **) (long)regs->regs[base + 6], regs);
+	putname(filename);
+
+	return error;
+}
+
+asmlinkage unsigned long irix_gethostid(void)
+{
+	printk("[%s:%d]: irix_gethostid() called...\n",
+	       current->comm, current->pid);
+
+	return -EINVAL;
+}
+
+asmlinkage unsigned long irix_sethostid(unsigned long val)
+{
+	printk("[%s:%d]: irix_sethostid(%08lx) called...\n",
+	       current->comm, current->pid, val);
+
+	return -EINVAL;
+}
+
+asmlinkage int irix_socket(int family, int type, int protocol)
+{
+	switch(type) {
+	case 1:
+		type = SOCK_DGRAM;
+		break;
+
+	case 2:
+		type = SOCK_STREAM;
+		break;
+
+	case 3:
+		type = 9; /* Invalid... */
+		break;
+
+	case 4:
+		type = SOCK_RAW;
+		break;
+
+	case 5:
+		type = SOCK_RDM;
+		break;
+
+	case 6:
+		type = SOCK_SEQPACKET;
+		break;
+
+	default:
+		break;
+	}
+
+	return sys_socket(family, type, protocol);
+}
+
+asmlinkage int irix_getdomainname(char *name, int len)
+{
+	int error;
+
+	if (!access_ok(VERIFY_WRITE, name, len))
+		return -EFAULT;
+
+	down_read(&uts_sem);
+	if (len > __NEW_UTS_LEN)
+		len = __NEW_UTS_LEN;
+	error = 0;
+	if (copy_to_user(name, system_utsname.domainname, len))
+		error = -EFAULT;
+	up_read(&uts_sem);
+
+	return error;
+}
+
+asmlinkage unsigned long irix_getpagesize(void)
+{
+	return PAGE_SIZE;
+}
+
+asmlinkage int irix_msgsys(int opcode, unsigned long arg0, unsigned long arg1,
+			   unsigned long arg2, unsigned long arg3,
+			   unsigned long arg4)
+{
+	switch (opcode) {
+	case 0:
+		return sys_msgget((key_t) arg0, (int) arg1);
+	case 1:
+		return sys_msgctl((int) arg0, (int) arg1, (struct msqid_ds *)arg2);
+	case 2:
+		return sys_msgrcv((int) arg0, (struct msgbuf *) arg1,
+				  (size_t) arg2, (long) arg3, (int) arg4);
+	case 3:
+		return sys_msgsnd((int) arg0, (struct msgbuf *) arg1,
+				  (size_t) arg2, (int) arg3);
+	default:
+		return -EINVAL;
+	}
+}
+
+asmlinkage int irix_shmsys(int opcode, unsigned long arg0, unsigned long arg1,
+			   unsigned long arg2, unsigned long arg3)
+{
+	switch (opcode) {
+	case 0:
+		return do_shmat((int) arg0, (char *)arg1, (int) arg2,
+				 (unsigned long *) arg3);
+	case 1:
+		return sys_shmctl((int)arg0, (int)arg1, (struct shmid_ds *)arg2);
+	case 2:
+		return sys_shmdt((char *)arg0);
+	case 3:
+		return sys_shmget((key_t) arg0, (int) arg1, (int) arg2);
+	default:
+		return -EINVAL;
+	}
+}
+
+asmlinkage int irix_semsys(int opcode, unsigned long arg0, unsigned long arg1,
+			   unsigned long arg2, int arg3)
+{
+	switch (opcode) {
+	case 0:
+		return sys_semctl((int) arg0, (int) arg1, (int) arg2,
+				  (union semun) arg3);
+	case 1:
+		return sys_semget((key_t) arg0, (int) arg1, (int) arg2);
+	case 2:
+		return sys_semop((int) arg0, (struct sembuf *)arg1,
+				 (unsigned int) arg2);
+	default:
+		return -EINVAL;
+	}
+}
+
+static inline loff_t llseek(struct file *file, loff_t offset, int origin)
+{
+	loff_t (*fn)(struct file *, loff_t, int);
+	loff_t retval;
+
+	fn = default_llseek;
+	if (file->f_op && file->f_op->llseek)
+        fn = file->f_op->llseek;
+	lock_kernel();
+	retval = fn(file, offset, origin);
+	unlock_kernel();
+	return retval;
+}
+
+asmlinkage int irix_lseek64(int fd, int _unused, int offhi, int offlow,
+                            int origin)
+{
+	int retval;
+	struct file * file;
+	loff_t offset;
+
+	retval = -EBADF;
+	file = fget(fd);
+	if (!file)
+		goto bad;
+	retval = -EINVAL;
+	if (origin > 2)
+		goto out_putf;
+
+	offset = llseek(file, ((loff_t) offhi << 32) | offlow, origin);
+	retval = (int) offset;
+
+out_putf:
+	fput(file);
+bad:
+	return retval;
+}
+
+asmlinkage int irix_sginap(int ticks)
+{
+	current->state = TASK_INTERRUPTIBLE;
+	schedule_timeout(ticks);
+	return 0;
+}
+
+asmlinkage int irix_sgikopt(char *istring, char *ostring, int len)
+{
+	return -EINVAL;
+}
+
+asmlinkage int irix_gettimeofday(struct timeval *tv)
+{
+	time_t sec;
+	long nsec, seq;
+	int err;
+
+	if (!access_ok(VERIFY_WRITE, tv, sizeof(struct timeval)))
+		return -EFAULT;
+
+	do {
+		seq = read_seqbegin(&xtime_lock);
+		sec = xtime.tv_sec;
+		nsec = xtime.tv_nsec;
+	} while (read_seqretry(&xtime_lock, seq));
+
+	err = __put_user(sec, &tv->tv_sec);
+	err |= __put_user((nsec / 1000), &tv->tv_usec);
+
+	return err;
+}
+
+#define IRIX_MAP_AUTOGROW 0x40
+
+asmlinkage unsigned long irix_mmap32(unsigned long addr, size_t len, int prot,
+				     int flags, int fd, off_t offset)
+{
+	struct file *file = NULL;
+	unsigned long retval;
+
+	if (!(flags & MAP_ANONYMOUS)) {
+		if (!(file = fget(fd)))
+			return -EBADF;
+
+		/* Ok, bad taste hack follows, try to think in something else
+		 * when reading this.  */
+		if (flags & IRIX_MAP_AUTOGROW) {
+			unsigned long old_pos;
+			long max_size = offset + len;
+
+			if (max_size > file->f_dentry->d_inode->i_size) {
+				old_pos = sys_lseek (fd, max_size - 1, 0);
+				sys_write (fd, "", 1);
+				sys_lseek (fd, old_pos, 0);
+			}
+		}
+	}
+
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+	down_write(&current->mm->mmap_sem);
+	retval = do_mmap(file, addr, len, prot, flags, offset);
+	up_write(&current->mm->mmap_sem);
+	if (file)
+		fput(file);
+
+	return retval;
+}
+
+asmlinkage int irix_madvise(unsigned long addr, int len, int behavior)
+{
+	printk("[%s:%d] Wheee.. irix_madvise(%08lx,%d,%d)\n",
+	       current->comm, current->pid, addr, len, behavior);
+
+	return -EINVAL;
+}
+
+asmlinkage int irix_pagelock(char *addr, int len, int op)
+{
+	printk("[%s:%d] Wheee.. irix_pagelock(%p,%d,%d)\n",
+	       current->comm, current->pid, addr, len, op);
+
+	return -EINVAL;
+}
+
+asmlinkage int irix_quotactl(struct pt_regs *regs)
+{
+	printk("[%s:%d] Wheee.. irix_quotactl()\n",
+	       current->comm, current->pid);
+
+	return -EINVAL;
+}
+
+asmlinkage int irix_BSDsetpgrp(int pid, int pgrp)
+{
+	int error;
+
+#ifdef DEBUG_PROCGRPS
+	printk("[%s:%d] BSDsetpgrp(%d, %d) ", current->comm, current->pid,
+	       pid, pgrp);
+#endif
+	if(!pid)
+		pid = current->pid;
+
+	/* Wheee, weird sysv thing... */
+	if ((pgrp == 0) && (pid == current->pid))
+		error = sys_setsid();
+	else
+		error = sys_setpgid(pid, pgrp);
+
+#ifdef DEBUG_PROCGRPS
+	printk("error = %d\n", error);
+#endif
+
+	return error;
+}
+
+asmlinkage int irix_systeminfo(int cmd, char *buf, int cnt)
+{
+	printk("[%s:%d] Wheee.. irix_systeminfo(%d,%p,%d)\n",
+	       current->comm, current->pid, cmd, buf, cnt);
+
+	return -EINVAL;
+}
+
+struct iuname {
+	char sysname[257], nodename[257], release[257];
+	char version[257], machine[257];
+	char m_type[257], base_rel[257];
+	char _unused0[257], _unused1[257], _unused2[257];
+	char _unused3[257], _unused4[257], _unused5[257];
+};
+
+asmlinkage int irix_uname(struct iuname *buf)
+{
+	down_read(&uts_sem);
+	if (copy_to_user(system_utsname.sysname, buf->sysname, 65)
+	    || copy_to_user(system_utsname.nodename, buf->nodename, 65)
+	    || copy_to_user(system_utsname.release, buf->release, 65)
+	    || copy_to_user(system_utsname.version, buf->version, 65)
+	    || copy_to_user(system_utsname.machine, buf->machine, 65)) {
+		return -EFAULT;
+	}
+	up_read(&uts_sem);
+
+	return 1;
+}
+
+#undef DEBUG_XSTAT
+
+static int irix_xstat32_xlate(struct kstat *stat, void *ubuf)
+{
+	struct xstat32 {
+		u32 st_dev, st_pad1[3], st_ino, st_mode, st_nlink, st_uid, st_gid;
+		u32 st_rdev, st_pad2[2], st_size, st_pad3;
+		u32 st_atime0, st_atime1;
+		u32 st_mtime0, st_mtime1;
+		u32 st_ctime0, st_ctime1;
+		u32 st_blksize, st_blocks;
+		char st_fstype[16];
+		u32 st_pad4[8];
+	} ub;
+
+	if (!sysv_valid_dev(stat->dev) || !sysv_valid_dev(stat->rdev))
+		return -EOVERFLOW;
+	ub.st_dev     = sysv_encode_dev(stat->dev);
+	ub.st_ino     = stat->ino;
+	ub.st_mode    = stat->mode;
+	ub.st_nlink   = stat->nlink;
+	SET_UID(ub.st_uid, stat->uid);
+	SET_GID(ub.st_gid, stat->gid);
+	ub.st_rdev    = sysv_encode_dev(stat->rdev);
+#if BITS_PER_LONG == 32
+	if (stat->size > MAX_NON_LFS)
+		return -EOVERFLOW;
+#endif
+	ub.st_size    = stat->size;
+	ub.st_atime0  = stat->atime.tv_sec;
+	ub.st_atime1  = stat->atime.tv_nsec;
+	ub.st_mtime0  = stat->mtime.tv_sec;
+	ub.st_mtime1  = stat->atime.tv_nsec;
+	ub.st_ctime0  = stat->ctime.tv_sec;
+	ub.st_ctime1  = stat->atime.tv_nsec;
+	ub.st_blksize = stat->blksize;
+	ub.st_blocks  = stat->blocks;
+	strcpy (ub.st_fstype, "efs");
+
+	return copy_to_user(ubuf, &ub, sizeof(ub)) ? -EFAULT : 0;
+}
+
+static int irix_xstat64_xlate(struct kstat *stat, void *ubuf)
+{
+	struct xstat64 {
+		u32 st_dev; s32 st_pad1[3];
+		unsigned long long st_ino;
+		u32 st_mode;
+		u32 st_nlink; s32 st_uid; s32 st_gid; u32 st_rdev;
+		s32 st_pad2[2];
+		long long st_size;
+		s32 st_pad3;
+		struct { s32 tv_sec, tv_nsec; } st_atime, st_mtime, st_ctime;
+		s32 st_blksize;
+		long long  st_blocks;
+		char st_fstype[16];
+		s32 st_pad4[8];
+	} ks;
+
+	if (!sysv_valid_dev(stat->dev) || !sysv_valid_dev(stat->rdev))
+		return -EOVERFLOW;
+
+	ks.st_dev = sysv_encode_dev(stat->dev);
+	ks.st_pad1[0] = ks.st_pad1[1] = ks.st_pad1[2] = 0;
+	ks.st_ino = (unsigned long long) stat->ino;
+	ks.st_mode = (u32) stat->mode;
+	ks.st_nlink = (u32) stat->nlink;
+	ks.st_uid = (s32) stat->uid;
+	ks.st_gid = (s32) stat->gid;
+	ks.st_rdev = sysv_encode_dev (stat->rdev);
+	ks.st_pad2[0] = ks.st_pad2[1] = 0;
+	ks.st_size = (long long) stat->size;
+	ks.st_pad3 = 0;
+
+	/* XXX hackety hack... */
+	ks.st_atime.tv_sec = (s32) stat->atime.tv_sec;
+	ks.st_atime.tv_nsec = stat->atime.tv_nsec;
+	ks.st_mtime.tv_sec = (s32) stat->mtime.tv_sec;
+	ks.st_mtime.tv_nsec = stat->mtime.tv_nsec;
+	ks.st_ctime.tv_sec = (s32) stat->ctime.tv_sec;
+	ks.st_ctime.tv_nsec = stat->ctime.tv_nsec;
+
+	ks.st_blksize = (s32) stat->blksize;
+	ks.st_blocks = (long long) stat->blocks;
+	memset(ks.st_fstype, 0, 16);
+	ks.st_pad4[0] = ks.st_pad4[1] = ks.st_pad4[2] = ks.st_pad4[3] = 0;
+	ks.st_pad4[4] = ks.st_pad4[5] = ks.st_pad4[6] = ks.st_pad4[7] = 0;
+
+	/* Now write it all back. */
+	return copy_to_user(ubuf, &ks, sizeof(ks)) ? -EFAULT : 0;
+}
+
+asmlinkage int irix_xstat(int version, char *filename, struct stat *statbuf)
+{
+	int retval;
+	struct kstat stat;
+
+#ifdef DEBUG_XSTAT
+	printk("[%s:%d] Wheee.. irix_xstat(%d,%s,%p) ",
+	       current->comm, current->pid, version, filename, statbuf);
+#endif
+
+	retval = vfs_stat(filename, &stat);
+	if (!retval) {
+		switch(version) {
+			case 2:
+				retval = irix_xstat32_xlate(&stat, statbuf);
+				break;
+			case 3:
+				retval = irix_xstat64_xlate(&stat, statbuf);
+				break;
+			default:
+				retval = -EINVAL;
+		}
+	}
+	return retval;
+}
+
+asmlinkage int irix_lxstat(int version, char *filename, struct stat *statbuf)
+{
+	int error;
+	struct kstat stat;
+
+#ifdef DEBUG_XSTAT
+	printk("[%s:%d] Wheee.. irix_lxstat(%d,%s,%p) ",
+	       current->comm, current->pid, version, filename, statbuf);
+#endif
+
+	error = vfs_lstat(filename, &stat);
+
+	if (!error) {
+		switch (version) {
+			case 2:
+				error = irix_xstat32_xlate(&stat, statbuf);
+				break;
+			case 3:
+				error = irix_xstat64_xlate(&stat, statbuf);
+				break;
+			default:
+				error = -EINVAL;
+		}
+	}
+	return error;
+}
+
+asmlinkage int irix_fxstat(int version, int fd, struct stat *statbuf)
+{
+	int error;
+	struct kstat stat;
+
+#ifdef DEBUG_XSTAT
+	printk("[%s:%d] Wheee.. irix_fxstat(%d,%d,%p) ",
+	       current->comm, current->pid, version, fd, statbuf);
+#endif
+
+	error = vfs_fstat(fd, &stat);
+	if (!error) {
+		switch (version) {
+			case 2:
+				error = irix_xstat32_xlate(&stat, statbuf);
+				break;
+			case 3:
+				error = irix_xstat64_xlate(&stat, statbuf);
+				break;
+			default:
+				error = -EINVAL;
+		}
+	}
+	return error;
+}
+
+asmlinkage int irix_xmknod(int ver, char *filename, int mode, unsigned dev)
+{
+	int retval;
+	printk("[%s:%d] Wheee.. irix_xmknod(%d,%s,%x,%x)\n",
+	       current->comm, current->pid, ver, filename, mode, dev);
+
+	switch(ver) {
+	case 2:
+		/* shouldn't we convert here as well as on stat()? */
+		retval = sys_mknod(filename, mode, dev);
+		break;
+
+	default:
+		retval = -EINVAL;
+		break;
+	};
+
+	return retval;
+}
+
+asmlinkage int irix_swapctl(int cmd, char *arg)
+{
+	printk("[%s:%d] Wheee.. irix_swapctl(%d,%p)\n",
+	       current->comm, current->pid, cmd, arg);
+
+	return -EINVAL;
+}
+
+struct irix_statvfs {
+	u32 f_bsize; u32 f_frsize; u32 f_blocks;
+	u32 f_bfree; u32 f_bavail; u32 f_files; u32 f_ffree; u32 f_favail;
+	u32 f_fsid; char f_basetype[16];
+	u32 f_flag; u32 f_namemax;
+	char	f_fstr[32]; u32 f_filler[16];
+};
+
+asmlinkage int irix_statvfs(char *fname, struct irix_statvfs *buf)
+{
+	struct nameidata nd;
+	struct kstatfs kbuf;
+	int error, i;
+
+	printk("[%s:%d] Wheee.. irix_statvfs(%s,%p)\n",
+	       current->comm, current->pid, fname, buf);
+	if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs))) {
+		error = -EFAULT;
+		goto out;
+	}
+	error = user_path_walk(fname, &nd);
+	if (error)
+		goto out;
+	error = vfs_statfs(nd.dentry->d_inode->i_sb, &kbuf);
+	if (error)
+		goto dput_and_out;
+
+	__put_user(kbuf.f_bsize, &buf->f_bsize);
+	__put_user(kbuf.f_frsize, &buf->f_frsize);
+	__put_user(kbuf.f_blocks, &buf->f_blocks);
+	__put_user(kbuf.f_bfree, &buf->f_bfree);
+	__put_user(kbuf.f_bfree, &buf->f_bavail);  /* XXX hackety hack... */
+	__put_user(kbuf.f_files, &buf->f_files);
+	__put_user(kbuf.f_ffree, &buf->f_ffree);
+	__put_user(kbuf.f_ffree, &buf->f_favail);  /* XXX hackety hack... */
+#ifdef __MIPSEB__
+	__put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
+#else
+	__put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
+#endif
+	for (i = 0; i < 16; i++)
+		__put_user(0, &buf->f_basetype[i]);
+	__put_user(0, &buf->f_flag);
+	__put_user(kbuf.f_namelen, &buf->f_namemax);
+	for (i = 0; i < 32; i++)
+		__put_user(0, &buf->f_fstr[i]);
+
+	error = 0;
+
+dput_and_out:
+	path_release(&nd);
+out:
+	return error;
+}
+
+asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf)
+{
+	struct kstatfs kbuf;
+	struct file *file;
+	int error, i;
+
+	printk("[%s:%d] Wheee.. irix_fstatvfs(%d,%p)\n",
+	       current->comm, current->pid, fd, buf);
+
+	if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs))) {
+		error = -EFAULT;
+		goto out;
+	}
+	if (!(file = fget(fd))) {
+		error = -EBADF;
+		goto out;
+	}
+	error = vfs_statfs(file->f_dentry->d_inode->i_sb, &kbuf);
+	if (error)
+		goto out_f;
+
+	__put_user(kbuf.f_bsize, &buf->f_bsize);
+	__put_user(kbuf.f_frsize, &buf->f_frsize);
+	__put_user(kbuf.f_blocks, &buf->f_blocks);
+	__put_user(kbuf.f_bfree, &buf->f_bfree);
+	__put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */
+	__put_user(kbuf.f_files, &buf->f_files);
+	__put_user(kbuf.f_ffree, &buf->f_ffree);
+	__put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */
+#ifdef __MIPSEB__
+	__put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
+#else
+	__put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
+#endif
+	for(i = 0; i < 16; i++)
+		__put_user(0, &buf->f_basetype[i]);
+	__put_user(0, &buf->f_flag);
+	__put_user(kbuf.f_namelen, &buf->f_namemax);
+	__clear_user(&buf->f_fstr, sizeof(buf->f_fstr));
+
+out_f:
+	fput(file);
+out:
+	return error;
+}
+
+asmlinkage int irix_priocntl(struct pt_regs *regs)
+{
+	printk("[%s:%d] Wheee.. irix_priocntl()\n",
+	       current->comm, current->pid);
+
+	return -EINVAL;
+}
+
+asmlinkage int irix_sigqueue(int pid, int sig, int code, int val)
+{
+	printk("[%s:%d] Wheee.. irix_sigqueue(%d,%d,%d,%d)\n",
+	       current->comm, current->pid, pid, sig, code, val);
+
+	return -EINVAL;
+}
+
+asmlinkage int irix_truncate64(char *name, int pad, int size1, int size2)
+{
+	int retval;
+
+	if (size1) {
+		retval = -EINVAL;
+		goto out;
+	}
+	retval = sys_truncate(name, size2);
+
+out:
+	return retval;
+}
+
+asmlinkage int irix_ftruncate64(int fd, int pad, int size1, int size2)
+{
+	int retval;
+
+	if (size1) {
+		retval = -EINVAL;
+		goto out;
+	}
+	retval = sys_ftruncate(fd, size2);
+
+out:
+	return retval;
+}
+
+asmlinkage int irix_mmap64(struct pt_regs *regs)
+{
+	int len, prot, flags, fd, off1, off2, error, base = 0;
+	unsigned long addr, pgoff, *sp;
+	struct file *file = NULL;
+
+	if (regs->regs[2] == 1000)
+		base = 1;
+	sp = (unsigned long *) (regs->regs[29] + 16);
+	addr = regs->regs[base + 4];
+	len = regs->regs[base + 5];
+	prot = regs->regs[base + 6];
+	if (!base) {
+		flags = regs->regs[base + 7];
+		if (!access_ok(VERIFY_READ, sp, (4 * sizeof(unsigned long)))) {
+			error = -EFAULT;
+			goto out;
+		}
+		fd = sp[0];
+		__get_user(off1, &sp[1]);
+		__get_user(off2, &sp[2]);
+	} else {
+		if (!access_ok(VERIFY_READ, sp, (5 * sizeof(unsigned long)))) {
+			error = -EFAULT;
+			goto out;
+		}
+		__get_user(flags, &sp[0]);
+		__get_user(fd, &sp[1]);
+		__get_user(off1, &sp[2]);
+		__get_user(off2, &sp[3]);
+	}
+
+	if (off1 & PAGE_MASK) {
+		error = -EOVERFLOW;
+		goto out;
+	}
+
+	pgoff = (off1 << (32 - PAGE_SHIFT)) | (off2 >> PAGE_SHIFT);
+
+	if (!(flags & MAP_ANONYMOUS)) {
+		if (!(file = fget(fd))) {
+			error = -EBADF;
+			goto out;
+		}
+
+		/* Ok, bad taste hack follows, try to think in something else
+		   when reading this */
+		if (flags & IRIX_MAP_AUTOGROW) {
+			unsigned long old_pos;
+			long max_size = off2 + len;
+
+			if (max_size > file->f_dentry->d_inode->i_size) {
+				old_pos = sys_lseek (fd, max_size - 1, 0);
+				sys_write (fd, "", 1);
+				sys_lseek (fd, old_pos, 0);
+			}
+		}
+	}
+
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+	down_write(&current->mm->mmap_sem);
+	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+	up_write(&current->mm->mmap_sem);
+
+	if (file)
+		fput(file);
+
+out:
+	return error;
+}
+
+asmlinkage int irix_dmi(struct pt_regs *regs)
+{
+	printk("[%s:%d] Wheee.. irix_dmi()\n",
+	       current->comm, current->pid);
+
+	return -EINVAL;
+}
+
+asmlinkage int irix_pread(int fd, char *buf, int cnt, int off64,
+			  int off1, int off2)
+{
+	printk("[%s:%d] Wheee.. irix_pread(%d,%p,%d,%d,%d,%d)\n",
+	       current->comm, current->pid, fd, buf, cnt, off64, off1, off2);
+
+	return -EINVAL;
+}
+
+asmlinkage int irix_pwrite(int fd, char *buf, int cnt, int off64,
+			   int off1, int off2)
+{
+	printk("[%s:%d] Wheee.. irix_pwrite(%d,%p,%d,%d,%d,%d)\n",
+	       current->comm, current->pid, fd, buf, cnt, off64, off1, off2);
+
+	return -EINVAL;
+}
+
+asmlinkage int irix_sgifastpath(int cmd, unsigned long arg0, unsigned long arg1,
+				unsigned long arg2, unsigned long arg3,
+				unsigned long arg4, unsigned long arg5)
+{
+	printk("[%s:%d] Wheee.. irix_fastpath(%d,%08lx,%08lx,%08lx,%08lx,"
+	       "%08lx,%08lx)\n",
+	       current->comm, current->pid, cmd, arg0, arg1, arg2,
+	       arg3, arg4, arg5);
+
+	return -EINVAL;
+}
+
+struct irix_statvfs64 {
+	u32  f_bsize; u32 f_frsize;
+	u64  f_blocks; u64 f_bfree; u64 f_bavail;
+	u64  f_files; u64 f_ffree; u64 f_favail;
+	u32  f_fsid;
+	char f_basetype[16];
+	u32  f_flag; u32 f_namemax;
+	char f_fstr[32];
+	u32  f_filler[16];
+};
+
+asmlinkage int irix_statvfs64(char *fname, struct irix_statvfs64 *buf)
+{
+	struct nameidata nd;
+	struct kstatfs kbuf;
+	int error, i;
+
+	printk("[%s:%d] Wheee.. irix_statvfs64(%s,%p)\n",
+	       current->comm, current->pid, fname, buf);
+	if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs64))) {
+		error = -EFAULT;
+		goto out;
+	}
+	error = user_path_walk(fname, &nd);
+	if (error)
+		goto out;
+	error = vfs_statfs(nd.dentry->d_inode->i_sb, &kbuf);
+	if (error)
+		goto dput_and_out;
+
+	__put_user(kbuf.f_bsize, &buf->f_bsize);
+	__put_user(kbuf.f_frsize, &buf->f_frsize);
+	__put_user(kbuf.f_blocks, &buf->f_blocks);
+	__put_user(kbuf.f_bfree, &buf->f_bfree);
+	__put_user(kbuf.f_bfree, &buf->f_bavail);  /* XXX hackety hack... */
+	__put_user(kbuf.f_files, &buf->f_files);
+	__put_user(kbuf.f_ffree, &buf->f_ffree);
+	__put_user(kbuf.f_ffree, &buf->f_favail);  /* XXX hackety hack... */
+#ifdef __MIPSEB__
+	__put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
+#else
+	__put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
+#endif
+	for(i = 0; i < 16; i++)
+		__put_user(0, &buf->f_basetype[i]);
+	__put_user(0, &buf->f_flag);
+	__put_user(kbuf.f_namelen, &buf->f_namemax);
+	for(i = 0; i < 32; i++)
+		__put_user(0, &buf->f_fstr[i]);
+
+	error = 0;
+
+dput_and_out:
+	path_release(&nd);
+out:
+	return error;
+}
+
+asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs *buf)
+{
+	struct kstatfs kbuf;
+	struct file *file;
+	int error, i;
+
+	printk("[%s:%d] Wheee.. irix_fstatvfs64(%d,%p)\n",
+	       current->comm, current->pid, fd, buf);
+
+	if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statvfs))) {
+		error = -EFAULT;
+		goto out;
+	}
+	if (!(file = fget(fd))) {
+		error = -EBADF;
+		goto out;
+	}
+	error = vfs_statfs(file->f_dentry->d_inode->i_sb, &kbuf);
+	if (error)
+		goto out_f;
+
+	__put_user(kbuf.f_bsize, &buf->f_bsize);
+	__put_user(kbuf.f_frsize, &buf->f_frsize);
+	__put_user(kbuf.f_blocks, &buf->f_blocks);
+	__put_user(kbuf.f_bfree, &buf->f_bfree);
+	__put_user(kbuf.f_bfree, &buf->f_bavail);  /* XXX hackety hack... */
+	__put_user(kbuf.f_files, &buf->f_files);
+	__put_user(kbuf.f_ffree, &buf->f_ffree);
+	__put_user(kbuf.f_ffree, &buf->f_favail);  /* XXX hackety hack... */
+#ifdef __MIPSEB__
+	__put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
+#else
+	__put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
+#endif
+	for(i = 0; i < 16; i++)
+		__put_user(0, &buf->f_basetype[i]);
+	__put_user(0, &buf->f_flag);
+	__put_user(kbuf.f_namelen, &buf->f_namemax);
+	__clear_user(buf->f_fstr, sizeof(buf->f_fstr[i]));
+
+out_f:
+	fput(file);
+out:
+	return error;
+}
+
+asmlinkage int irix_getmountid(char *fname, unsigned long *midbuf)
+{
+	int err = 0;
+
+	printk("[%s:%d] irix_getmountid(%s, %p)\n",
+	       current->comm, current->pid, fname, midbuf);
+	if (!access_ok(VERIFY_WRITE, midbuf, (sizeof(unsigned long) * 4)))
+		return -EFAULT;
+
+	/*
+	 * The idea with this system call is that when trying to determine
+	 * 'pwd' and it's a toss-up for some reason, userland can use the
+	 * fsid of the filesystem to try and make the right decision, but
+	 * we don't have this so for now. XXX
+	 */
+	err |= __put_user(0, &midbuf[0]);
+	err |= __put_user(0, &midbuf[1]);
+	err |= __put_user(0, &midbuf[2]);
+	err |= __put_user(0, &midbuf[3]);
+
+	return err;
+}
+
+asmlinkage int irix_nsproc(unsigned long entry, unsigned long mask,
+			   unsigned long arg, unsigned long sp, int slen)
+{
+	printk("[%s:%d] Wheee.. irix_nsproc(%08lx,%08lx,%08lx,%08lx,%d)\n",
+	       current->comm, current->pid, entry, mask, arg, sp, slen);
+
+	return -EINVAL;
+}
+
+#undef DEBUG_GETDENTS
+
+struct irix_dirent32 {
+	u32  d_ino;
+	u32  d_off;
+	unsigned short  d_reclen;
+	char d_name[1];
+};
+
+struct irix_dirent32_callback {
+	struct irix_dirent32 *current_dir;
+	struct irix_dirent32 *previous;
+	int count;
+	int error;
+};
+
+#define NAME_OFFSET32(de) ((int) ((de)->d_name - (char *) (de)))
+#define ROUND_UP32(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
+
+static int irix_filldir32(void *__buf, const char *name, int namlen,
+                          loff_t offset, ino_t ino, unsigned int d_type)
+{
+	struct irix_dirent32 *dirent;
+	struct irix_dirent32_callback *buf =
+		 (struct irix_dirent32_callback *)__buf;
+	unsigned short reclen = ROUND_UP32(NAME_OFFSET32(dirent) + namlen + 1);
+
+#ifdef DEBUG_GETDENTS
+	printk("\nirix_filldir32[reclen<%d>namlen<%d>count<%d>]",
+	       reclen, namlen, buf->count);
+#endif
+	buf->error = -EINVAL;	/* only used if we fail.. */
+	if (reclen > buf->count)
+		return -EINVAL;
+	dirent = buf->previous;
+	if (dirent)
+		__put_user(offset, &dirent->d_off);
+	dirent = buf->current_dir;
+	buf->previous = dirent;
+	__put_user(ino, &dirent->d_ino);
+	__put_user(reclen, &dirent->d_reclen);
+	copy_to_user(dirent->d_name, name, namlen);
+	__put_user(0, &dirent->d_name[namlen]);
+	((char *) dirent) += reclen;
+	buf->current_dir = dirent;
+	buf->count -= reclen;
+
+	return 0;
+}
+
+asmlinkage int irix_ngetdents(unsigned int fd, void * dirent,
+	unsigned int count, int *eob)
+{
+	struct file *file;
+	struct irix_dirent32 *lastdirent;
+	struct irix_dirent32_callback buf;
+	int error;
+
+#ifdef DEBUG_GETDENTS
+	printk("[%s:%d] ngetdents(%d, %p, %d, %p) ", current->comm,
+	       current->pid, fd, dirent, count, eob);
+#endif
+	error = -EBADF;
+	file = fget(fd);
+	if (!file)
+		goto out;
+
+	buf.current_dir = (struct irix_dirent32 *) dirent;
+	buf.previous = NULL;
+	buf.count = count;
+	buf.error = 0;
+
+	error = vfs_readdir(file, irix_filldir32, &buf);
+	if (error < 0)
+		goto out_putf;
+
+	error = buf.error;
+	lastdirent = buf.previous;
+	if (lastdirent) {
+		put_user(file->f_pos, &lastdirent->d_off);
+		error = count - buf.count;
+	}
+
+	if (put_user(0, eob) < 0) {
+		error = -EFAULT;
+		goto out_putf;
+	}
+
+#ifdef DEBUG_GETDENTS
+	printk("eob=%d returning %d\n", *eob, count - buf.count);
+#endif
+	error = count - buf.count;
+
+out_putf:
+	fput(file);
+out:
+	return error;
+}
+
+struct irix_dirent64 {
+	u64            d_ino;
+	u64            d_off;
+	unsigned short d_reclen;
+	char           d_name[1];
+};
+
+struct irix_dirent64_callback {
+	struct irix_dirent64 *curr;
+	struct irix_dirent64 *previous;
+	int count;
+	int error;
+};
+
+#define NAME_OFFSET64(de) ((int) ((de)->d_name - (char *) (de)))
+#define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))
+
+static int irix_filldir64(void * __buf, const char * name, int namlen,
+			  loff_t offset, ino_t ino, unsigned int d_type)
+{
+	struct irix_dirent64 *dirent;
+	struct irix_dirent64_callback * buf =
+		(struct irix_dirent64_callback *) __buf;
+	unsigned short reclen = ROUND_UP64(NAME_OFFSET64(dirent) + namlen + 1);
+
+	buf->error = -EINVAL;	/* only used if we fail.. */
+	if (reclen > buf->count)
+		return -EINVAL;
+	dirent = buf->previous;
+	if (dirent)
+		__put_user(offset, &dirent->d_off);
+	dirent = buf->curr;
+	buf->previous = dirent;
+	__put_user(ino, &dirent->d_ino);
+	__put_user(reclen, &dirent->d_reclen);
+	__copy_to_user(dirent->d_name, name, namlen);
+	__put_user(0, &dirent->d_name[namlen]);
+	((char *) dirent) += reclen;
+	buf->curr = dirent;
+	buf->count -= reclen;
+
+	return 0;
+}
+
+asmlinkage int irix_getdents64(int fd, void *dirent, int cnt)
+{
+	struct file *file;
+	struct irix_dirent64 *lastdirent;
+	struct irix_dirent64_callback buf;
+	int error;
+
+#ifdef DEBUG_GETDENTS
+	printk("[%s:%d] getdents64(%d, %p, %d) ", current->comm,
+	       current->pid, fd, dirent, cnt);
+#endif
+	error = -EBADF;
+	if (!(file = fget(fd)))
+		goto out;
+
+	error = -EFAULT;
+	if (!access_ok(VERIFY_WRITE, dirent, cnt))
+		goto out_f;
+
+	error = -EINVAL;
+	if (cnt < (sizeof(struct irix_dirent64) + 255))
+		goto out_f;
+
+	buf.curr = (struct irix_dirent64 *) dirent;
+	buf.previous = NULL;
+	buf.count = cnt;
+	buf.error = 0;
+	error = vfs_readdir(file, irix_filldir64, &buf);
+	if (error < 0)
+		goto out_f;
+	lastdirent = buf.previous;
+	if (!lastdirent) {
+		error = buf.error;
+		goto out_f;
+	}
+	lastdirent->d_off = (u64) file->f_pos;
+#ifdef DEBUG_GETDENTS
+	printk("returning %d\n", cnt - buf.count);
+#endif
+	error = cnt - buf.count;
+
+out_f:
+	fput(file);
+out:
+	return error;
+}
+
+asmlinkage int irix_ngetdents64(int fd, void *dirent, int cnt, int *eob)
+{
+	struct file *file;
+	struct irix_dirent64 *lastdirent;
+	struct irix_dirent64_callback buf;
+	int error;
+
+#ifdef DEBUG_GETDENTS
+	printk("[%s:%d] ngetdents64(%d, %p, %d) ", current->comm,
+	       current->pid, fd, dirent, cnt);
+#endif
+	error = -EBADF;
+	if (!(file = fget(fd)))
+		goto out;
+
+	error = -EFAULT;
+	if (!access_ok(VERIFY_WRITE, dirent, cnt) ||
+	    !access_ok(VERIFY_WRITE, eob, sizeof(*eob)))
+		goto out_f;
+
+	error = -EINVAL;
+	if (cnt < (sizeof(struct irix_dirent64) + 255))
+		goto out_f;
+
+	*eob = 0;
+	buf.curr = (struct irix_dirent64 *) dirent;
+	buf.previous = NULL;
+	buf.count = cnt;
+	buf.error = 0;
+	error = vfs_readdir(file, irix_filldir64, &buf);
+	if (error < 0)
+		goto out_f;
+	lastdirent = buf.previous;
+	if (!lastdirent) {
+		error = buf.error;
+		goto out_f;
+	}
+	lastdirent->d_off = (u64) file->f_pos;
+#ifdef DEBUG_GETDENTS
+	printk("eob=%d returning %d\n", *eob, cnt - buf.count);
+#endif
+	error = cnt - buf.count;
+
+out_f:
+	fput(file);
+out:
+	return error;
+}
+
+asmlinkage int irix_uadmin(unsigned long op, unsigned long func, unsigned long arg)
+{
+	int retval;
+
+	switch (op) {
+	case 1:
+		/* Reboot */
+		printk("[%s:%d] irix_uadmin: Wants to reboot...\n",
+		       current->comm, current->pid);
+		retval = -EINVAL;
+		goto out;
+
+	case 2:
+		/* Shutdown */
+		printk("[%s:%d] irix_uadmin: Wants to shutdown...\n",
+		       current->comm, current->pid);
+		retval = -EINVAL;
+		goto out;
+
+	case 4:
+		/* Remount-root */
+		printk("[%s:%d] irix_uadmin: Wants to remount root...\n",
+		       current->comm, current->pid);
+		retval = -EINVAL;
+		goto out;
+
+	case 8:
+		/* Kill all tasks. */
+		printk("[%s:%d] irix_uadmin: Wants to kill all tasks...\n",
+		       current->comm, current->pid);
+		retval = -EINVAL;
+		goto out;
+
+	case 256:
+		/* Set magic mushrooms... */
+		printk("[%s:%d] irix_uadmin: Wants to set magic mushroom[%d]...\n",
+		       current->comm, current->pid, (int) func);
+		retval = -EINVAL;
+		goto out;
+
+	default:
+		printk("[%s:%d] irix_uadmin: Unknown operation [%d]...\n",
+		       current->comm, current->pid, (int) op);
+		retval = -EINVAL;
+		goto out;
+	};
+
+out:
+	return retval;
+}
+
+asmlinkage int irix_utssys(char *inbuf, int arg, int type, char *outbuf)
+{
+	int retval;
+
+	switch(type) {
+	case 0:
+		/* uname() */
+		retval = irix_uname((struct iuname *)inbuf);
+		goto out;
+
+	case 2:
+		/* ustat() */
+		printk("[%s:%d] irix_utssys: Wants to do ustat()\n",
+		       current->comm, current->pid);
+		retval = -EINVAL;
+		goto out;
+
+	case 3:
+		/* fusers() */
+		printk("[%s:%d] irix_utssys: Wants to do fusers()\n",
+		       current->comm, current->pid);
+		retval = -EINVAL;
+		goto out;
+
+	default:
+		printk("[%s:%d] irix_utssys: Wants to do unknown type[%d]\n",
+		       current->comm, current->pid, (int) type);
+		retval = -EINVAL;
+		goto out;
+	}
+
+out:
+	return retval;
+}
+
+#undef DEBUG_FCNTL
+
+#define IRIX_F_ALLOCSP 10
+
+asmlinkage int irix_fcntl(int fd, int cmd, int arg)
+{
+	int retval;
+
+#ifdef DEBUG_FCNTL
+	printk("[%s:%d] irix_fcntl(%d, %d, %d) ", current->comm,
+	       current->pid, fd, cmd, arg);
+#endif
+	if (cmd == IRIX_F_ALLOCSP){
+		return 0;
+	}
+	retval = sys_fcntl(fd, cmd, arg);
+#ifdef DEBUG_FCNTL
+	printk("%d\n", retval);
+#endif
+	return retval;
+}
+
+asmlinkage int irix_ulimit(int cmd, int arg)
+{
+	int retval;
+
+	switch(cmd) {
+	case 1:
+		printk("[%s:%d] irix_ulimit: Wants to get file size limit.\n",
+		       current->comm, current->pid);
+		retval = -EINVAL;
+		goto out;
+
+	case 2:
+		printk("[%s:%d] irix_ulimit: Wants to set file size limit.\n",
+		       current->comm, current->pid);
+		retval = -EINVAL;
+		goto out;
+
+	case 3:
+		printk("[%s:%d] irix_ulimit: Wants to get brk limit.\n",
+		       current->comm, current->pid);
+		retval = -EINVAL;
+		goto out;
+
+	case 4:
+#if 0
+		printk("[%s:%d] irix_ulimit: Wants to get fd limit.\n",
+		       current->comm, current->pid);
+		retval = -EINVAL;
+		goto out;
+#endif
+		retval = current->signal->rlim[RLIMIT_NOFILE].rlim_cur;
+		goto out;
+
+	case 5:
+		printk("[%s:%d] irix_ulimit: Wants to get txt offset.\n",
+		       current->comm, current->pid);
+		retval = -EINVAL;
+		goto out;
+
+	default:
+		printk("[%s:%d] irix_ulimit: Unknown command [%d].\n",
+		       current->comm, current->pid, cmd);
+		retval = -EINVAL;
+		goto out;
+	}
+out:
+	return retval;
+}
+
+asmlinkage int irix_unimp(struct pt_regs *regs)
+{
+	printk("irix_unimp [%s:%d] v0=%d v1=%d a0=%08lx a1=%08lx a2=%08lx "
+	       "a3=%08lx\n", current->comm, current->pid,
+	       (int) regs->regs[2], (int) regs->regs[3],
+	       regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
+
+	return -ENOSYS;
+}
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
new file mode 100644
index 0000000..648c822
--- /dev/null
+++ b/arch/mips/kernel/time.c
@@ -0,0 +1,755 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ * Copyright (c) 2003, 2004  Maciej W. Rozycki
+ *
+ * Common time service routines for MIPS machines. See
+ * Documentation/mips/time.README.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/smp.h>
+#include <linux/kernel_stat.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+
+#include <asm/bootinfo.h>
+#include <asm/compiler.h>
+#include <asm/cpu.h>
+#include <asm/cpu-features.h>
+#include <asm/div64.h>
+#include <asm/sections.h>
+#include <asm/time.h>
+
+/*
+ * The integer part of the number of usecs per jiffy is taken from tick,
+ * but the fractional part is not recorded, so we calculate it using the
+ * initial value of HZ.  This aids systems where tick isn't really an
+ * integer (e.g. for HZ = 128).
+ */
+#define USECS_PER_JIFFY		TICK_SIZE
+#define USECS_PER_JIFFY_FRAC	((unsigned long)(u32)((1000000ULL << 32) / HZ))
+
+#define TICK_SIZE	(tick_nsec / 1000)
+
+u64 jiffies_64 = INITIAL_JIFFIES;
+
+EXPORT_SYMBOL(jiffies_64);
+
+/*
+ * forward reference
+ */
+extern volatile unsigned long wall_jiffies;
+
+DEFINE_SPINLOCK(rtc_lock);
+
+/*
+ * By default we provide the null RTC ops
+ */
+static unsigned long null_rtc_get_time(void)
+{
+	return mktime(2000, 1, 1, 0, 0, 0);
+}
+
+static int null_rtc_set_time(unsigned long sec)
+{
+	return 0;
+}
+
+unsigned long (*rtc_get_time)(void) = null_rtc_get_time;
+int (*rtc_set_time)(unsigned long) = null_rtc_set_time;
+int (*rtc_set_mmss)(unsigned long);
+
+
+/* usecs per counter cycle, shifted to left by 32 bits */
+static unsigned int sll32_usecs_per_cycle;
+
+/* how many counter cycles in a jiffy */
+static unsigned long cycles_per_jiffy;
+
+/* Cycle counter value at the previous timer interrupt.. */
+static unsigned int timerhi, timerlo;
+
+/* expirelo is the count value for next CPU timer interrupt */
+static unsigned int expirelo;
+
+
+/*
+ * Null timer ack for systems not needing one (e.g. i8254).
+ */
+static void null_timer_ack(void) { /* nothing */ }
+
+/*
+ * Null high precision timer functions for systems lacking one.
+ */
+static unsigned int null_hpt_read(void)
+{
+	return 0;
+}
+
+static void null_hpt_init(unsigned int count) { /* nothing */ }
+
+
+/*
+ * Timer ack for an R4k-compatible timer of a known frequency.
+ */
+static void c0_timer_ack(void)
+{
+	unsigned int count;
+
+	/* Ack this timer interrupt and set the next one.  */
+	expirelo += cycles_per_jiffy;
+	write_c0_compare(expirelo);
+
+	/* Check to see if we have missed any timer interrupts.  */
+	count = read_c0_count();
+	if ((count - expirelo) < 0x7fffffff) {
+		/* missed_timer_count++; */
+		expirelo = count + cycles_per_jiffy;
+		write_c0_compare(expirelo);
+	}
+}
+
+/*
+ * High precision timer functions for a R4k-compatible timer.
+ */
+static unsigned int c0_hpt_read(void)
+{
+	return read_c0_count();
+}
+
+/* For use solely as a high precision timer.  */
+static void c0_hpt_init(unsigned int count)
+{
+	write_c0_count(read_c0_count() - count);
+}
+
+/* For use both as a high precision timer and an interrupt source.  */
+static void c0_hpt_timer_init(unsigned int count)
+{
+	count = read_c0_count() - count;
+	expirelo = (count / cycles_per_jiffy + 1) * cycles_per_jiffy;
+	write_c0_count(expirelo - cycles_per_jiffy);
+	write_c0_compare(expirelo);
+	write_c0_count(count);
+}
+
+int (*mips_timer_state)(void);
+void (*mips_timer_ack)(void);
+unsigned int (*mips_hpt_read)(void);
+void (*mips_hpt_init)(unsigned int);
+
+
+/*
+ * This version of gettimeofday has microsecond resolution and better than
+ * microsecond precision on fast machines with cycle counter.
+ */
+void do_gettimeofday(struct timeval *tv)
+{
+	unsigned long seq;
+	unsigned long lost;
+	unsigned long usec, sec;
+	unsigned long max_ntp_tick = tick_usec - tickadj;
+
+	do {
+		seq = read_seqbegin(&xtime_lock);
+
+		usec = do_gettimeoffset();
+
+		lost = jiffies - wall_jiffies;
+
+		/*
+		 * If time_adjust is negative then NTP is slowing the clock
+		 * so make sure not to go into next possible interval.
+		 * Better to lose some accuracy than have time go backwards..
+		 */
+		if (unlikely(time_adjust < 0)) {
+			usec = min(usec, max_ntp_tick);
+
+			if (lost)
+				usec += lost * max_ntp_tick;
+		} else if (unlikely(lost))
+			usec += lost * tick_usec;
+
+		sec = xtime.tv_sec;
+		usec += (xtime.tv_nsec / 1000);
+
+	} while (read_seqretry(&xtime_lock, seq));
+
+	while (usec >= 1000000) {
+		usec -= 1000000;
+		sec++;
+	}
+
+	tv->tv_sec = sec;
+	tv->tv_usec = usec;
+}
+
+EXPORT_SYMBOL(do_gettimeofday);
+
+int do_settimeofday(struct timespec *tv)
+{
+	time_t wtm_sec, sec = tv->tv_sec;
+	long wtm_nsec, nsec = tv->tv_nsec;
+
+	if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
+		return -EINVAL;
+
+	write_seqlock_irq(&xtime_lock);
+
+	/*
+	 * This is revolting.  We need to set "xtime" correctly.  However,
+	 * the value in this location is the value at the most recent update
+	 * of wall time.  Discover what correction gettimeofday() would have
+	 * made, and then undo it!
+	 */
+	nsec -= do_gettimeoffset() * NSEC_PER_USEC;
+	nsec -= (jiffies - wall_jiffies) * tick_nsec;
+
+	wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
+	wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
+
+	set_normalized_timespec(&xtime, sec, nsec);
+	set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
+
+	time_adjust = 0;			/* stop active adjtime() */
+	time_status |= STA_UNSYNC;
+	time_maxerror = NTP_PHASE_LIMIT;
+	time_esterror = NTP_PHASE_LIMIT;
+
+	write_sequnlock_irq(&xtime_lock);
+	clock_was_set();
+	return 0;
+}
+
+EXPORT_SYMBOL(do_settimeofday);
+
+/*
+ * Gettimeoffset routines.  These routines returns the time duration
+ * since last timer interrupt in usecs.
+ *
+ * If the exact CPU counter frequency is known, use fixed_rate_gettimeoffset.
+ * Otherwise use calibrate_gettimeoffset()
+ *
+ * If the CPU does not have the counter register, you can either supply
+ * your own gettimeoffset() routine, or use null_gettimeoffset(), which
+ * gives the same resolution as HZ.
+ */
+
+static unsigned long null_gettimeoffset(void)
+{
+	return 0;
+}
+
+
+/* The function pointer to one of the gettimeoffset funcs.  */
+unsigned long (*do_gettimeoffset)(void) = null_gettimeoffset;
+
+
+static unsigned long fixed_rate_gettimeoffset(void)
+{
+	u32 count;
+	unsigned long res;
+
+	/* Get last timer tick in absolute kernel time */
+	count = mips_hpt_read();
+
+	/* .. relative to previous jiffy (32 bits is enough) */
+	count -= timerlo;
+
+	__asm__("multu	%1,%2"
+		: "=h" (res)
+		: "r" (count), "r" (sll32_usecs_per_cycle)
+		: "lo", GCC_REG_ACCUM);
+
+	/*
+	 * Due to possible jiffies inconsistencies, we need to check
+	 * the result so that we'll get a timer that is monotonic.
+	 */
+	if (res >= USECS_PER_JIFFY)
+		res = USECS_PER_JIFFY - 1;
+
+	return res;
+}
+
+
+/*
+ * Cached "1/(clocks per usec) * 2^32" value.
+ * It has to be recalculated once each jiffy.
+ */
+static unsigned long cached_quotient;
+
+/* Last jiffy when calibrate_divXX_gettimeoffset() was called. */
+static unsigned long last_jiffies;
+
+/*
+ * This is moved from dec/time.c:do_ioasic_gettimeoffset() by Maciej.
+ */
+static unsigned long calibrate_div32_gettimeoffset(void)
+{
+	u32 count;
+	unsigned long res, tmp;
+	unsigned long quotient;
+
+	tmp = jiffies;
+
+	quotient = cached_quotient;
+
+	if (last_jiffies != tmp) {
+		last_jiffies = tmp;
+		if (last_jiffies != 0) {
+			unsigned long r0;
+			do_div64_32(r0, timerhi, timerlo, tmp);
+			do_div64_32(quotient, USECS_PER_JIFFY,
+				    USECS_PER_JIFFY_FRAC, r0);
+			cached_quotient = quotient;
+		}
+	}
+
+	/* Get last timer tick in absolute kernel time */
+	count = mips_hpt_read();
+
+	/* .. relative to previous jiffy (32 bits is enough) */
+	count -= timerlo;
+
+	__asm__("multu  %1,%2"
+		: "=h" (res)
+		: "r" (count), "r" (quotient)
+		: "lo", GCC_REG_ACCUM);
+
+	/*
+	 * Due to possible jiffies inconsistencies, we need to check
+	 * the result so that we'll get a timer that is monotonic.
+	 */
+	if (res >= USECS_PER_JIFFY)
+		res = USECS_PER_JIFFY - 1;
+
+	return res;
+}
+
+static unsigned long calibrate_div64_gettimeoffset(void)
+{
+	u32 count;
+	unsigned long res, tmp;
+	unsigned long quotient;
+
+	tmp = jiffies;
+
+	quotient = cached_quotient;
+
+	if (last_jiffies != tmp) {
+		last_jiffies = tmp;
+		if (last_jiffies) {
+			unsigned long r0;
+			__asm__(".set	push\n\t"
+				".set	mips3\n\t"
+				"lwu	%0,%3\n\t"
+				"dsll32	%1,%2,0\n\t"
+				"or	%1,%1,%0\n\t"
+				"ddivu	$0,%1,%4\n\t"
+				"mflo	%1\n\t"
+				"dsll32	%0,%5,0\n\t"
+				"or	%0,%0,%6\n\t"
+				"ddivu	$0,%0,%1\n\t"
+				"mflo	%0\n\t"
+				".set	pop"
+				: "=&r" (quotient), "=&r" (r0)
+				: "r" (timerhi), "m" (timerlo),
+				  "r" (tmp), "r" (USECS_PER_JIFFY),
+				  "r" (USECS_PER_JIFFY_FRAC)
+				: "hi", "lo", GCC_REG_ACCUM);
+			cached_quotient = quotient;
+		}
+	}
+
+	/* Get last timer tick in absolute kernel time */
+	count = mips_hpt_read();
+
+	/* .. relative to previous jiffy (32 bits is enough) */
+	count -= timerlo;
+
+	__asm__("multu	%1,%2"
+		: "=h" (res)
+		: "r" (count), "r" (quotient)
+		: "lo", GCC_REG_ACCUM);
+
+	/*
+	 * Due to possible jiffies inconsistencies, we need to check
+	 * the result so that we'll get a timer that is monotonic.
+	 */
+	if (res >= USECS_PER_JIFFY)
+		res = USECS_PER_JIFFY - 1;
+
+	return res;
+}
+
+
+/* last time when xtime and rtc are sync'ed up */
+static long last_rtc_update;
+
+/*
+ * local_timer_interrupt() does profiling and process accounting
+ * on a per-CPU basis.
+ *
+ * In UP mode, it is invoked from the (global) timer_interrupt.
+ *
+ * In SMP mode, it might invoked by per-CPU timer interrupt, or
+ * a broadcasted inter-processor interrupt which itself is triggered
+ * by the global timer interrupt.
+ */
+void local_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	if (current->pid)
+		profile_tick(CPU_PROFILING, regs);
+	update_process_times(user_mode(regs));
+}
+
+/*
+ * High-level timer interrupt service routines.  This function
+ * is set as irqaction->handler and is invoked through do_IRQ.
+ */
+irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned long j;
+	unsigned int count;
+
+	count = mips_hpt_read();
+	mips_timer_ack();
+
+	/* Update timerhi/timerlo for intra-jiffy calibration. */
+	timerhi += count < timerlo;			/* Wrap around */
+	timerlo = count;
+
+	/*
+	 * call the generic timer interrupt handling
+	 */
+	do_timer(regs);
+
+	/*
+	 * If we have an externally synchronized Linux clock, then update
+	 * CMOS clock accordingly every ~11 minutes. rtc_set_time() has to be
+	 * called as close as possible to 500 ms before the new second starts.
+	 */
+	write_seqlock(&xtime_lock);
+	if ((time_status & STA_UNSYNC) == 0 &&
+	    xtime.tv_sec > last_rtc_update + 660 &&
+	    (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
+	    (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
+		if (rtc_set_mmss(xtime.tv_sec) == 0) {
+			last_rtc_update = xtime.tv_sec;
+		} else {
+			/* do it again in 60 s */
+			last_rtc_update = xtime.tv_sec - 600;
+		}
+	}
+	write_sequnlock(&xtime_lock);
+
+	/*
+	 * If jiffies has overflown in this timer_interrupt, we must
+	 * update the timer[hi]/[lo] to make fast gettimeoffset funcs
+	 * quotient calc still valid. -arca
+	 *
+	 * The first timer interrupt comes late as interrupts are
+	 * enabled long after timers are initialized.  Therefore the
+	 * high precision timer is fast, leading to wrong gettimeoffset()
+	 * calculations.  We deal with it by setting it based on the
+	 * number of its ticks between the second and the third interrupt.
+	 * That is still somewhat imprecise, but it's a good estimate.
+	 * --macro
+	 */
+	j = jiffies;
+	if (j < 4) {
+		static unsigned int prev_count;
+		static int hpt_initialized;
+
+		switch (j) {
+		case 0:
+			timerhi = timerlo = 0;
+			mips_hpt_init(count);
+			break;
+		case 2:
+			prev_count = count;
+			break;
+		case 3:
+			if (!hpt_initialized) {
+				unsigned int c3 = 3 * (count - prev_count);
+
+				timerhi = 0;
+				timerlo = c3;
+				mips_hpt_init(count - c3);
+				hpt_initialized = 1;
+			}
+			break;
+		default:
+			break;
+		}
+	}
+
+	/*
+	 * In UP mode, we call local_timer_interrupt() to do profiling
+	 * and process accouting.
+	 *
+	 * In SMP mode, local_timer_interrupt() is invoked by appropriate
+	 * low-level local timer interrupt handler.
+	 */
+	local_timer_interrupt(irq, dev_id, regs);
+
+	return IRQ_HANDLED;
+}
+
+asmlinkage void ll_timer_interrupt(int irq, struct pt_regs *regs)
+{
+	irq_enter();
+	kstat_this_cpu.irqs[irq]++;
+
+	/* we keep interrupt disabled all the time */
+	timer_interrupt(irq, NULL, regs);
+
+	irq_exit();
+}
+
+asmlinkage void ll_local_timer_interrupt(int irq, struct pt_regs *regs)
+{
+	irq_enter();
+	if (smp_processor_id() != 0)
+		kstat_this_cpu.irqs[irq]++;
+
+	/* we keep interrupt disabled all the time */
+	local_timer_interrupt(irq, NULL, regs);
+
+	irq_exit();
+}
+
+/*
+ * time_init() - it does the following things.
+ *
+ * 1) board_time_init() -
+ * 	a) (optional) set up RTC routines,
+ *      b) (optional) calibrate and set the mips_hpt_frequency
+ *	    (only needed if you intended to use fixed_rate_gettimeoffset
+ *	     or use cpu counter as timer interrupt source)
+ * 2) setup xtime based on rtc_get_time().
+ * 3) choose a appropriate gettimeoffset routine.
+ * 4) calculate a couple of cached variables for later usage
+ * 5) board_timer_setup() -
+ *	a) (optional) over-write any choices made above by time_init().
+ *	b) machine specific code should setup the timer irqaction.
+ *	c) enable the timer interrupt
+ */
+
+void (*board_time_init)(void);
+void (*board_timer_setup)(struct irqaction *irq);
+
+unsigned int mips_hpt_frequency;
+
+static struct irqaction timer_irqaction = {
+	.handler = timer_interrupt,
+	.flags = SA_INTERRUPT,
+	.name = "timer",
+};
+
+static unsigned int __init calibrate_hpt(void)
+{
+	u64 frequency;
+	u32 hpt_start, hpt_end, hpt_count, hz;
+
+	const int loops = HZ / 10;
+	int log_2_loops = 0;
+	int i;
+
+	/*
+	 * We want to calibrate for 0.1s, but to avoid a 64-bit
+	 * division we round the number of loops up to the nearest
+	 * power of 2.
+	 */
+	while (loops > 1 << log_2_loops)
+		log_2_loops++;
+	i = 1 << log_2_loops;
+
+	/*
+	 * Wait for a rising edge of the timer interrupt.
+	 */
+	while (mips_timer_state());
+	while (!mips_timer_state());
+
+	/*
+	 * Now see how many high precision timer ticks happen
+	 * during the calculated number of periods between timer
+	 * interrupts.
+	 */
+	hpt_start = mips_hpt_read();
+	do {
+		while (mips_timer_state());
+		while (!mips_timer_state());
+	} while (--i);
+	hpt_end = mips_hpt_read();
+
+	hpt_count = hpt_end - hpt_start;
+	hz = HZ;
+	frequency = (u64)hpt_count * (u64)hz;
+
+	return frequency >> log_2_loops;
+}
+
+void __init time_init(void)
+{
+	if (board_time_init)
+		board_time_init();
+
+	if (!rtc_set_mmss)
+		rtc_set_mmss = rtc_set_time;
+
+	xtime.tv_sec = rtc_get_time();
+	xtime.tv_nsec = 0;
+
+	set_normalized_timespec(&wall_to_monotonic,
+	                        -xtime.tv_sec, -xtime.tv_nsec);
+
+	/* Choose appropriate high precision timer routines.  */
+	if (!cpu_has_counter && !mips_hpt_read) {
+		/* No high precision timer -- sorry.  */
+		mips_hpt_read = null_hpt_read;
+		mips_hpt_init = null_hpt_init;
+	} else if (!mips_hpt_frequency && !mips_timer_state) {
+		/* A high precision timer of unknown frequency.  */
+		if (!mips_hpt_read) {
+			/* No external high precision timer -- use R4k.  */
+			mips_hpt_read = c0_hpt_read;
+			mips_hpt_init = c0_hpt_init;
+		}
+
+		if ((current_cpu_data.isa_level == MIPS_CPU_ISA_M32) ||
+			 (current_cpu_data.isa_level == MIPS_CPU_ISA_I) ||
+			 (current_cpu_data.isa_level == MIPS_CPU_ISA_II))
+			/*
+			 * We need to calibrate the counter but we don't have
+			 * 64-bit division.
+			 */
+			do_gettimeoffset = calibrate_div32_gettimeoffset;
+		else
+			/*
+			 * We need to calibrate the counter but we *do* have
+			 * 64-bit division.
+			 */
+			do_gettimeoffset = calibrate_div64_gettimeoffset;
+	} else {
+		/* We know counter frequency.  Or we can get it.  */
+		if (!mips_hpt_read) {
+			/* No external high precision timer -- use R4k.  */
+			mips_hpt_read = c0_hpt_read;
+
+			if (mips_timer_state)
+				mips_hpt_init = c0_hpt_init;
+			else {
+				/* No external timer interrupt -- use R4k.  */
+				mips_hpt_init = c0_hpt_timer_init;
+				mips_timer_ack = c0_timer_ack;
+			}
+		}
+		if (!mips_hpt_frequency)
+			mips_hpt_frequency = calibrate_hpt();
+
+		do_gettimeoffset = fixed_rate_gettimeoffset;
+
+		/* Calculate cache parameters.  */
+		cycles_per_jiffy = (mips_hpt_frequency + HZ / 2) / HZ;
+
+		/* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq  */
+		do_div64_32(sll32_usecs_per_cycle,
+			    1000000, mips_hpt_frequency / 2,
+			    mips_hpt_frequency);
+
+		/* Report the high precision timer rate for a reference.  */
+		printk("Using %u.%03u MHz high precision timer.\n",
+		       ((mips_hpt_frequency + 500) / 1000) / 1000,
+		       ((mips_hpt_frequency + 500) / 1000) % 1000);
+	}
+
+	if (!mips_timer_ack)
+		/* No timer interrupt ack (e.g. i8254).  */
+		mips_timer_ack = null_timer_ack;
+
+	/* This sets up the high precision timer for the first interrupt.  */
+	mips_hpt_init(mips_hpt_read());
+
+	/*
+	 * Call board specific timer interrupt setup.
+	 *
+	 * this pointer must be setup in machine setup routine.
+	 *
+	 * Even if a machine chooses to use a low-level timer interrupt,
+	 * it still needs to setup the timer_irqaction.
+	 * In that case, it might be better to set timer_irqaction.handler
+	 * to be NULL function so that we are sure the high-level code
+	 * is not invoked accidentally.
+	 */
+	board_timer_setup(&timer_irqaction);
+}
+
+#define FEBRUARY		2
+#define STARTOFTIME		1970
+#define SECDAY			86400L
+#define SECYR			(SECDAY * 365)
+#define leapyear(y)		((!((y) % 4) && ((y) % 100)) || !((y) % 400))
+#define days_in_year(y)		(leapyear(y) ? 366 : 365)
+#define days_in_month(m)	(month_days[(m) - 1])
+
+static int month_days[12] = {
+	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+};
+
+void to_tm(unsigned long tim, struct rtc_time *tm)
+{
+	long hms, day, gday;
+	int i;
+
+	gday = day = tim / SECDAY;
+	hms = tim % SECDAY;
+
+	/* Hours, minutes, seconds are easy */
+	tm->tm_hour = hms / 3600;
+	tm->tm_min = (hms % 3600) / 60;
+	tm->tm_sec = (hms % 3600) % 60;
+
+	/* Number of years in days */
+	for (i = STARTOFTIME; day >= days_in_year(i); i++)
+		day -= days_in_year(i);
+	tm->tm_year = i;
+
+	/* Number of months in days left */
+	if (leapyear(tm->tm_year))
+		days_in_month(FEBRUARY) = 29;
+	for (i = 1; day >= days_in_month(i); i++)
+		day -= days_in_month(i);
+	days_in_month(FEBRUARY) = 28;
+	tm->tm_mon = i - 1;		/* tm_mon starts from 0 to 11 */
+
+	/* Days are what is left over (+1) from all that. */
+	tm->tm_mday = day + 1;
+
+	/*
+	 * Determine the day of week
+	 */
+	tm->tm_wday = (gday + 4) % 7;	/* 1970/1/1 was Thursday */
+}
+
+EXPORT_SYMBOL(rtc_lock);
+EXPORT_SYMBOL(to_tm);
+EXPORT_SYMBOL(rtc_set_time);
+EXPORT_SYMBOL(rtc_get_time);
+
+unsigned long long sched_clock(void)
+{
+	return (unsigned long long)jiffies*(1000000000/HZ);
+}
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
new file mode 100644
index 0000000..56c36e4
--- /dev/null
+++ b/arch/mips/kernel/traps.c
@@ -0,0 +1,1062 @@
+/*
+ * 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) 1994 - 1999, 2000, 01 Ralf Baechle
+ * Copyright (C) 1995, 1996 Paul M. Antoine
+ * Copyright (C) 1998 Ulf Carlsson
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000, 01 MIPS Technologies, Inc.
+ * Copyright (C) 2002, 2003, 2004  Maciej W. Rozycki
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/spinlock.h>
+#include <linux/kallsyms.h>
+
+#include <asm/bootinfo.h>
+#include <asm/branch.h>
+#include <asm/break.h>
+#include <asm/cpu.h>
+#include <asm/fpu.h>
+#include <asm/module.h>
+#include <asm/pgtable.h>
+#include <asm/ptrace.h>
+#include <asm/sections.h>
+#include <asm/system.h>
+#include <asm/tlbdebug.h>
+#include <asm/traps.h>
+#include <asm/uaccess.h>
+#include <asm/mmu_context.h>
+#include <asm/watch.h>
+#include <asm/types.h>
+
+extern asmlinkage void handle_tlbm(void);
+extern asmlinkage void handle_tlbl(void);
+extern asmlinkage void handle_tlbs(void);
+extern asmlinkage void handle_adel(void);
+extern asmlinkage void handle_ades(void);
+extern asmlinkage void handle_ibe(void);
+extern asmlinkage void handle_dbe(void);
+extern asmlinkage void handle_sys(void);
+extern asmlinkage void handle_bp(void);
+extern asmlinkage void handle_ri(void);
+extern asmlinkage void handle_cpu(void);
+extern asmlinkage void handle_ov(void);
+extern asmlinkage void handle_tr(void);
+extern asmlinkage void handle_fpe(void);
+extern asmlinkage void handle_mdmx(void);
+extern asmlinkage void handle_watch(void);
+extern asmlinkage void handle_mcheck(void);
+extern asmlinkage void handle_reserved(void);
+
+extern int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp,
+	struct mips_fpu_soft_struct *ctx);
+
+void (*board_be_init)(void);
+int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
+
+/*
+ * These constant is for searching for possible module text segments.
+ * MODULE_RANGE is a guess of how much space is likely to be vmalloced.
+ */
+#define MODULE_RANGE (8*1024*1024)
+
+/*
+ * This routine abuses get_user()/put_user() to reference pointers
+ * with at least a bit of error checking ...
+ */
+void show_stack(struct task_struct *task, unsigned long *sp)
+{
+	const int field = 2 * sizeof(unsigned long);
+	long stackdata;
+	int i;
+
+	if (!sp) {
+		if (task && task != current)
+			sp = (unsigned long *) task->thread.reg29;
+		else
+			sp = (unsigned long *) &sp;
+	}
+
+	printk("Stack :");
+	i = 0;
+	while ((unsigned long) sp & (PAGE_SIZE - 1)) {
+		if (i && ((i % (64 / field)) == 0))
+			printk("\n       ");
+		if (i > 39) {
+			printk(" ...");
+			break;
+		}
+
+		if (__get_user(stackdata, sp++)) {
+			printk(" (Bad stack address)");
+			break;
+		}
+
+		printk(" %0*lx", field, stackdata);
+		i++;
+	}
+	printk("\n");
+}
+
+void show_trace(struct task_struct *task, unsigned long *stack)
+{
+	const int field = 2 * sizeof(unsigned long);
+	unsigned long addr;
+
+	if (!stack) {
+		if (task && task != current)
+			stack = (unsigned long *) task->thread.reg29;
+		else
+			stack = (unsigned long *) &stack;
+	}
+
+	printk("Call Trace:");
+#ifdef CONFIG_KALLSYMS
+	printk("\n");
+#endif
+	while (!kstack_end(stack)) {
+		addr = *stack++;
+		if (__kernel_text_address(addr)) {
+			printk(" [<%0*lx>] ", field, addr);
+			print_symbol("%s\n", addr);
+		}
+	}
+	printk("\n");
+}
+
+/*
+ * The architecture-independent dump_stack generator
+ */
+void dump_stack(void)
+{
+	unsigned long stack;
+
+	show_trace(current, &stack);
+}
+
+EXPORT_SYMBOL(dump_stack);
+
+void show_code(unsigned int *pc)
+{
+	long i;
+
+	printk("\nCode:");
+
+	for(i = -3 ; i < 6 ; i++) {
+		unsigned int insn;
+		if (__get_user(insn, pc + i)) {
+			printk(" (Bad address in epc)\n");
+			break;
+		}
+		printk("%c%08x%c", (i?' ':'<'), insn, (i?' ':'>'));
+	}
+}
+
+void show_regs(struct pt_regs *regs)
+{
+	const int field = 2 * sizeof(unsigned long);
+	unsigned int cause = regs->cp0_cause;
+	int i;
+
+	printk("Cpu %d\n", smp_processor_id());
+
+	/*
+	 * Saved main processor registers
+	 */
+	for (i = 0; i < 32; ) {
+		if ((i % 4) == 0)
+			printk("$%2d   :", i);
+		if (i == 0)
+			printk(" %0*lx", field, 0UL);
+		else if (i == 26 || i == 27)
+			printk(" %*s", field, "");
+		else
+			printk(" %0*lx", field, regs->regs[i]);
+
+		i++;
+		if ((i % 4) == 0)
+			printk("\n");
+	}
+
+	printk("Hi    : %0*lx\n", field, regs->hi);
+	printk("Lo    : %0*lx\n", field, regs->lo);
+
+	/*
+	 * Saved cp0 registers
+	 */
+	printk("epc   : %0*lx ", field, regs->cp0_epc);
+	print_symbol("%s ", regs->cp0_epc);
+	printk("    %s\n", print_tainted());
+	printk("ra    : %0*lx ", field, regs->regs[31]);
+	print_symbol("%s\n", regs->regs[31]);
+
+	printk("Status: %08x    ", (uint32_t) regs->cp0_status);
+
+	if (regs->cp0_status & ST0_KX)
+		printk("KX ");
+	if (regs->cp0_status & ST0_SX)
+		printk("SX ");
+	if (regs->cp0_status & ST0_UX)
+		printk("UX ");
+	switch (regs->cp0_status & ST0_KSU) {
+	case KSU_USER:
+		printk("USER ");
+		break;
+	case KSU_SUPERVISOR:
+		printk("SUPERVISOR ");
+		break;
+	case KSU_KERNEL:
+		printk("KERNEL ");
+		break;
+	default:
+		printk("BAD_MODE ");
+		break;
+	}
+	if (regs->cp0_status & ST0_ERL)
+		printk("ERL ");
+	if (regs->cp0_status & ST0_EXL)
+		printk("EXL ");
+	if (regs->cp0_status & ST0_IE)
+		printk("IE ");
+	printk("\n");
+
+	printk("Cause : %08x\n", cause);
+
+	cause = (cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE;
+	if (1 <= cause && cause <= 5)
+		printk("BadVA : %0*lx\n", field, regs->cp0_badvaddr);
+
+	printk("PrId  : %08x\n", read_c0_prid());
+}
+
+void show_registers(struct pt_regs *regs)
+{
+	show_regs(regs);
+	print_modules();
+	printk("Process %s (pid: %d, threadinfo=%p, task=%p)\n",
+	        current->comm, current->pid, current_thread_info(), current);
+	show_stack(current, (long *) regs->regs[29]);
+	show_trace(current, (long *) regs->regs[29]);
+	show_code((unsigned int *) regs->cp0_epc);
+	printk("\n");
+}
+
+static DEFINE_SPINLOCK(die_lock);
+
+NORET_TYPE void __die(const char * str, struct pt_regs * regs,
+	const char * file, const char * func, unsigned long line)
+{
+	static int die_counter;
+
+	console_verbose();
+	spin_lock_irq(&die_lock);
+	printk("%s", str);
+	if (file && func)
+		printk(" in %s:%s, line %ld", file, func, line);
+	printk("[#%d]:\n", ++die_counter);
+	show_registers(regs);
+	spin_unlock_irq(&die_lock);
+	do_exit(SIGSEGV);
+}
+
+void __die_if_kernel(const char * str, struct pt_regs * regs,
+		     const char * file, const char * func, unsigned long line)
+{
+	if (!user_mode(regs))
+		__die(str, regs, file, func, line);
+}
+
+extern const struct exception_table_entry __start___dbe_table[];
+extern const struct exception_table_entry __stop___dbe_table[];
+
+void __declare_dbe_table(void)
+{
+	__asm__ __volatile__(
+	".section\t__dbe_table,\"a\"\n\t"
+	".previous"
+	);
+}
+
+/* Given an address, look for it in the exception tables. */
+static const struct exception_table_entry *search_dbe_tables(unsigned long addr)
+{
+	const struct exception_table_entry *e;
+
+	e = search_extable(__start___dbe_table, __stop___dbe_table - 1, addr);
+	if (!e)
+		e = search_module_dbetables(addr);
+	return e;
+}
+
+asmlinkage void do_be(struct pt_regs *regs)
+{
+	const int field = 2 * sizeof(unsigned long);
+	const struct exception_table_entry *fixup = NULL;
+	int data = regs->cp0_cause & 4;
+	int action = MIPS_BE_FATAL;
+
+	/* XXX For now.  Fixme, this searches the wrong table ...  */
+	if (data && !user_mode(regs))
+		fixup = search_dbe_tables(exception_epc(regs));
+
+	if (fixup)
+		action = MIPS_BE_FIXUP;
+
+	if (board_be_handler)
+		action = board_be_handler(regs, fixup != 0);
+
+	switch (action) {
+	case MIPS_BE_DISCARD:
+		return;
+	case MIPS_BE_FIXUP:
+		if (fixup) {
+			regs->cp0_epc = fixup->nextinsn;
+			return;
+		}
+		break;
+	default:
+		break;
+	}
+
+	/*
+	 * Assume it would be too dangerous to continue ...
+	 */
+	printk(KERN_ALERT "%s bus error, epc == %0*lx, ra == %0*lx\n",
+	       data ? "Data" : "Instruction",
+	       field, regs->cp0_epc, field, regs->regs[31]);
+	die_if_kernel("Oops", regs);
+	force_sig(SIGBUS, current);
+}
+
+static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode)
+{
+	unsigned int *epc;
+
+	epc = (unsigned int *) regs->cp0_epc +
+	      ((regs->cp0_cause & CAUSEF_BD) != 0);
+	if (!get_user(*opcode, epc))
+		return 0;
+
+	force_sig(SIGSEGV, current);
+	return 1;
+}
+
+/*
+ * ll/sc emulation
+ */
+
+#define OPCODE 0xfc000000
+#define BASE   0x03e00000
+#define RT     0x001f0000
+#define OFFSET 0x0000ffff
+#define LL     0xc0000000
+#define SC     0xe0000000
+
+/*
+ * The ll_bit is cleared by r*_switch.S
+ */
+
+unsigned long ll_bit;
+
+static struct task_struct *ll_task = NULL;
+
+static inline void simulate_ll(struct pt_regs *regs, unsigned int opcode)
+{
+	unsigned long value, *vaddr;
+	long offset;
+	int signal = 0;
+
+	/*
+	 * analyse the ll instruction that just caused a ri exception
+	 * and put the referenced address to addr.
+	 */
+
+	/* sign extend offset */
+	offset = opcode & OFFSET;
+	offset <<= 16;
+	offset >>= 16;
+
+	vaddr = (unsigned long *)((long)(regs->regs[(opcode & BASE) >> 21]) + offset);
+
+	if ((unsigned long)vaddr & 3) {
+		signal = SIGBUS;
+		goto sig;
+	}
+	if (get_user(value, vaddr)) {
+		signal = SIGSEGV;
+		goto sig;
+	}
+
+	preempt_disable();
+
+	if (ll_task == NULL || ll_task == current) {
+		ll_bit = 1;
+	} else {
+		ll_bit = 0;
+	}
+	ll_task = current;
+
+	preempt_enable();
+
+	regs->regs[(opcode & RT) >> 16] = value;
+
+	compute_return_epc(regs);
+	return;
+
+sig:
+	force_sig(signal, current);
+}
+
+static inline void simulate_sc(struct pt_regs *regs, unsigned int opcode)
+{
+	unsigned long *vaddr, reg;
+	long offset;
+	int signal = 0;
+
+	/*
+	 * analyse the sc instruction that just caused a ri exception
+	 * and put the referenced address to addr.
+	 */
+
+	/* sign extend offset */
+	offset = opcode & OFFSET;
+	offset <<= 16;
+	offset >>= 16;
+
+	vaddr = (unsigned long *)((long)(regs->regs[(opcode & BASE) >> 21]) + offset);
+	reg = (opcode & RT) >> 16;
+
+	if ((unsigned long)vaddr & 3) {
+		signal = SIGBUS;
+		goto sig;
+	}
+
+	preempt_disable();
+
+	if (ll_bit == 0 || ll_task != current) {
+		regs->regs[reg] = 0;
+		preempt_enable();
+		compute_return_epc(regs);
+		return;
+	}
+
+	preempt_enable();
+
+	if (put_user(regs->regs[reg], vaddr)) {
+		signal = SIGSEGV;
+		goto sig;
+	}
+
+	regs->regs[reg] = 1;
+
+	compute_return_epc(regs);
+	return;
+
+sig:
+	force_sig(signal, current);
+}
+
+/*
+ * ll uses the opcode of lwc0 and sc uses the opcode of swc0.  That is both
+ * opcodes are supposed to result in coprocessor unusable exceptions if
+ * executed on ll/sc-less processors.  That's the theory.  In practice a
+ * few processors such as NEC's VR4100 throw reserved instruction exceptions
+ * instead, so we're doing the emulation thing in both exception handlers.
+ */
+static inline int simulate_llsc(struct pt_regs *regs)
+{
+	unsigned int opcode;
+
+	if (unlikely(get_insn_opcode(regs, &opcode)))
+		return -EFAULT;
+
+	if ((opcode & OPCODE) == LL) {
+		simulate_ll(regs, opcode);
+		return 0;
+	}
+	if ((opcode & OPCODE) == SC) {
+		simulate_sc(regs, opcode);
+		return 0;
+	}
+
+	return -EFAULT;			/* Strange things going on ... */
+}
+
+asmlinkage void do_ov(struct pt_regs *regs)
+{
+	siginfo_t info;
+
+	info.si_code = FPE_INTOVF;
+	info.si_signo = SIGFPE;
+	info.si_errno = 0;
+	info.si_addr = (void *)regs->cp0_epc;
+	force_sig_info(SIGFPE, &info, current);
+}
+
+/*
+ * XXX Delayed fp exceptions when doing a lazy ctx switch XXX
+ */
+asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
+{
+	if (fcr31 & FPU_CSR_UNI_X) {
+		int sig;
+
+		preempt_disable();
+
+		/*
+	 	 * Unimplemented operation exception.  If we've got the full
+		 * software emulator on-board, let's use it...
+		 *
+		 * Force FPU to dump state into task/thread context.  We're
+		 * moving a lot of data here for what is probably a single
+		 * instruction, but the alternative is to pre-decode the FP
+		 * register operands before invoking the emulator, which seems
+		 * a bit extreme for what should be an infrequent event.
+		 */
+		save_fp(current);
+
+		/* Run the emulator */
+		sig = fpu_emulator_cop1Handler (0, regs,
+			&current->thread.fpu.soft);
+
+		/*
+		 * We can't allow the emulated instruction to leave any of
+		 * the cause bit set in $fcr31.
+		 */
+		current->thread.fpu.soft.fcr31 &= ~FPU_CSR_ALL_X;
+
+		/* Restore the hardware register state */
+		restore_fp(current);
+
+		preempt_enable();
+
+		/* If something went wrong, signal */
+		if (sig)
+			force_sig(sig, current);
+
+		return;
+	}
+
+	force_sig(SIGFPE, current);
+}
+
+asmlinkage void do_bp(struct pt_regs *regs)
+{
+	unsigned int opcode, bcode;
+	siginfo_t info;
+
+	die_if_kernel("Break instruction in kernel code", regs);
+
+	if (get_insn_opcode(regs, &opcode))
+		return;
+
+	/*
+	 * There is the ancient bug in the MIPS assemblers that the break
+	 * code starts left to bit 16 instead to bit 6 in the opcode.
+	 * Gas is bug-compatible, but not always, grrr...
+	 * We handle both cases with a simple heuristics.  --macro
+	 */
+	bcode = ((opcode >> 6) & ((1 << 20) - 1));
+	if (bcode < (1 << 10))
+		bcode <<= 10;
+
+	/*
+	 * (A short test says that IRIX 5.3 sends SIGTRAP for all break
+	 * insns, even for break codes that indicate arithmetic failures.
+	 * Weird ...)
+	 * But should we continue the brokenness???  --macro
+	 */
+	switch (bcode) {
+	case BRK_OVERFLOW << 10:
+	case BRK_DIVZERO << 10:
+		if (bcode == (BRK_DIVZERO << 10))
+			info.si_code = FPE_INTDIV;
+		else
+			info.si_code = FPE_INTOVF;
+		info.si_signo = SIGFPE;
+		info.si_errno = 0;
+		info.si_addr = (void *)regs->cp0_epc;
+		force_sig_info(SIGFPE, &info, current);
+		break;
+	default:
+		force_sig(SIGTRAP, current);
+	}
+}
+
+asmlinkage void do_tr(struct pt_regs *regs)
+{
+	unsigned int opcode, tcode = 0;
+	siginfo_t info;
+
+	die_if_kernel("Trap instruction in kernel code", regs);
+
+	if (get_insn_opcode(regs, &opcode))
+		return;
+
+	/* Immediate versions don't provide a code.  */
+	if (!(opcode & OPCODE))
+		tcode = ((opcode >> 6) & ((1 << 10) - 1));
+
+	/*
+	 * (A short test says that IRIX 5.3 sends SIGTRAP for all trap
+	 * insns, even for trap codes that indicate arithmetic failures.
+	 * Weird ...)
+	 * But should we continue the brokenness???  --macro
+	 */
+	switch (tcode) {
+	case BRK_OVERFLOW:
+	case BRK_DIVZERO:
+		if (tcode == BRK_DIVZERO)
+			info.si_code = FPE_INTDIV;
+		else
+			info.si_code = FPE_INTOVF;
+		info.si_signo = SIGFPE;
+		info.si_errno = 0;
+		info.si_addr = (void *)regs->cp0_epc;
+		force_sig_info(SIGFPE, &info, current);
+		break;
+	default:
+		force_sig(SIGTRAP, current);
+	}
+}
+
+asmlinkage void do_ri(struct pt_regs *regs)
+{
+	die_if_kernel("Reserved instruction in kernel code", regs);
+
+	if (!cpu_has_llsc)
+		if (!simulate_llsc(regs))
+			return;
+
+	force_sig(SIGILL, current);
+}
+
+asmlinkage void do_cpu(struct pt_regs *regs)
+{
+	unsigned int cpid;
+
+	die_if_kernel("do_cpu invoked from kernel context!", regs);
+
+	cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
+
+	switch (cpid) {
+	case 0:
+		if (cpu_has_llsc)
+			break;
+
+		if (!simulate_llsc(regs))
+			return;
+		break;
+
+	case 1:
+		preempt_disable();
+
+		own_fpu();
+		if (used_math()) {	/* Using the FPU again.  */
+			restore_fp(current);
+		} else {			/* First time FPU user.  */
+			init_fpu();
+			set_used_math();
+		}
+
+		if (!cpu_has_fpu) {
+			int sig = fpu_emulator_cop1Handler(0, regs,
+						&current->thread.fpu.soft);
+			if (sig)
+				force_sig(sig, current);
+		}
+
+		preempt_enable();
+
+		return;
+
+	case 2:
+	case 3:
+		break;
+	}
+
+	force_sig(SIGILL, current);
+}
+
+asmlinkage void do_mdmx(struct pt_regs *regs)
+{
+	force_sig(SIGILL, current);
+}
+
+asmlinkage void do_watch(struct pt_regs *regs)
+{
+	/*
+	 * We use the watch exception where available to detect stack
+	 * overflows.
+	 */
+	dump_tlb_all();
+	show_regs(regs);
+	panic("Caught WATCH exception - probably caused by stack overflow.");
+}
+
+asmlinkage void do_mcheck(struct pt_regs *regs)
+{
+	show_regs(regs);
+	dump_tlb_all();
+	/*
+	 * Some chips may have other causes of machine check (e.g. SB1
+	 * graduation timer)
+	 */
+	panic("Caught Machine Check exception - %scaused by multiple "
+	      "matching entries in the TLB.",
+	      (regs->cp0_status & ST0_TS) ? "" : "not ");
+}
+
+asmlinkage void do_reserved(struct pt_regs *regs)
+{
+	/*
+	 * Game over - no way to handle this if it ever occurs.  Most probably
+	 * caused by a new unknown cpu type or after another deadly
+	 * hard/software error.
+	 */
+	show_regs(regs);
+	panic("Caught reserved exception %ld - should not happen.",
+	      (regs->cp0_cause & 0x7f) >> 2);
+}
+
+/*
+ * Some MIPS CPUs can enable/disable for cache parity detection, but do
+ * it different ways.
+ */
+static inline void parity_protection_init(void)
+{
+	switch (current_cpu_data.cputype) {
+	case CPU_24K:
+		/* 24K cache parity not currently implemented in FPGA */
+		printk(KERN_INFO "Disable cache parity protection for "
+		       "MIPS 24K CPU.\n");
+		write_c0_ecc(read_c0_ecc() & ~0x80000000);
+		break;
+	case CPU_5KC:
+		/* Set the PE bit (bit 31) in the c0_ecc register. */
+		printk(KERN_INFO "Enable cache parity protection for "
+		       "MIPS 5KC/24K CPUs.\n");
+		write_c0_ecc(read_c0_ecc() | 0x80000000);
+		break;
+	case CPU_20KC:
+	case CPU_25KF:
+		/* Clear the DE bit (bit 16) in the c0_status register. */
+		printk(KERN_INFO "Enable cache parity protection for "
+		       "MIPS 20KC/25KF CPUs.\n");
+		clear_c0_status(ST0_DE);
+		break;
+	default:
+		break;
+	}
+}
+
+asmlinkage void cache_parity_error(void)
+{
+	const int field = 2 * sizeof(unsigned long);
+	unsigned int reg_val;
+
+	/* For the moment, report the problem and hang. */
+	printk("Cache error exception:\n");
+	printk("cp0_errorepc == %0*lx\n", field, read_c0_errorepc());
+	reg_val = read_c0_cacheerr();
+	printk("c0_cacheerr == %08x\n", reg_val);
+
+	printk("Decoded c0_cacheerr: %s cache fault in %s reference.\n",
+	       reg_val & (1<<30) ? "secondary" : "primary",
+	       reg_val & (1<<31) ? "data" : "insn");
+	printk("Error bits: %s%s%s%s%s%s%s\n",
+	       reg_val & (1<<29) ? "ED " : "",
+	       reg_val & (1<<28) ? "ET " : "",
+	       reg_val & (1<<26) ? "EE " : "",
+	       reg_val & (1<<25) ? "EB " : "",
+	       reg_val & (1<<24) ? "EI " : "",
+	       reg_val & (1<<23) ? "E1 " : "",
+	       reg_val & (1<<22) ? "E0 " : "");
+	printk("IDX: 0x%08x\n", reg_val & ((1<<22)-1));
+
+#if defined(CONFIG_CPU_MIPS32) || defined (CONFIG_CPU_MIPS64)
+	if (reg_val & (1<<22))
+		printk("DErrAddr0: 0x%0*lx\n", field, read_c0_derraddr0());
+
+	if (reg_val & (1<<23))
+		printk("DErrAddr1: 0x%0*lx\n", field, read_c0_derraddr1());
+#endif
+
+	panic("Can't handle the cache error!");
+}
+
+/*
+ * SDBBP EJTAG debug exception handler.
+ * We skip the instruction and return to the next instruction.
+ */
+void ejtag_exception_handler(struct pt_regs *regs)
+{
+	const int field = 2 * sizeof(unsigned long);
+	unsigned long depc, old_epc;
+	unsigned int debug;
+
+	printk("SDBBP EJTAG debug exception - not handled yet, just ignored!\n");
+	depc = read_c0_depc();
+	debug = read_c0_debug();
+	printk("c0_depc = %0*lx, DEBUG = %08x\n", field, depc, debug);
+	if (debug & 0x80000000) {
+		/*
+		 * In branch delay slot.
+		 * We cheat a little bit here and use EPC to calculate the
+		 * debug return address (DEPC). EPC is restored after the
+		 * calculation.
+		 */
+		old_epc = regs->cp0_epc;
+		regs->cp0_epc = depc;
+		__compute_return_epc(regs);
+		depc = regs->cp0_epc;
+		regs->cp0_epc = old_epc;
+	} else
+		depc += 4;
+	write_c0_depc(depc);
+
+#if 0
+	printk("\n\n----- Enable EJTAG single stepping ----\n\n");
+	write_c0_debug(debug | 0x100);
+#endif
+}
+
+/*
+ * NMI exception handler.
+ */
+void nmi_exception_handler(struct pt_regs *regs)
+{
+	printk("NMI taken!!!!\n");
+	die("NMI", regs);
+	while(1) ;
+}
+
+unsigned long exception_handlers[32];
+
+/*
+ * As a side effect of the way this is implemented we're limited
+ * to interrupt handlers in the address range from
+ * KSEG0 <= x < KSEG0 + 256mb on the Nevada.  Oh well ...
+ */
+void *set_except_vector(int n, void *addr)
+{
+	unsigned long handler = (unsigned long) addr;
+	unsigned long old_handler = exception_handlers[n];
+
+	exception_handlers[n] = handler;
+	if (n == 0 && cpu_has_divec) {
+		*(volatile u32 *)(CAC_BASE + 0x200) = 0x08000000 |
+		                                 (0x03ffffff & (handler >> 2));
+		flush_icache_range(CAC_BASE + 0x200, CAC_BASE + 0x204);
+	}
+	return (void *)old_handler;
+}
+
+/*
+ * This is used by native signal handling
+ */
+asmlinkage int (*save_fp_context)(struct sigcontext *sc);
+asmlinkage int (*restore_fp_context)(struct sigcontext *sc);
+
+extern asmlinkage int _save_fp_context(struct sigcontext *sc);
+extern asmlinkage int _restore_fp_context(struct sigcontext *sc);
+
+extern asmlinkage int fpu_emulator_save_context(struct sigcontext *sc);
+extern asmlinkage int fpu_emulator_restore_context(struct sigcontext *sc);
+
+static inline void signal_init(void)
+{
+	if (cpu_has_fpu) {
+		save_fp_context = _save_fp_context;
+		restore_fp_context = _restore_fp_context;
+	} else {
+		save_fp_context = fpu_emulator_save_context;
+		restore_fp_context = fpu_emulator_restore_context;
+	}
+}
+
+#ifdef CONFIG_MIPS32_COMPAT
+
+/*
+ * This is used by 32-bit signal stuff on the 64-bit kernel
+ */
+asmlinkage int (*save_fp_context32)(struct sigcontext32 *sc);
+asmlinkage int (*restore_fp_context32)(struct sigcontext32 *sc);
+
+extern asmlinkage int _save_fp_context32(struct sigcontext32 *sc);
+extern asmlinkage int _restore_fp_context32(struct sigcontext32 *sc);
+
+extern asmlinkage int fpu_emulator_save_context32(struct sigcontext32 *sc);
+extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 *sc);
+
+static inline void signal32_init(void)
+{
+	if (cpu_has_fpu) {
+		save_fp_context32 = _save_fp_context32;
+		restore_fp_context32 = _restore_fp_context32;
+	} else {
+		save_fp_context32 = fpu_emulator_save_context32;
+		restore_fp_context32 = fpu_emulator_restore_context32;
+	}
+}
+#endif
+
+extern void cpu_cache_init(void);
+extern void tlb_init(void);
+
+void __init per_cpu_trap_init(void)
+{
+	unsigned int cpu = smp_processor_id();
+	unsigned int status_set = ST0_CU0;
+
+	/*
+	 * Disable coprocessors and select 32-bit or 64-bit addressing
+	 * and the 16/32 or 32/32 FPR register model.  Reset the BEV
+	 * flag that some firmware may have left set and the TS bit (for
+	 * IP27).  Set XX for ISA IV code to work.
+	 */
+#ifdef CONFIG_MIPS64
+	status_set |= ST0_FR|ST0_KX|ST0_SX|ST0_UX;
+#endif
+	if (current_cpu_data.isa_level == MIPS_CPU_ISA_IV)
+		status_set |= ST0_XX;
+	change_c0_status(ST0_CU|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX,
+			 status_set);
+
+	/*
+	 * Some MIPS CPUs have a dedicated interrupt vector which reduces the
+	 * interrupt processing overhead.  Use it where available.
+	 */
+	if (cpu_has_divec)
+		set_c0_cause(CAUSEF_IV);
+
+	cpu_data[cpu].asid_cache = ASID_FIRST_VERSION;
+	TLBMISS_HANDLER_SETUP();
+
+	atomic_inc(&init_mm.mm_count);
+	current->active_mm = &init_mm;
+	BUG_ON(current->mm);
+	enter_lazy_tlb(&init_mm, current);
+
+	cpu_cache_init();
+	tlb_init();
+}
+
+void __init trap_init(void)
+{
+	extern char except_vec3_generic, except_vec3_r4000;
+	extern char except_vec_ejtag_debug;
+	extern char except_vec4;
+	unsigned long i;
+
+	per_cpu_trap_init();
+
+	/*
+	 * Copy the generic exception handlers to their final destination.
+	 * This will be overriden later as suitable for a particular
+	 * configuration.
+	 */
+	memcpy((void *)(CAC_BASE + 0x180), &except_vec3_generic, 0x80);
+
+	/*
+	 * Setup default vectors
+	 */
+	for (i = 0; i <= 31; i++)
+		set_except_vector(i, handle_reserved);
+
+	/*
+	 * Copy the EJTAG debug exception vector handler code to it's final
+	 * destination.
+	 */
+	if (cpu_has_ejtag)
+		memcpy((void *)(CAC_BASE + 0x300), &except_vec_ejtag_debug, 0x80);
+
+	/*
+	 * Only some CPUs have the watch exceptions.
+	 */
+	if (cpu_has_watch)
+		set_except_vector(23, handle_watch);
+
+	/*
+	 * Some MIPS CPUs have a dedicated interrupt vector which reduces the
+	 * interrupt processing overhead.  Use it where available.
+	 */
+	if (cpu_has_divec)
+		memcpy((void *)(CAC_BASE + 0x200), &except_vec4, 0x8);
+
+	/*
+	 * Some CPUs can enable/disable for cache parity detection, but does
+	 * it different ways.
+	 */
+	parity_protection_init();
+
+	/*
+	 * The Data Bus Errors / Instruction Bus Errors are signaled
+	 * by external hardware.  Therefore these two exceptions
+	 * may have board specific handlers.
+	 */
+	if (board_be_init)
+		board_be_init();
+
+	set_except_vector(1, handle_tlbm);
+	set_except_vector(2, handle_tlbl);
+	set_except_vector(3, handle_tlbs);
+
+	set_except_vector(4, handle_adel);
+	set_except_vector(5, handle_ades);
+
+	set_except_vector(6, handle_ibe);
+	set_except_vector(7, handle_dbe);
+
+	set_except_vector(8, handle_sys);
+	set_except_vector(9, handle_bp);
+	set_except_vector(10, handle_ri);
+	set_except_vector(11, handle_cpu);
+	set_except_vector(12, handle_ov);
+	set_except_vector(13, handle_tr);
+	set_except_vector(22, handle_mdmx);
+
+	if (cpu_has_fpu && !cpu_has_nofpuex)
+		set_except_vector(15, handle_fpe);
+
+	if (cpu_has_mcheck)
+		set_except_vector(24, handle_mcheck);
+
+	if (cpu_has_vce)
+		/* Special exception: R4[04]00 uses also the divec space. */
+		memcpy((void *)(CAC_BASE + 0x180), &except_vec3_r4000, 0x100);
+	else if (cpu_has_4kex)
+		memcpy((void *)(CAC_BASE + 0x180), &except_vec3_generic, 0x80);
+	else
+		memcpy((void *)(CAC_BASE + 0x080), &except_vec3_generic, 0x80);
+
+	if (current_cpu_data.cputype == CPU_R6000 ||
+	    current_cpu_data.cputype == CPU_R6000A) {
+		/*
+		 * The R6000 is the only R-series CPU that features a machine
+		 * check exception (similar to the R4000 cache error) and
+		 * unaligned ldc1/sdc1 exception.  The handlers have not been
+		 * written yet.  Well, anyway there is no R6000 machine on the
+		 * current list of targets for Linux/MIPS.
+		 * (Duh, crap, there is someone with a triple R6k machine)
+		 */
+		//set_except_vector(14, handle_mc);
+		//set_except_vector(15, handle_ndc);
+	}
+
+	signal_init();
+#ifdef CONFIG_MIPS32_COMPAT
+	signal32_init();
+#endif
+
+	flush_icache_range(CAC_BASE, CAC_BASE + 0x400);
+}
diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c
new file mode 100644
index 0000000..3f24a1d
--- /dev/null
+++ b/arch/mips/kernel/unaligned.c
@@ -0,0 +1,550 @@
+/*
+ * Handle unaligned accesses by emulation.
+ *
+ * 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) 1996, 1998, 1999, 2002 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ *
+ * This file contains exception handler for address error exception with the
+ * special capability to execute faulting instructions in software.  The
+ * handler does not try to handle the case when the program counter points
+ * to an address not aligned to a word boundary.
+ *
+ * Putting data to unaligned addresses is a bad practice even on Intel where
+ * only the performance is affected.  Much worse is that such code is non-
+ * portable.  Due to several programs that die on MIPS due to alignment
+ * problems I decided to implement this handler anyway though I originally
+ * didn't intend to do this at all for user code.
+ *
+ * For now I enable fixing of address errors by default to make life easier.
+ * I however intend to disable this somewhen in the future when the alignment
+ * problems with user programs have been fixed.  For programmers this is the
+ * right way to go.
+ *
+ * Fixing address errors is a per process option.  The option is inherited
+ * across fork(2) and execve(2) calls.  If you really want to use the
+ * option in your user programs - I discourage the use of the software
+ * emulation strongly - use the following code in your userland stuff:
+ *
+ * #include <sys/sysmips.h>
+ *
+ * ...
+ * sysmips(MIPS_FIXADE, x);
+ * ...
+ *
+ * The argument x is 0 for disabling software emulation, enabled otherwise.
+ *
+ * Below a little program to play around with this feature.
+ *
+ * #include <stdio.h>
+ * #include <sys/sysmips.h>
+ *
+ * struct foo {
+ *         unsigned char bar[8];
+ * };
+ *
+ * main(int argc, char *argv[])
+ * {
+ *         struct foo x = {0, 1, 2, 3, 4, 5, 6, 7};
+ *         unsigned int *p = (unsigned int *) (x.bar + 3);
+ *         int i;
+ *
+ *         if (argc > 1)
+ *                 sysmips(MIPS_FIXADE, atoi(argv[1]));
+ *
+ *         printf("*p = %08lx\n", *p);
+ *
+ *         *p = 0xdeadface;
+ *
+ *         for(i = 0; i <= 7; i++)
+ *         printf("%02x ", x.bar[i]);
+ *         printf("\n");
+ * }
+ *
+ * Coprocessor loads are not supported; I think this case is unimportant
+ * in the practice.
+ *
+ * TODO: Handle ndc (attempted store to doubleword in uncached memory)
+ *       exception for the R6000.
+ *       A store crossing a page boundary might be executed only partially.
+ *       Undo the partial store in this case.
+ */
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+
+#include <asm/asm.h>
+#include <asm/branch.h>
+#include <asm/byteorder.h>
+#include <asm/inst.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
+#define STR(x)  __STR(x)
+#define __STR(x)  #x
+
+#ifdef CONFIG_PROC_FS
+unsigned long unaligned_instructions;
+#endif
+
+static inline int emulate_load_store_insn(struct pt_regs *regs,
+	void *addr, unsigned long pc,
+	unsigned long **regptr, unsigned long *newvalue)
+{
+	union mips_instruction insn;
+	unsigned long value;
+	unsigned int res;
+
+	regs->regs[0] = 0;
+	*regptr=NULL;
+
+	/*
+	 * This load never faults.
+	 */
+	__get_user(insn.word, (unsigned int *)pc);
+
+	switch (insn.i_format.opcode) {
+	/*
+	 * These are instructions that a compiler doesn't generate.  We
+	 * can assume therefore that the code is MIPS-aware and
+	 * really buggy.  Emulating these instructions would break the
+	 * semantics anyway.
+	 */
+	case ll_op:
+	case lld_op:
+	case sc_op:
+	case scd_op:
+
+	/*
+	 * For these instructions the only way to create an address
+	 * error is an attempted access to kernel/supervisor address
+	 * space.
+	 */
+	case ldl_op:
+	case ldr_op:
+	case lwl_op:
+	case lwr_op:
+	case sdl_op:
+	case sdr_op:
+	case swl_op:
+	case swr_op:
+	case lb_op:
+	case lbu_op:
+	case sb_op:
+		goto sigbus;
+
+	/*
+	 * The remaining opcodes are the ones that are really of interest.
+	 */
+	case lh_op:
+		if (!access_ok(VERIFY_READ, addr, 2))
+			goto sigbus;
+
+		__asm__ __volatile__ (".set\tnoat\n"
+#ifdef __BIG_ENDIAN
+			"1:\tlb\t%0, 0(%2)\n"
+			"2:\tlbu\t$1, 1(%2)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+			"1:\tlb\t%0, 1(%2)\n"
+			"2:\tlbu\t$1, 0(%2)\n\t"
+#endif
+			"sll\t%0, 0x8\n\t"
+			"or\t%0, $1\n\t"
+			"li\t%1, 0\n"
+			"3:\t.set\tat\n\t"
+			".section\t.fixup,\"ax\"\n\t"
+			"4:\tli\t%1, %3\n\t"
+			"j\t3b\n\t"
+			".previous\n\t"
+			".section\t__ex_table,\"a\"\n\t"
+			STR(PTR)"\t1b, 4b\n\t"
+			STR(PTR)"\t2b, 4b\n\t"
+			".previous"
+			: "=&r" (value), "=r" (res)
+			: "r" (addr), "i" (-EFAULT));
+		if (res)
+			goto fault;
+		*newvalue = value;
+		*regptr = &regs->regs[insn.i_format.rt];
+		break;
+
+	case lw_op:
+		if (!access_ok(VERIFY_READ, addr, 4))
+			goto sigbus;
+
+		__asm__ __volatile__ (
+#ifdef __BIG_ENDIAN
+			"1:\tlwl\t%0, (%2)\n"
+			"2:\tlwr\t%0, 3(%2)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+			"1:\tlwl\t%0, 3(%2)\n"
+			"2:\tlwr\t%0, (%2)\n\t"
+#endif
+			"li\t%1, 0\n"
+			"3:\t.section\t.fixup,\"ax\"\n\t"
+			"4:\tli\t%1, %3\n\t"
+			"j\t3b\n\t"
+			".previous\n\t"
+			".section\t__ex_table,\"a\"\n\t"
+			STR(PTR)"\t1b, 4b\n\t"
+			STR(PTR)"\t2b, 4b\n\t"
+			".previous"
+			: "=&r" (value), "=r" (res)
+			: "r" (addr), "i" (-EFAULT));
+		if (res)
+			goto fault;
+		*newvalue = value;
+		*regptr = &regs->regs[insn.i_format.rt];
+		break;
+
+	case lhu_op:
+		if (!access_ok(VERIFY_READ, addr, 2))
+			goto sigbus;
+
+		__asm__ __volatile__ (
+			".set\tnoat\n"
+#ifdef __BIG_ENDIAN
+			"1:\tlbu\t%0, 0(%2)\n"
+			"2:\tlbu\t$1, 1(%2)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+			"1:\tlbu\t%0, 1(%2)\n"
+			"2:\tlbu\t$1, 0(%2)\n\t"
+#endif
+			"sll\t%0, 0x8\n\t"
+			"or\t%0, $1\n\t"
+			"li\t%1, 0\n"
+			"3:\t.set\tat\n\t"
+			".section\t.fixup,\"ax\"\n\t"
+			"4:\tli\t%1, %3\n\t"
+			"j\t3b\n\t"
+			".previous\n\t"
+			".section\t__ex_table,\"a\"\n\t"
+			STR(PTR)"\t1b, 4b\n\t"
+			STR(PTR)"\t2b, 4b\n\t"
+			".previous"
+			: "=&r" (value), "=r" (res)
+			: "r" (addr), "i" (-EFAULT));
+		if (res)
+			goto fault;
+		*newvalue = value;
+		*regptr = &regs->regs[insn.i_format.rt];
+		break;
+
+	case lwu_op:
+#ifdef CONFIG_MIPS64
+		/*
+		 * A 32-bit kernel might be running on a 64-bit processor.  But
+		 * if we're on a 32-bit processor and an i-cache incoherency
+		 * or race makes us see a 64-bit instruction here the sdl/sdr
+		 * would blow up, so for now we don't handle unaligned 64-bit
+		 * instructions on 32-bit kernels.
+		 */
+		if (!access_ok(VERIFY_READ, addr, 4))
+			goto sigbus;
+
+		__asm__ __volatile__ (
+#ifdef __BIG_ENDIAN
+			"1:\tlwl\t%0, (%2)\n"
+			"2:\tlwr\t%0, 3(%2)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+			"1:\tlwl\t%0, 3(%2)\n"
+			"2:\tlwr\t%0, (%2)\n\t"
+#endif
+			"dsll\t%0, %0, 32\n\t"
+			"dsrl\t%0, %0, 32\n\t"
+			"li\t%1, 0\n"
+			"3:\t.section\t.fixup,\"ax\"\n\t"
+			"4:\tli\t%1, %3\n\t"
+			"j\t3b\n\t"
+			".previous\n\t"
+			".section\t__ex_table,\"a\"\n\t"
+			STR(PTR)"\t1b, 4b\n\t"
+			STR(PTR)"\t2b, 4b\n\t"
+			".previous"
+			: "=&r" (value), "=r" (res)
+			: "r" (addr), "i" (-EFAULT));
+		if (res)
+			goto fault;
+		*newvalue = value;
+		*regptr = &regs->regs[insn.i_format.rt];
+		break;
+#endif /* CONFIG_MIPS64 */
+
+		/* Cannot handle 64-bit instructions in 32-bit kernel */
+		goto sigill;
+
+	case ld_op:
+#ifdef CONFIG_MIPS64
+		/*
+		 * A 32-bit kernel might be running on a 64-bit processor.  But
+		 * if we're on a 32-bit processor and an i-cache incoherency
+		 * or race makes us see a 64-bit instruction here the sdl/sdr
+		 * would blow up, so for now we don't handle unaligned 64-bit
+		 * instructions on 32-bit kernels.
+		 */
+		if (!access_ok(VERIFY_READ, addr, 8))
+			goto sigbus;
+
+		__asm__ __volatile__ (
+#ifdef __BIG_ENDIAN
+			"1:\tldl\t%0, (%2)\n"
+			"2:\tldr\t%0, 7(%2)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+			"1:\tldl\t%0, 7(%2)\n"
+			"2:\tldr\t%0, (%2)\n\t"
+#endif
+			"li\t%1, 0\n"
+			"3:\t.section\t.fixup,\"ax\"\n\t"
+			"4:\tli\t%1, %3\n\t"
+			"j\t3b\n\t"
+			".previous\n\t"
+			".section\t__ex_table,\"a\"\n\t"
+			STR(PTR)"\t1b, 4b\n\t"
+			STR(PTR)"\t2b, 4b\n\t"
+			".previous"
+			: "=&r" (value), "=r" (res)
+			: "r" (addr), "i" (-EFAULT));
+		if (res)
+			goto fault;
+		*newvalue = value;
+		*regptr = &regs->regs[insn.i_format.rt];
+		break;
+#endif /* CONFIG_MIPS64 */
+
+		/* Cannot handle 64-bit instructions in 32-bit kernel */
+		goto sigill;
+
+	case sh_op:
+		if (!access_ok(VERIFY_WRITE, addr, 2))
+			goto sigbus;
+
+		value = regs->regs[insn.i_format.rt];
+		__asm__ __volatile__ (
+#ifdef __BIG_ENDIAN
+			".set\tnoat\n"
+			"1:\tsb\t%1, 1(%2)\n\t"
+			"srl\t$1, %1, 0x8\n"
+			"2:\tsb\t$1, 0(%2)\n\t"
+			".set\tat\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+			".set\tnoat\n"
+			"1:\tsb\t%1, 0(%2)\n\t"
+			"srl\t$1,%1, 0x8\n"
+			"2:\tsb\t$1, 1(%2)\n\t"
+			".set\tat\n\t"
+#endif
+			"li\t%0, 0\n"
+			"3:\n\t"
+			".section\t.fixup,\"ax\"\n\t"
+			"4:\tli\t%0, %3\n\t"
+			"j\t3b\n\t"
+			".previous\n\t"
+			".section\t__ex_table,\"a\"\n\t"
+			STR(PTR)"\t1b, 4b\n\t"
+			STR(PTR)"\t2b, 4b\n\t"
+			".previous"
+			: "=r" (res)
+			: "r" (value), "r" (addr), "i" (-EFAULT));
+		if (res)
+			goto fault;
+		break;
+
+	case sw_op:
+		if (!access_ok(VERIFY_WRITE, addr, 4))
+			goto sigbus;
+
+		value = regs->regs[insn.i_format.rt];
+		__asm__ __volatile__ (
+#ifdef __BIG_ENDIAN
+			"1:\tswl\t%1,(%2)\n"
+			"2:\tswr\t%1, 3(%2)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+			"1:\tswl\t%1, 3(%2)\n"
+			"2:\tswr\t%1, (%2)\n\t"
+#endif
+			"li\t%0, 0\n"
+			"3:\n\t"
+			".section\t.fixup,\"ax\"\n\t"
+			"4:\tli\t%0, %3\n\t"
+			"j\t3b\n\t"
+			".previous\n\t"
+			".section\t__ex_table,\"a\"\n\t"
+			STR(PTR)"\t1b, 4b\n\t"
+			STR(PTR)"\t2b, 4b\n\t"
+			".previous"
+		: "=r" (res)
+		: "r" (value), "r" (addr), "i" (-EFAULT));
+		if (res)
+			goto fault;
+		break;
+
+	case sd_op:
+#ifdef CONFIG_MIPS64
+		/*
+		 * A 32-bit kernel might be running on a 64-bit processor.  But
+		 * if we're on a 32-bit processor and an i-cache incoherency
+		 * or race makes us see a 64-bit instruction here the sdl/sdr
+		 * would blow up, so for now we don't handle unaligned 64-bit
+		 * instructions on 32-bit kernels.
+		 */
+		if (!access_ok(VERIFY_WRITE, addr, 8))
+			goto sigbus;
+
+		value = regs->regs[insn.i_format.rt];
+		__asm__ __volatile__ (
+#ifdef __BIG_ENDIAN
+			"1:\tsdl\t%1,(%2)\n"
+			"2:\tsdr\t%1, 7(%2)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+			"1:\tsdl\t%1, 7(%2)\n"
+			"2:\tsdr\t%1, (%2)\n\t"
+#endif
+			"li\t%0, 0\n"
+			"3:\n\t"
+			".section\t.fixup,\"ax\"\n\t"
+			"4:\tli\t%0, %3\n\t"
+			"j\t3b\n\t"
+			".previous\n\t"
+			".section\t__ex_table,\"a\"\n\t"
+			STR(PTR)"\t1b, 4b\n\t"
+			STR(PTR)"\t2b, 4b\n\t"
+			".previous"
+		: "=r" (res)
+		: "r" (value), "r" (addr), "i" (-EFAULT));
+		if (res)
+			goto fault;
+		break;
+#endif /* CONFIG_MIPS64 */
+
+		/* Cannot handle 64-bit instructions in 32-bit kernel */
+		goto sigill;
+
+	case lwc1_op:
+	case ldc1_op:
+	case swc1_op:
+	case sdc1_op:
+		/*
+		 * I herewith declare: this does not happen.  So send SIGBUS.
+		 */
+		goto sigbus;
+
+	case lwc2_op:
+	case ldc2_op:
+	case swc2_op:
+	case sdc2_op:
+		/*
+		 * These are the coprocessor 2 load/stores.  The current
+		 * implementations don't use cp2 and cp2 should always be
+		 * disabled in c0_status.  So send SIGILL.
+                 * (No longer true: The Sony Praystation uses cp2 for
+                 * 3D matrix operations.  Dunno if that thingy has a MMU ...)
+		 */
+	default:
+		/*
+		 * Pheeee...  We encountered an yet unknown instruction or
+		 * cache coherence problem.  Die sucker, die ...
+		 */
+		goto sigill;
+	}
+
+#ifdef CONFIG_PROC_FS
+	unaligned_instructions++;
+#endif
+
+	return 0;
+
+fault:
+	/* Did we have an exception handler installed? */
+	if (fixup_exception(regs))
+		return 1;
+
+	die_if_kernel ("Unhandled kernel unaligned access", regs);
+	send_sig(SIGSEGV, current, 1);
+
+	return 0;
+
+sigbus:
+	die_if_kernel("Unhandled kernel unaligned access", regs);
+	send_sig(SIGBUS, current, 1);
+
+	return 0;
+
+sigill:
+	die_if_kernel("Unhandled kernel unaligned access or invalid instruction", regs);
+	send_sig(SIGILL, current, 1);
+
+	return 0;
+}
+
+asmlinkage void do_ade(struct pt_regs *regs)
+{
+	unsigned long *regptr, newval;
+	extern int do_dsemulret(struct pt_regs *);
+	mm_segment_t seg;
+	unsigned long pc;
+
+	/*
+	 * Address errors may be deliberately induced by the FPU emulator to
+	 * retake control of the CPU after executing the instruction in the
+	 * delay slot of an emulated branch.
+	 */
+	/* Terminate if exception was recognized as a delay slot return */
+	if (do_dsemulret(regs))
+		return;
+
+	/* Otherwise handle as normal */
+
+	/*
+	 * Did we catch a fault trying to load an instruction?
+	 * Or are we running in MIPS16 mode?
+	 */
+	if ((regs->cp0_badvaddr == regs->cp0_epc) || (regs->cp0_epc & 0x1))
+		goto sigbus;
+
+	pc = exception_epc(regs);
+	if ((current->thread.mflags & MF_FIXADE) == 0)
+		goto sigbus;
+
+	/*
+	 * Do branch emulation only if we didn't forward the exception.
+	 * This is all so but ugly ...
+	 */
+	seg = get_fs();
+	if (!user_mode(regs))
+		set_fs(KERNEL_DS);
+	if (!emulate_load_store_insn(regs, (void *)regs->cp0_badvaddr, pc,
+	                             &regptr, &newval)) {
+		compute_return_epc(regs);
+		/*
+		 * Now that branch is evaluated, update the dest
+		 * register if necessary
+		 */
+		if (regptr)
+			*regptr = newval;
+	}
+	set_fs(seg);
+
+	return;
+
+sigbus:
+	die_if_kernel("Kernel unaligned instruction access", regs);
+	force_sig(SIGBUS, current);
+
+	/*
+	 * XXX On return from the signal handler we should advance the epc
+	 */
+}
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
new file mode 100644
index 0000000..e830d78
--- /dev/null
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -0,0 +1,183 @@
+#include <linux/config.h>
+#include <asm-generic/vmlinux.lds.h>
+
+#undef mips		/* CPP really sucks for this job  */
+#define mips mips
+OUTPUT_ARCH(mips)
+ENTRY(kernel_entry)
+jiffies = JIFFIES;
+SECTIONS
+{
+#ifdef CONFIG_BOOT_ELF64
+  /* Read-only sections, merged into text segment: */
+  /* . = 0xc000000000000000; */
+
+  /* This is the value for an Origin kernel, taken from an IRIX kernel.  */
+  /* . = 0xc00000000001c000; */
+
+  /* Set the vaddr for the text segment to a value 
+        >= 0xa800 0000 0001 9000 if no symmon is going to configured
+        >= 0xa800 0000 0030 0000 otherwise  */
+
+  /* . = 0xa800000000300000; */
+  /* . = 0xa800000000300000; */
+  . = 0xffffffff80300000;
+#endif
+  . = LOADADDR;
+  /* read-only */
+  _text = .;			/* Text and read-only data */
+  .text : {
+    *(.text)
+    SCHED_TEXT
+    LOCK_TEXT
+    *(.fixup)
+    *(.gnu.warning)
+  } =0
+
+  _etext = .;			/* End of text section */
+
+  . = ALIGN(16);		/* Exception table */
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  __start___dbe_table = .;	/* Exception table for data bus errors */
+  __dbe_table : { *(__dbe_table) }
+  __stop___dbe_table = .;
+
+  RODATA
+
+  /* writeable */
+  .data : {			/* Data */
+    . = . + DATAOFFSET;		/* for CONFIG_MAPPED_KERNEL */
+    *(.data.init_task)
+
+    *(.data)
+
+   /* Align the initial ramdisk image (INITRD) on page boundaries. */
+   . = ALIGN(4096);
+   __rd_start = .;
+   *(.initrd)
+   . = ALIGN(4096);
+   __rd_end = .;
+
+    CONSTRUCTORS
+  }
+  _gp = . + 0x8000;
+  .lit8 : { *(.lit8) }
+  .lit4 : { *(.lit4) }
+  /* 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) }
+
+  . = ALIGN(4096);
+  __nosave_begin = .;
+  .data_nosave : { *(.data.nosave) }
+  . = ALIGN(4096);
+  __nosave_end = .;
+
+  . = ALIGN(32);
+  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+
+  _edata =  .;			/* End of data section */
+
+  /* will be freed after init */
+  . = ALIGN(4096);		/* Init code and data */
+  __init_begin = .;
+  .init.text : {
+	_sinittext = .;
+	*(.init.text)
+	_einittext = .;
+  }
+  .init.data : { *(.init.data) }
+  . = ALIGN(16);
+  __setup_start = .;
+  .init.setup : { *(.init.setup) }
+  __setup_end = .;
+
+  .early_initcall.init : {
+  __earlyinitcall_start = .;
+	*(.initcall.early1.init)
+  }
+  __earlyinitcall_end = .;
+
+  __initcall_start = .;
+  .initcall.init : {
+	*(.initcall1.init)
+	*(.initcall2.init)
+	*(.initcall3.init)
+	*(.initcall4.init)
+	*(.initcall5.init)
+	*(.initcall6.init)
+	*(.initcall7.init)
+  }
+  __initcall_end = .;
+
+  __con_initcall_start = .;
+  .con_initcall.init : { *(.con_initcall.init) }
+  __con_initcall_end = .;
+  SECURITY_INIT
+  . = ALIGN(4096);
+  __initramfs_start = .;
+  .init.ramfs : { *(.init.ramfs) }
+  __initramfs_end = .;
+  . = ALIGN(32);
+  __per_cpu_start = .;
+  .data.percpu  : { *(.data.percpu) }
+  __per_cpu_end = .;
+  . = ALIGN(4096);
+  __init_end = .;
+  /* freed after init ends here */
+
+  __bss_start = .;		/* BSS */
+  .sbss      : {
+    *(.sbss)
+    *(.scommon)
+  }
+  .bss : {
+    *(.bss)
+    *(COMMON)
+  }
+  __bss_stop = .;
+
+  _end = . ;
+
+  /* Sections to be discarded */
+  /DISCARD/ : {
+        *(.exit.text)
+        *(.exit.data)
+        *(.exitcall.exit)
+
+	/* ABI crap starts here */
+	*(.comment)
+	*(.MIPS.options)
+	*(.note)
+	*(.options)
+	*(.pdr)
+	*(.reginfo)
+	*(.mdebug*)
+  }
+
+  /* This is the MIPS specific mdebug section.  */
+  .mdebug : { *(.mdebug) }
+  /* These are needed for ELF backends which have not yet been
+     converted to the new style linker.  */
+  .stab 0 : { *(.stab) }
+  .stabstr 0 : { *(.stabstr) }
+  /* DWARF debug sections.
+     Symbols in the .debug DWARF section are relative to the beginning of the
+     section so we begin .debug at 0.  It's not clear yet what needs to happen
+     for the others.   */
+  .debug          0 : { *(.debug) }
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+  .line           0 : { *(.line) }
+  /* These must appear regardless of  .  */
+  .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
+  .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
+  .comment : { *(.comment) }
+  .note : { *(.note) }
+}
diff --git a/arch/mips/lasat/Makefile b/arch/mips/lasat/Makefile
new file mode 100644
index 0000000..0d5aec4
--- /dev/null
+++ b/arch/mips/lasat/Makefile
@@ -0,0 +1,14 @@
+#
+# Makefile for the LASAT specific kernel interface routines under Linux.
+#
+
+obj-y	 			+= reset.o setup.o prom.o lasat_board.o \
+				   at93c.o interrupt.o lasatIRQ.o
+
+obj-$(CONFIG_LASAT_SYSCTL)	+= sysctl.o
+obj-$(CONFIG_DS1603)		+= ds1603.o
+obj-$(CONFIG_PICVUE)		+= picvue.o
+obj-$(CONFIG_PICVUE_PROC)	+= picvue_proc.o
+
+clean:
+	make -C image clean
diff --git a/arch/mips/lasat/at93c.c b/arch/mips/lasat/at93c.c
new file mode 100644
index 0000000..f6add04
--- /dev/null
+++ b/arch/mips/lasat/at93c.c
@@ -0,0 +1,148 @@
+/* 
+ * Atmel AT93C46 serial eeprom driver
+ *
+ * Brian Murphy <brian.murphy@eicon.com> 
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <asm/lasat/lasat.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include "at93c.h"
+
+#define AT93C_ADDR_SHIFT	7
+#define AT93C_ADDR_MAX		((1 << AT93C_ADDR_SHIFT) - 1)
+#define AT93C_RCMD		(0x6 << AT93C_ADDR_SHIFT)
+#define AT93C_WCMD		(0x5 << AT93C_ADDR_SHIFT)
+#define AT93C_WENCMD		0x260
+#define AT93C_WDSCMD		0x200
+
+struct at93c_defs *at93c;
+
+static void at93c_reg_write(u32 val) 
+{
+	*at93c->reg = val;
+}
+
+static u32 at93c_reg_read(void) 
+{
+	u32 tmp = *at93c->reg;
+	return tmp;
+}
+
+static u32 at93c_datareg_read(void)
+{
+	u32 tmp = *at93c->rdata_reg;
+	return tmp;
+}
+
+static void at93c_cycle_clk(u32 data)
+{
+	at93c_reg_write(data | at93c->clk);
+	lasat_ndelay(250);
+	at93c_reg_write(data & ~at93c->clk);
+	lasat_ndelay(250);
+}
+
+static void at93c_write_databit(u8 bit)
+{
+	u32 data = at93c_reg_read();
+	if (bit)
+		data |= 1 << at93c->wdata_shift;
+	else
+		data &= ~(1 << at93c->wdata_shift);
+
+	at93c_reg_write(data);
+	lasat_ndelay(100);
+	at93c_cycle_clk(data);
+}
+
+static unsigned int at93c_read_databit(void)
+{
+	u32 data;
+
+	at93c_cycle_clk(at93c_reg_read());
+	data = (at93c_datareg_read() >> at93c->rdata_shift) & 1;
+	return data;
+}
+
+static u8 at93c_read_byte(void)
+{
+	int i;
+	u8 data = 0;
+
+	for (i = 0; i<=7; i++) {
+		data <<= 1;
+		data |= at93c_read_databit();
+	}
+	return data;
+}
+
+static void at93c_write_bits(u32 data, int size)
+{               
+	int i;
+	int shift = size - 1;
+	u32 mask = (1 << shift);
+
+	for (i = 0; i < size; i++) {
+		at93c_write_databit((data & mask) >> shift);
+		data <<= 1;
+	}
+}       
+
+static void at93c_init_op(void)
+{
+	at93c_reg_write((at93c_reg_read() | at93c->cs) & ~at93c->clk & ~(1 << at93c->rdata_shift));
+	lasat_ndelay(50);
+}
+
+static void at93c_end_op(void)
+{
+	at93c_reg_write(at93c_reg_read() & ~at93c->cs);
+	lasat_ndelay(250);
+}
+
+static void at93c_wait(void) 
+{ 
+	at93c_init_op();
+	while (!at93c_read_databit())
+		;
+	at93c_end_op();
+};
+
+static void at93c_disable_wp(void)
+{
+	at93c_init_op();
+	at93c_write_bits(AT93C_WENCMD, 10);
+	at93c_end_op();
+}
+
+static void at93c_enable_wp(void)
+{
+	at93c_init_op();
+	at93c_write_bits(AT93C_WDSCMD, 10);
+	at93c_end_op();
+}
+
+u8 at93c_read(u8 addr)
+{
+	u8 byte;
+	at93c_init_op();
+	at93c_write_bits((addr & AT93C_ADDR_MAX)|AT93C_RCMD, 10);
+	byte = at93c_read_byte();
+	at93c_end_op();
+	return byte;
+}
+
+void at93c_write(u8 addr, u8 data)
+{
+	at93c_disable_wp();
+	at93c_init_op();
+	at93c_write_bits((addr & AT93C_ADDR_MAX)|AT93C_WCMD, 10);
+	at93c_write_bits(data, 8);
+	at93c_end_op();
+	at93c_wait();
+	at93c_enable_wp();
+}
diff --git a/arch/mips/lasat/at93c.h b/arch/mips/lasat/at93c.h
new file mode 100644
index 0000000..a912ac2
--- /dev/null
+++ b/arch/mips/lasat/at93c.h
@@ -0,0 +1,18 @@
+/* 
+ * Atmel AT93C46 serial eeprom driver
+ *
+ * Brian Murphy <brian.murphy@eicon.com> 
+ *
+ */
+
+extern struct at93c_defs {
+	volatile u32 *reg;
+	volatile u32 *rdata_reg;
+	int rdata_shift;
+	int wdata_shift;
+	u32 cs;
+	u32 clk;
+} *at93c;
+
+u8 at93c_read(u8 addr);
+void at93c_write(u8 addr, u8 data);
diff --git a/arch/mips/lasat/ds1603.c b/arch/mips/lasat/ds1603.c
new file mode 100644
index 0000000..7bbf6cf
--- /dev/null
+++ b/arch/mips/lasat/ds1603.c
@@ -0,0 +1,174 @@
+/* 
+ * Dallas Semiconductors 1603 RTC driver 
+ *
+ * Brian Murphy <brian@murphy.dk> 
+ *
+ */
+#include <linux/kernel.h>
+#include <asm/lasat/lasat.h>
+#include <linux/delay.h>
+#include <asm/lasat/ds1603.h>
+
+#include "ds1603.h"
+
+#define READ_TIME_CMD 0x81
+#define SET_TIME_CMD 0x80
+#define TRIMMER_SET_CMD 0xC0
+#define TRIMMER_VALUE_MASK 0x38
+#define TRIMMER_SHIFT 3
+
+struct ds_defs *ds1603 = NULL;
+
+/* HW specific register functions */
+static void rtc_reg_write(unsigned long val) 
+{
+	*ds1603->reg = val;
+}
+
+static unsigned long rtc_reg_read(void) 
+{
+	unsigned long tmp = *ds1603->reg;
+	return tmp;
+}
+
+static unsigned long rtc_datareg_read(void)
+{
+	unsigned long tmp = *ds1603->data_reg;
+	return tmp;
+}
+
+static void rtc_nrst_high(void)
+{
+	rtc_reg_write(rtc_reg_read() | ds1603->rst);
+}
+
+static void rtc_nrst_low(void)
+{
+	rtc_reg_write(rtc_reg_read() & ~ds1603->rst);
+}
+
+static void rtc_cycle_clock(unsigned long data)
+{
+	data |= ds1603->clk;
+	rtc_reg_write(data);
+	lasat_ndelay(250);
+	if (ds1603->data_reversed)
+		data &= ~ds1603->data;
+	else
+		data |= ds1603->data;
+	data &= ~ds1603->clk;
+	rtc_reg_write(data);
+	lasat_ndelay(250 + ds1603->huge_delay);
+}
+
+static void rtc_write_databit(unsigned int bit)
+{
+	unsigned long data = rtc_reg_read();
+	if (ds1603->data_reversed)
+		bit = !bit;
+	if (bit)
+		data |= ds1603->data;
+	else
+		data &= ~ds1603->data;
+
+	rtc_reg_write(data);
+	lasat_ndelay(50 + ds1603->huge_delay);
+	rtc_cycle_clock(data);
+}
+
+static unsigned int rtc_read_databit(void)
+{
+	unsigned int data;
+
+	data = (rtc_datareg_read() & (1 << ds1603->data_read_shift)) 
+		>> ds1603->data_read_shift;
+	rtc_cycle_clock(rtc_reg_read());
+	return data;
+}
+
+static void rtc_write_byte(unsigned int byte)
+{
+	int i;
+
+	for (i = 0; i<=7; i++) {
+		rtc_write_databit(byte & 1L);
+		byte >>= 1;
+	}
+}
+
+static void rtc_write_word(unsigned long word)
+{
+	int i;
+
+	for (i = 0; i<=31; i++) {
+		rtc_write_databit(word & 1L);
+		word >>= 1;
+	}
+}
+
+static unsigned long rtc_read_word(void)
+{
+	int i;
+	unsigned long word = 0;
+	unsigned long shift = 0;
+
+	for (i = 0; i<=31; i++) {
+		word |= rtc_read_databit() << shift;
+		shift++;
+	}
+	return word;
+}
+
+static void rtc_init_op(void)
+{
+	rtc_nrst_high();
+
+	rtc_reg_write(rtc_reg_read() & ~ds1603->clk);
+
+	lasat_ndelay(50);
+}
+
+static void rtc_end_op(void)
+{
+	rtc_nrst_low();
+	lasat_ndelay(1000);
+}
+
+/* interface */
+unsigned long ds1603_read(void)
+{
+	unsigned long word;
+	rtc_init_op();
+	rtc_write_byte(READ_TIME_CMD);
+	word = rtc_read_word();
+	rtc_end_op();
+	return word;
+}
+
+int ds1603_set(unsigned long time)
+{
+	rtc_init_op();
+	rtc_write_byte(SET_TIME_CMD);
+	rtc_write_word(time);
+	rtc_end_op();
+
+	return 0;
+}
+
+void ds1603_set_trimmer(unsigned int trimval)
+{
+	rtc_init_op();
+	rtc_write_byte(((trimval << TRIMMER_SHIFT) & TRIMMER_VALUE_MASK)
+			| (TRIMMER_SET_CMD));
+	rtc_end_op();
+}
+
+void ds1603_disable(void)
+{
+	ds1603_set_trimmer(TRIMMER_DISABLE_RTC);
+}
+
+void ds1603_enable(void)
+{
+	ds1603_set_trimmer(TRIMMER_DEFAULT);
+}
diff --git a/arch/mips/lasat/ds1603.h b/arch/mips/lasat/ds1603.h
new file mode 100644
index 0000000..55f3b04
--- /dev/null
+++ b/arch/mips/lasat/ds1603.h
@@ -0,0 +1,33 @@
+/* 
+ * Dallas Semiconductors 1603 RTC driver 
+ *
+ * Brian Murphy <brian@murphy.dk> 
+ *
+ */
+#ifndef __DS1603_H
+#define __DS1603_H
+
+struct ds_defs {
+	volatile u32 *reg;
+	volatile u32 *data_reg;
+	u32 rst;
+	u32 clk;
+	u32 data;
+	u32 data_read_shift;
+	char data_reversed;
+	u32 huge_delay;
+};
+
+extern struct ds_defs *ds1603;
+
+unsigned long ds1603_read(void);
+int ds1603_set(unsigned long);
+void ds1603_set_trimmer(unsigned int);
+void ds1603_enable(void);
+void ds1603_disable(void);
+void ds1603_init(struct ds_defs *);
+
+#define TRIMMER_DEFAULT	3
+#define TRIMMER_DISABLE_RTC 0
+
+#endif
diff --git a/arch/mips/lasat/image/Makefile b/arch/mips/lasat/image/Makefile
new file mode 100644
index 0000000..18b6430
--- /dev/null
+++ b/arch/mips/lasat/image/Makefile
@@ -0,0 +1,53 @@
+#
+# MAKEFILE FOR THE MIPS LINUX BOOTLOADER AND ROM DEBUGGER
+#
+# i-data Networks
+#
+# Author: Thomas Horsten <thh@i-data.com>
+#
+
+ifndef Version
+ Version = "$(USER)-test"
+endif
+
+MKLASATIMG = mklasatimg
+MKLASATIMG_ARCH = mq2,mqpro,sp100,sp200
+KERNEL_IMAGE = $(TOPDIR)/vmlinux
+KERNEL_START = $(shell $(NM) $(KERNEL_IMAGE) | grep " _text" | cut -f1 -d\ )
+KERNEL_ENTRY = $(shell $(NM) $(KERNEL_IMAGE) | grep kernel_entry | cut -f1 -d\ )
+
+LDSCRIPT= -L$(obj) -Tromscript.normal
+
+HEAD_DEFINES := -D_kernel_start=0x$(KERNEL_START) \
+		-D_kernel_entry=0x$(KERNEL_ENTRY) \
+		-D VERSION="\"$(Version)\"" \
+		-D TIMESTAMP=$(shell date +%s) 
+
+$(obj)/head.o: $(obj)/head.S $(KERNEL_IMAGE)
+	$(CC) -fno-pic $(HEAD_DEFINES) -I$(TOPDIR)/include -c -o $@ $<
+
+OBJECTS = head.o kImage.o
+
+rom.sw:	$(obj)/rom.sw
+
+$(obj)/rom.sw:	$(obj)/rom.bin
+	$(MKLASATIMG) -o $@ -k $^ -m $(MKLASATIMG_ARCH)
+
+$(obj)/rom.bin: $(obj)/rom
+	$(OBJCOPY) -O binary -S $^ $@
+
+# Rule to make the bootloader
+$(obj)/rom: $(addprefix $(obj)/,$(OBJECTS))
+	$(LD) $(LDFLAGS) $(LDSCRIPT) -o $@ $^
+
+$(obj)/%.o: $(obj)/%.gz
+	$(LD) -r -o $@ -b binary $<
+
+$(obj)/%.gz: $(obj)/%.bin
+	gzip -cf -9 $< > $@
+
+$(obj)/kImage.bin: $(KERNEL_IMAGE)
+	$(OBJCOPY) -O binary -S $^ $@
+
+clean:
+	rm -f rom rom.bin rom.sw kImage.bin kImage.o
diff --git a/arch/mips/lasat/image/head.S b/arch/mips/lasat/image/head.S
new file mode 100644
index 0000000..426bd7d
--- /dev/null
+++ b/arch/mips/lasat/image/head.S
@@ -0,0 +1,31 @@
+#include <asm/lasat/head.h>
+
+	.text
+	.section .text.start, "ax"
+	.set noreorder
+	.set mips3
+
+	/* Magic words identifying a software image */
+	.word	LASAT_K_MAGIC0_VAL
+	.word 	LASAT_K_MAGIC1_VAL
+
+	/* Image header version */
+	.word	0x00000002
+
+	/* image start and size */
+	.word	_image_start
+	.word	_image_size
+
+	/* start of kernel and entrypoint in uncompressed image */
+	.word	_kernel_start
+	.word	_kernel_entry
+
+	/* Here we have room for future flags */
+
+	.org	0x40
+reldate:
+	.word	TIMESTAMP
+
+	.org	0x50
+release:	
+	.string VERSION
diff --git a/arch/mips/lasat/image/romscript.normal b/arch/mips/lasat/image/romscript.normal
new file mode 100644
index 0000000..ca22336
--- /dev/null
+++ b/arch/mips/lasat/image/romscript.normal
@@ -0,0 +1,22 @@
+OUTPUT_ARCH(mips)
+
+SECTIONS
+{
+  .text :
+  {
+    *(.text.start)
+  }
+
+  /* Data in ROM */
+
+  .data ALIGN(0x10) :
+  {
+    *(.data)
+  }
+  _image_start = ADDR(.data);
+  _image_size = SIZEOF(.data);
+
+  .other : {
+  	*(.*)
+  }
+}
diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c
new file mode 100644
index 0000000..1148a2d
--- /dev/null
+++ b/arch/mips/lasat/interrupt.c
@@ -0,0 +1,160 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Routines for generic manipulation of the interrupts found on the 
+ * Lasat boards.
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/lasat/lasatint.h>
+#include <asm/gdb-stub.h>
+
+static volatile int *lasat_int_status = NULL;
+static volatile int *lasat_int_mask = NULL;
+static volatile int lasat_int_mask_shift;
+
+extern asmlinkage void lasatIRQ(void);
+
+void disable_lasat_irq(unsigned int irq_nr)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	*lasat_int_mask &= ~(1 << irq_nr) << lasat_int_mask_shift;
+	local_irq_restore(flags);
+}
+
+void enable_lasat_irq(unsigned int irq_nr)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	*lasat_int_mask |= (1 << irq_nr) << lasat_int_mask_shift;
+	local_irq_restore(flags);
+}
+
+static unsigned int startup_lasat_irq(unsigned int irq)
+{
+	enable_lasat_irq(irq);
+
+	return 0; /* never anything pending */
+}
+
+#define shutdown_lasat_irq	disable_lasat_irq
+
+#define mask_and_ack_lasat_irq disable_lasat_irq
+
+static void end_lasat_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_lasat_irq(irq);
+}
+
+static struct hw_interrupt_type lasat_irq_type = {
+	"Lasat",
+	startup_lasat_irq,
+	shutdown_lasat_irq,
+	enable_lasat_irq,
+	disable_lasat_irq,
+	mask_and_ack_lasat_irq,
+	end_lasat_irq,
+	NULL
+};
+
+static inline int ls1bit32(unsigned int x)
+{
+	int b = 31, s;
+
+	s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s;
+	s =  8; if (x <<  8 == 0) s = 0; b -= s; x <<= s;
+	s =  4; if (x <<  4 == 0) s = 0; b -= s; x <<= s;
+	s =  2; if (x <<  2 == 0) s = 0; b -= s; x <<= s;
+	s =  1; if (x <<  1 == 0) s = 0; b -= s;
+
+	return b;
+}
+
+static unsigned long (* get_int_status)(void);
+
+static unsigned long get_int_status_100(void)
+{
+	return *lasat_int_status & *lasat_int_mask;
+}
+
+static unsigned long get_int_status_200(void) 
+{
+	unsigned long int_status;
+
+	int_status = *lasat_int_status;
+	int_status &= (int_status >> LASATINT_MASK_SHIFT_200) & 0xffff;
+	return int_status;
+}
+
+void lasat_hw0_irqdispatch(struct pt_regs *regs)
+{
+	unsigned long int_status;
+	int irq;
+
+	int_status = get_int_status();
+
+	/* if int_status == 0, then the interrupt has already been cleared */
+	if (int_status) {
+		irq = ls1bit32(int_status);
+
+		do_IRQ(irq, regs);
+	}
+}
+
+void __init arch_init_irq(void)
+{
+	int i;
+
+	switch (mips_machtype) {
+	case MACH_LASAT_100:
+		lasat_int_status = (void *)LASAT_INT_STATUS_REG_100;
+		lasat_int_mask = (void *)LASAT_INT_MASK_REG_100;
+		lasat_int_mask_shift = LASATINT_MASK_SHIFT_100;
+		get_int_status = get_int_status_100;
+		*lasat_int_mask = 0;
+		break;
+	case MACH_LASAT_200:
+		lasat_int_status = (void *)LASAT_INT_STATUS_REG_200;
+		lasat_int_mask = (void *)LASAT_INT_MASK_REG_200;
+		lasat_int_mask_shift = LASATINT_MASK_SHIFT_200;
+		get_int_status = get_int_status_200;
+		*lasat_int_mask &= 0xffff;
+		break;
+	default:
+		panic("arch_init_irq: mips_machtype incorrect");
+	}
+
+	/* Now safe to set the exception vector. */
+	set_except_vector(0, lasatIRQ);
+
+	for (i = 0; i <= LASATINT_END; i++) {
+		irq_desc[i].status	= IRQ_DISABLED;
+		irq_desc[i].action	= 0;
+		irq_desc[i].depth	= 1;
+		irq_desc[i].handler	= &lasat_irq_type;
+	}
+}
diff --git a/arch/mips/lasat/lasatIRQ.S b/arch/mips/lasat/lasatIRQ.S
new file mode 100644
index 0000000..2a2b0d0
--- /dev/null
+++ b/arch/mips/lasat/lasatIRQ.S
@@ -0,0 +1,69 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999, 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Interrupt exception dispatch code.
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+	.text
+	.set	noreorder
+	.align	5
+	NESTED(lasatIRQ, PT_SIZE, sp)
+	.set	noat
+	SAVE_ALL
+	CLI
+	.set	at
+	.set	noreorder
+
+	mfc0	s0, CP0_CAUSE		# get irq mask
+
+	/* First we check for r4k counter/timer IRQ. */
+	andi	a0, s0, CAUSEF_IP7
+	beq	a0, zero, 1f
+	 andi	a0, s0, CAUSEF_IP2	# delay slot, check hw0 interrupt
+
+	/* Wheee, a timer interrupt. */
+	li	a0, 7
+	jal	ll_timer_interrupt
+	 move	a1, sp
+
+	j	ret_from_irq
+	 nop
+
+1:
+	/* Wheee, combined hardware level zero interrupt. */
+	jal	lasat_hw0_irqdispatch
+	 move	a0, sp			# delay slot
+
+	j	ret_from_irq
+	 nop				# delay slot
+
+1:
+	/*
+	 * Here by mistake?  This is possible, what can happen is that by the
+	 * time we take the exception the IRQ pin goes low, so just leave if
+	 * this is the case.
+	 */
+	move	a1,s0
+	mfc0	a1, CP0_EPC
+
+	j	ret_from_irq
+	 nop
+	END(lasatIRQ)
diff --git a/arch/mips/lasat/lasat_board.c b/arch/mips/lasat/lasat_board.c
new file mode 100644
index 0000000..8c784bc
--- /dev/null
+++ b/arch/mips/lasat/lasat_board.c
@@ -0,0 +1,277 @@
+/*
+ * Thomas Horsten <thh@lasat.com>
+ * Copyright (C) 2000 LASAT Networks A/S.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Routines specific to the LASAT boards
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/crc32.h>
+#include <asm/lasat/lasat.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <asm/bootinfo.h>
+#include <asm/addrspace.h>
+#include "at93c.h"
+/* New model description table */
+#include "lasat_models.h"
+
+#define EEPROM_CRC(data, len) (~0 ^ crc32(~0, data, len))
+
+struct lasat_info lasat_board_info;
+
+void update_bcastaddr(void);
+
+int EEPROMRead(unsigned int pos, unsigned char *data, int len)
+{
+	int i;
+
+	for (i=0; i<len; i++)
+		*data++ = at93c_read(pos++);
+
+	return 0;
+}
+int EEPROMWrite(unsigned int pos, unsigned char *data, int len)
+{
+	int i;
+
+	for (i=0; i<len; i++)
+		at93c_write(pos++, *data++);
+
+	return 0;
+}
+
+static void init_flash_sizes(void)
+{
+	int i;
+	unsigned long *lb = lasat_board_info.li_flashpart_base;
+	unsigned long *ls = lasat_board_info.li_flashpart_size;
+
+	ls[LASAT_MTD_BOOTLOADER] = 0x40000;
+	ls[LASAT_MTD_SERVICE] = 0xC0000;
+	ls[LASAT_MTD_NORMAL] = 0x100000;
+
+	if (mips_machtype == MACH_LASAT_100) {
+		lasat_board_info.li_flash_base = 0x1e000000;
+		
+		lb[LASAT_MTD_BOOTLOADER] = 0x1e400000;
+
+		if (lasat_board_info.li_flash_size > 0x200000) {
+			ls[LASAT_MTD_CONFIG] = 0x100000;
+			ls[LASAT_MTD_FS] = 0x500000;
+		}
+	} else {
+		lasat_board_info.li_flash_base = 0x10000000;
+
+		if (lasat_board_info.li_flash_size < 0x1000000) {
+			lb[LASAT_MTD_BOOTLOADER] = 0x10000000;
+			ls[LASAT_MTD_CONFIG] = 0x100000;
+			if (lasat_board_info.li_flash_size >= 0x400000) {
+				ls[LASAT_MTD_FS] = lasat_board_info.li_flash_size - 0x300000;
+			}
+		}
+	}
+
+	for (i = 1; i < LASAT_MTD_LAST; i++)
+		lb[i] = lb[i-1] + ls[i-1];
+}
+
+int lasat_init_board_info(void)
+{
+	int c;
+	unsigned long crc;
+	unsigned long cfg0, cfg1;
+	const product_info_t   *ppi;
+	int i_n_base_models = N_BASE_MODELS;
+	const char * const * i_txt_base_models = txt_base_models;
+	int i_n_prids = N_PRIDS;
+
+	memset(&lasat_board_info, 0, sizeof(lasat_board_info));
+
+	/* First read the EEPROM info */
+	EEPROMRead(0, (unsigned char *)&lasat_board_info.li_eeprom_info, 
+		   sizeof(struct lasat_eeprom_struct));
+
+	/* Check the CRC */
+	crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info),
+		    sizeof(struct lasat_eeprom_struct) - 4);
+
+	if (crc != lasat_board_info.li_eeprom_info.crc32) {
+		prom_printf("WARNING...\nWARNING...\nEEPROM CRC does not match calculated, attempting to soldier on...\n");
+	}
+
+	if (lasat_board_info.li_eeprom_info.version != LASAT_EEPROM_VERSION)
+	{
+		prom_printf("WARNING...\nWARNING...\nEEPROM version %d, wanted version %d, attempting to soldier on...\n",
+		       (unsigned int)lasat_board_info.li_eeprom_info.version,
+		       LASAT_EEPROM_VERSION);
+	}
+
+	cfg0 = lasat_board_info.li_eeprom_info.cfg[0];
+	cfg1 = lasat_board_info.li_eeprom_info.cfg[1];
+
+	if ( LASAT_W0_DSCTYPE(cfg0) != 1) {
+		prom_printf("WARNING...\nWARNING...\nInvalid configuration read from EEPROM, attempting to soldier on...");
+	}
+	/* We have a valid configuration */
+
+	switch (LASAT_W0_SDRAMBANKSZ(cfg0)) {
+	case 0:
+		lasat_board_info.li_memsize = 0x0800000;
+		break;
+	case 1:
+		lasat_board_info.li_memsize = 0x1000000;
+		break;
+	case 2:
+		lasat_board_info.li_memsize = 0x2000000;
+		break;
+	case 3:
+		lasat_board_info.li_memsize = 0x4000000;
+		break;
+	case 4:
+		lasat_board_info.li_memsize = 0x8000000;
+		break;
+	default:
+		lasat_board_info.li_memsize = 0;
+	}
+
+	switch (LASAT_W0_SDRAMBANKS(cfg0)) {
+	case 0:
+		break;
+	case 1:
+		lasat_board_info.li_memsize *= 2;
+		break;
+	default:
+		break;
+	}
+
+	switch (LASAT_W0_BUSSPEED(cfg0)) {
+	case 0x0:
+		lasat_board_info.li_bus_hz = 60000000;
+		break;
+	case 0x1:
+		lasat_board_info.li_bus_hz = 66000000;
+		break;
+	case 0x2:
+		lasat_board_info.li_bus_hz = 66666667;
+		break;
+	case 0x3:
+		lasat_board_info.li_bus_hz = 80000000;
+		break;
+	case 0x4:
+		lasat_board_info.li_bus_hz = 83333333;
+		break;
+	case 0x5:
+		lasat_board_info.li_bus_hz = 100000000;
+		break;
+	}
+
+	switch (LASAT_W0_CPUCLK(cfg0)) {
+	case 0x0:
+		lasat_board_info.li_cpu_hz =
+			lasat_board_info.li_bus_hz;
+		break;
+	case 0x1:
+		lasat_board_info.li_cpu_hz =
+			lasat_board_info.li_bus_hz +
+			(lasat_board_info.li_bus_hz >> 1);	
+		break;
+	case 0x2:
+		lasat_board_info.li_cpu_hz =
+			lasat_board_info.li_bus_hz +
+			lasat_board_info.li_bus_hz;
+		break;
+	case 0x3:
+		lasat_board_info.li_cpu_hz =
+			lasat_board_info.li_bus_hz +
+			lasat_board_info.li_bus_hz +
+			(lasat_board_info.li_bus_hz >> 1);
+		break;
+	case 0x4:
+		lasat_board_info.li_cpu_hz =
+			lasat_board_info.li_bus_hz +
+			lasat_board_info.li_bus_hz +
+			lasat_board_info.li_bus_hz;
+		break;
+	}
+
+	/* Flash size */
+	switch (LASAT_W1_FLASHSIZE(cfg1)) {
+	case 0:
+		lasat_board_info.li_flash_size = 0x200000;
+		break;
+	case 1:
+		lasat_board_info.li_flash_size = 0x400000;
+		break;
+	case 2:
+		lasat_board_info.li_flash_size = 0x800000;
+		break;
+	case 3:
+		lasat_board_info.li_flash_size = 0x1000000;
+		break;
+	case 4:
+		lasat_board_info.li_flash_size = 0x2000000;
+		break;
+	}
+
+	init_flash_sizes();
+
+	lasat_board_info.li_bmid = LASAT_W0_BMID(cfg0);
+	lasat_board_info.li_prid = lasat_board_info.li_eeprom_info.prid;
+	if (lasat_board_info.li_prid == 0xffff || lasat_board_info.li_prid == 0)
+		lasat_board_info.li_prid = lasat_board_info.li_bmid;
+
+	/* Base model stuff */
+	if (lasat_board_info.li_bmid > i_n_base_models)
+		lasat_board_info.li_bmid = i_n_base_models;
+	strcpy(lasat_board_info.li_bmstr, i_txt_base_models[lasat_board_info.li_bmid]);
+
+	/* Product ID dependent values */
+	c = lasat_board_info.li_prid;
+	if (c >= i_n_prids) {
+		strcpy(lasat_board_info.li_namestr, "Unknown Model");
+		strcpy(lasat_board_info.li_typestr, "Unknown Type");
+	} else {
+		ppi = &vendor_info_table[0].vi_product_info[c];
+		strcpy(lasat_board_info.li_namestr, ppi->pi_name);
+		if (ppi->pi_type)
+			strcpy(lasat_board_info.li_typestr, ppi->pi_type);
+		else
+			sprintf(lasat_board_info.li_typestr, "%d",10*c);
+	}
+
+#if defined(CONFIG_INET) && defined(CONFIG_SYSCTL)
+	update_bcastaddr();
+#endif
+
+	return 0;
+}
+
+void lasat_write_eeprom_info(void)
+{
+	unsigned long crc;
+
+	/* Generate the CRC */
+	crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info),
+		    sizeof(struct lasat_eeprom_struct) - 4);
+	lasat_board_info.li_eeprom_info.crc32 = crc;
+
+	/* Write the EEPROM info */
+	EEPROMWrite(0, (unsigned char *)&lasat_board_info.li_eeprom_info, 
+		    sizeof(struct lasat_eeprom_struct));
+}
+
diff --git a/arch/mips/lasat/lasat_models.h b/arch/mips/lasat/lasat_models.h
new file mode 100644
index 0000000..ae0c5d0
--- /dev/null
+++ b/arch/mips/lasat/lasat_models.h
@@ -0,0 +1,63 @@
+/*
+ * Model description tables
+ */
+
+typedef struct product_info_t {
+	const char     *pi_name;
+	const char     *pi_type;
+} product_info_t;
+
+typedef struct vendor_info_t {
+	const char     *vi_name;
+	const product_info_t *vi_product_info;
+} vendor_info_t;
+
+/*
+ * Base models
+ */
+static const char * const txt_base_models[] = {
+  "MQ 2", "MQ Pro", "SP 25", "SP 50", "SP 100", "SP 5000", "SP 7000", "SP 1000", "Unknown"
+};
+#define N_BASE_MODELS (sizeof(txt_base_models)/sizeof(char*)-1)
+
+/*
+ * Eicon Networks
+ */
+static const char txt_en_mq[] = "Masquerade";
+static const char txt_en_sp[] = "Safepipe";
+
+static const product_info_t product_info_eicon[] = {
+  { txt_en_mq, "II"   }, /*  0 */
+  { txt_en_mq, "Pro"  }, /*  1 */
+  { txt_en_sp, "25"   }, /*  2 */
+  { txt_en_sp, "50"   }, /*  3 */
+  { txt_en_sp, "100"  }, /*  4 */
+  { txt_en_sp, "5000" }, /*  5 */
+  { txt_en_sp, "7000" }, /*  6 */
+  { txt_en_sp, "30"   }, /*  7 */
+  { txt_en_sp, "5100" }, /*  8 */
+  { txt_en_sp, "7100" }, /*  9 */
+  { txt_en_sp, "1110" }, /* 10 */
+  { txt_en_sp, "3020" }, /* 11 */
+  { txt_en_sp, "3030" }, /* 12 */
+  { txt_en_sp, "5020" }, /* 13 */
+  { txt_en_sp, "5030" }, /* 14 */
+  { txt_en_sp, "1120" }, /* 15 */
+  { txt_en_sp, "1130" }, /* 16 */
+  { txt_en_sp, "6010" }, /* 17 */
+  { txt_en_sp, "6110" }, /* 18 */
+  { txt_en_sp, "6210" }, /* 19 */
+  { txt_en_sp, "1020" }, /* 20 */
+  { txt_en_sp, "1040" }, /* 21 */
+  { txt_en_sp, "1050" }, /* 22 */
+  { txt_en_sp, "1060" }, /* 23 */
+};
+#define N_PRIDS (sizeof(product_info_eicon)/sizeof(product_info_t))
+
+/*
+ * The vendor table
+ */
+static vendor_info_t const vendor_info_table[] = {
+  { "Eicon Networks",	product_info_eicon   },
+};
+#define N_VENDORS (sizeof(vendor_info_table)/sizeof(vendor_info_t))
diff --git a/arch/mips/lasat/picvue.c b/arch/mips/lasat/picvue.c
new file mode 100644
index 0000000..5637cd1
--- /dev/null
+++ b/arch/mips/lasat/picvue.c
@@ -0,0 +1,240 @@
+/* 
+ * Picvue PVC160206 display driver
+ *
+ * Brian Murphy <brian@murphy.dk> 
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <asm/bootinfo.h>
+#include <asm/lasat/lasat.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+
+#include "picvue.h"
+
+#define PVC_BUSY		0x80
+#define PVC_NLINES		2
+#define PVC_DISPMEM		80
+#define PVC_LINELEN		PVC_DISPMEM / PVC_NLINES
+
+struct pvc_defs *picvue = NULL;
+
+DECLARE_MUTEX(pvc_sem);
+
+static void pvc_reg_write(u32 val) 
+{
+	*picvue->reg = val;
+}
+
+static u32 pvc_reg_read(void) 
+{
+	u32 tmp = *picvue->reg;
+	return tmp;
+}
+
+static void pvc_write_byte(u32 data, u8 byte)
+{
+	data |= picvue->e;
+	pvc_reg_write(data);
+	data &= ~picvue->data_mask;
+	data |= byte << picvue->data_shift;
+	pvc_reg_write(data);
+	ndelay(220);
+	pvc_reg_write(data & ~picvue->e);
+	ndelay(220);
+}
+
+static u8 pvc_read_byte(u32 data)
+{
+	u8 byte;
+
+	data |= picvue->e;
+	pvc_reg_write(data);
+	ndelay(220);
+	byte = (pvc_reg_read() & picvue->data_mask) >> picvue->data_shift;
+	data &= ~picvue->e;
+	pvc_reg_write(data);
+	ndelay(220);
+	return byte;
+}
+
+static u8 pvc_read_data(void)
+{
+	u32 data = pvc_reg_read();
+	u8 byte;
+	data |= picvue->rw; 
+	data &= ~picvue->rs;
+	pvc_reg_write(data);
+	ndelay(40);
+	byte = pvc_read_byte(data);
+	data |= picvue->rs; 
+	pvc_reg_write(data);
+	return byte;
+}
+
+#define TIMEOUT 1000
+static int pvc_wait(void)
+{
+	int i = TIMEOUT;
+	int err = 0;
+
+	while ((pvc_read_data() & PVC_BUSY) && i)
+		i--;
+	if (i == 0)
+		err = -ETIME;
+
+	return err;
+}
+
+#define MODE_INST 0
+#define MODE_DATA 1
+static void pvc_write(u8 byte, int mode)
+{
+	u32 data = pvc_reg_read();
+	data &= ~picvue->rw;
+	if (mode == MODE_DATA)
+		data |= picvue->rs;
+	else
+		data &= ~picvue->rs;
+	pvc_reg_write(data);
+	ndelay(40);
+	pvc_write_byte(data, byte);
+	if (mode == MODE_DATA)
+		data &= ~picvue->rs;
+	else
+		data |= picvue->rs;
+	pvc_reg_write(data);
+	pvc_wait();
+}
+
+void pvc_write_string(const unsigned char *str, u8 addr, int line)
+{
+	int i = 0;
+
+	if (line > 0 && (PVC_NLINES > 1))
+		addr += 0x40 * line;
+	pvc_write(0x80 | addr, MODE_INST);
+
+	while (*str != 0 && i < PVC_LINELEN) {
+		pvc_write(*str++, MODE_DATA);
+		i++;
+	}
+}
+
+void pvc_write_string_centered(const unsigned char *str, int line)
+{
+	int len = strlen(str);
+	u8 addr;
+
+	if (len > PVC_VISIBLE_CHARS)
+		addr = 0;
+	else
+		addr = (PVC_VISIBLE_CHARS - strlen(str))/2;
+
+	pvc_write_string(str, addr, line);
+}
+
+void pvc_dump_string(const unsigned char *str)
+{
+	int len = strlen(str);
+
+	pvc_write_string(str, 0, 0);
+	if (len > PVC_VISIBLE_CHARS)
+		pvc_write_string(&str[PVC_VISIBLE_CHARS], 0, 1);
+}
+
+#define BM_SIZE			8
+#define MAX_PROGRAMMABLE_CHARS	8
+int pvc_program_cg(int charnum, u8 bitmap[BM_SIZE])
+{
+	int i;
+	int addr;
+
+	if (charnum > MAX_PROGRAMMABLE_CHARS)
+		return -ENOENT;
+
+	addr = charnum * 8;
+	pvc_write(0x40 | addr, MODE_INST);
+
+	for (i=0; i<BM_SIZE; i++)
+		pvc_write(bitmap[i], MODE_DATA);
+	return 0;
+}
+
+#define FUNC_SET_CMD	0x20
+#define  EIGHT_BYTE	(1 << 4)
+#define  FOUR_BYTE	0
+#define  TWO_LINES	(1 << 3)
+#define  ONE_LINE	0
+#define  LARGE_FONT	(1 << 2)
+#define  SMALL_FONT	0
+static void pvc_funcset(u8 cmd)
+{
+	pvc_write(FUNC_SET_CMD | (cmd & (EIGHT_BYTE|TWO_LINES|LARGE_FONT)), MODE_INST);
+}
+
+#define ENTRYMODE_CMD		0x4
+#define  AUTO_INC		(1 << 1)
+#define  AUTO_DEC		0
+#define  CURSOR_FOLLOWS_DISP	(1 << 0)
+static void pvc_entrymode(u8 cmd)
+{
+	pvc_write(ENTRYMODE_CMD | (cmd & (AUTO_INC|CURSOR_FOLLOWS_DISP)), MODE_INST);
+}
+
+#define DISP_CNT_CMD	0x08
+#define  DISP_OFF	0
+#define  DISP_ON	(1 << 2)
+#define  CUR_ON		(1 << 1)
+#define  CUR_BLINK	(1 << 0)
+void pvc_dispcnt(u8 cmd)
+{
+	pvc_write(DISP_CNT_CMD | (cmd & (DISP_ON|CUR_ON|CUR_BLINK)), MODE_INST);
+}
+
+#define MOVE_CMD	0x10
+#define  DISPLAY	(1 << 3)
+#define  CURSOR		0
+#define  RIGHT		(1 << 2)
+#define  LEFT		0
+void pvc_move(u8 cmd)
+{
+	pvc_write(MOVE_CMD | (cmd & (DISPLAY|RIGHT)), MODE_INST);
+}
+
+#define CLEAR_CMD	0x1
+void pvc_clear(void)
+{
+	pvc_write(CLEAR_CMD, MODE_INST);
+}
+
+#define HOME_CMD	0x2
+void pvc_home(void)
+{
+	pvc_write(HOME_CMD, MODE_INST);
+}
+
+int pvc_init(void)
+{
+	u8 cmd = EIGHT_BYTE;
+
+	if (PVC_NLINES == 2)
+		cmd |= (SMALL_FONT|TWO_LINES);
+	else
+		cmd |= (LARGE_FONT|ONE_LINE);
+	pvc_funcset(cmd);
+	pvc_dispcnt(DISP_ON);
+	pvc_entrymode(AUTO_INC);
+
+	pvc_clear();
+	pvc_write_string_centered("Display", 0);
+	pvc_write_string_centered("Initialized", 1);
+
+	return 0;
+}
+
+module_init(pvc_init);
+MODULE_LICENSE("GPL");
diff --git a/arch/mips/lasat/picvue.h b/arch/mips/lasat/picvue.h
new file mode 100644
index 0000000..74a3903
--- /dev/null
+++ b/arch/mips/lasat/picvue.h
@@ -0,0 +1,48 @@
+/* 
+ * Picvue PVC160206 display driver
+ *
+ * Brian Murphy <brian.murphy@eicon.com> 
+ *
+ */
+#include <asm/semaphore.h>
+
+struct pvc_defs {
+	volatile u32 *reg;
+	u32 data_shift;
+	u32 data_mask;
+	u32 e;
+	u32 rw;
+	u32 rs;
+};
+
+extern struct pvc_defs *picvue;
+
+#define PVC_NLINES		2
+#define PVC_DISPMEM		80
+#define PVC_LINELEN		PVC_DISPMEM / PVC_NLINES
+#define PVC_VISIBLE_CHARS	16
+
+void pvc_write_string(const unsigned char *str, u8 addr, int line);
+void pvc_write_string_centered(const unsigned char *str, int line);
+void pvc_dump_string(const unsigned char *str);
+
+#define BM_SIZE			8
+#define MAX_PROGRAMMABLE_CHARS	8
+int pvc_program_cg(int charnum, u8 bitmap[BM_SIZE]);
+
+void pvc_dispcnt(u8 cmd);
+#define  DISP_OFF	0
+#define  DISP_ON	(1 << 2)
+#define  CUR_ON		(1 << 1)
+#define  CUR_BLINK	(1 << 0)
+
+void pvc_move(u8 cmd);
+#define  DISPLAY	(1 << 3)
+#define  CURSOR		0
+#define  RIGHT		(1 << 2)
+#define  LEFT		0
+
+void pvc_clear(void);
+void pvc_home(void);
+
+extern struct semaphore pvc_sem;
diff --git a/arch/mips/lasat/picvue_proc.c b/arch/mips/lasat/picvue_proc.c
new file mode 100644
index 0000000..eaa2b46
--- /dev/null
+++ b/arch/mips/lasat/picvue_proc.c
@@ -0,0 +1,186 @@
+/* 
+ * Picvue PVC160206 display driver
+ *
+ * Brian Murphy <brian.murphy@eicon.com> 
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+
+#include <linux/proc_fs.h>
+#include <linux/interrupt.h>
+
+#include <linux/timer.h>
+
+#include "picvue.h"
+
+static char pvc_lines[PVC_NLINES][PVC_LINELEN+1];
+static int pvc_linedata[PVC_NLINES];
+static struct proc_dir_entry *pvc_display_dir;
+static char *pvc_linename[PVC_NLINES] = {"line1", "line2"};
+#define DISPLAY_DIR_NAME "display"
+static int scroll_dir = 0, scroll_interval = 0;
+
+static struct timer_list timer;
+
+static void pvc_display(unsigned long data) {
+	int i;
+
+	pvc_clear();
+	for (i=0; i<PVC_NLINES; i++)
+		pvc_write_string(pvc_lines[i], 0, i);
+}
+
+static DECLARE_TASKLET(pvc_display_tasklet, &pvc_display, 0);
+
+static int pvc_proc_read_line(char *page, char **start,
+                             off_t off, int count,
+                             int *eof, void *data)
+{
+        char *origpage = page;
+	int lineno = *(int *)data;
+
+	if (lineno < 0 || lineno > PVC_NLINES) {
+		printk("proc_read_line: invalid lineno %d\n", lineno);
+		return 0;
+	}
+
+	down(&pvc_sem);
+        page += sprintf(page, "%s\n", pvc_lines[lineno]);
+	up(&pvc_sem);
+
+        return page - origpage; 
+}
+
+static int pvc_proc_write_line(struct file *file, const char *buffer,            
+                           unsigned long count, void *data)
+{
+        int origcount = count;
+	int lineno = *(int *)data;
+
+	if (lineno < 0 || lineno > PVC_NLINES) {
+		printk("proc_write_line: invalid lineno %d\n", lineno);
+		return origcount;
+	}
+
+	if (count > PVC_LINELEN)
+		count = PVC_LINELEN;
+
+	if (buffer[count-1] == '\n')
+		count--;
+
+	down(&pvc_sem);
+	strncpy(pvc_lines[lineno], buffer, count);
+	pvc_lines[lineno][count] = '\0';
+	up(&pvc_sem);
+
+	tasklet_schedule(&pvc_display_tasklet);
+
+        return origcount;
+}
+
+static int pvc_proc_write_scroll(struct file *file, const char *buffer,
+                           unsigned long count, void *data)
+{
+        int origcount = count;
+	int cmd = simple_strtol(buffer, NULL, 10);
+
+	down(&pvc_sem);
+	if (scroll_interval != 0)
+		del_timer(&timer);
+
+	if (cmd == 0) {
+		scroll_dir = 0;
+		scroll_interval = 0;
+	} else {
+		if (cmd < 0) {
+			scroll_dir = -1;
+			scroll_interval = -cmd;
+		} else {
+			scroll_dir = 1;
+			scroll_interval = cmd;
+		}
+		add_timer(&timer);
+	}
+	up(&pvc_sem);
+
+        return origcount;
+}
+
+static int pvc_proc_read_scroll(char *page, char **start,
+                             off_t off, int count,
+                             int *eof, void *data)
+{
+        char *origpage = page;
+
+	down(&pvc_sem);
+        page += sprintf(page, "%d\n", scroll_dir * scroll_interval);
+	up(&pvc_sem);
+
+        return page - origpage; 
+}
+
+
+void pvc_proc_timerfunc(unsigned long data)
+{
+	if (scroll_dir < 0)
+		pvc_move(DISPLAY|RIGHT);
+	else if (scroll_dir > 0)
+		pvc_move(DISPLAY|LEFT);
+
+	timer.expires = jiffies + scroll_interval;
+	add_timer(&timer);
+}
+
+static void pvc_proc_cleanup(void)
+{
+	int i;
+	for (i=0; i<PVC_NLINES; i++)
+		remove_proc_entry(pvc_linename[i], pvc_display_dir);
+	remove_proc_entry("scroll", pvc_display_dir);
+	remove_proc_entry(DISPLAY_DIR_NAME, NULL);
+
+	del_timer(&timer);
+}
+
+static int __init pvc_proc_init(void)
+{
+	struct proc_dir_entry *proc_entry;
+	int i;
+
+	pvc_display_dir = proc_mkdir(DISPLAY_DIR_NAME, NULL);
+	if (pvc_display_dir == NULL)
+		goto error;
+
+	for (i=0; i<PVC_NLINES; i++) {
+		strcpy(pvc_lines[i], "");
+		pvc_linedata[i] = i;
+	}
+	for (i=0; i<PVC_NLINES; i++) {
+		proc_entry = create_proc_entry(pvc_linename[i], 0644, pvc_display_dir);
+		if (proc_entry == NULL)
+			goto error;
+		proc_entry->read_proc = pvc_proc_read_line;
+		proc_entry->write_proc = pvc_proc_write_line;
+		proc_entry->data = &pvc_linedata[i];
+	}
+	proc_entry = create_proc_entry("scroll", 0644, pvc_display_dir);
+	if (proc_entry == NULL)
+		goto error;
+	proc_entry->write_proc = pvc_proc_write_scroll;
+	proc_entry->read_proc = pvc_proc_read_scroll;
+
+	init_timer(&timer);
+	timer.function = pvc_proc_timerfunc;
+
+	return 0;
+error:
+	pvc_proc_cleanup();
+	return -ENOMEM;
+}
+
+module_init(pvc_proc_init);
+module_exit(pvc_proc_cleanup);
+MODULE_LICENSE("GPL");
diff --git a/arch/mips/lasat/prom.c b/arch/mips/lasat/prom.c
new file mode 100644
index 0000000..ca62881
--- /dev/null
+++ b/arch/mips/lasat/prom.c
@@ -0,0 +1,143 @@
+/*
+ * PROM interface routines.
+ */
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/ioport.h>
+#include <asm/bootinfo.h>
+#include <asm/lasat/lasat.h>
+#include <asm/cpu.h>
+
+#include "at93c.h"
+#include <asm/lasat/eeprom.h>
+#include "prom.h"
+
+#define RESET_VECTOR	0xbfc00000
+#define PROM_JUMP_TABLE_ENTRY(n) (*((u32 *)(RESET_VECTOR + 0x20) + n))
+#define PROM_DISPLAY_ADDR	PROM_JUMP_TABLE_ENTRY(0)
+#define PROM_PUTC_ADDR		PROM_JUMP_TABLE_ENTRY(1)
+#define PROM_MONITOR_ADDR	PROM_JUMP_TABLE_ENTRY(2)
+
+static void null_prom_printf(const char * fmt, ...)
+{
+}
+
+static void null_prom_display(const char *string, int pos, int clear)
+{
+}
+
+static void null_prom_monitor(void)
+{
+}
+
+static void null_prom_putc(char c)
+{
+}
+
+/* these are functions provided by the bootloader */
+static void (* prom_putc)(char c) = null_prom_putc;
+void (* prom_printf)(const char * fmt, ...) = null_prom_printf;
+void (* prom_display)(const char *string, int pos, int clear) = 
+		null_prom_display;
+void (* prom_monitor)(void) = null_prom_monitor;
+
+unsigned int lasat_ndelay_divider;
+
+#define PROM_PRINTFBUF_SIZE 256
+static char prom_printfbuf[PROM_PRINTFBUF_SIZE];
+
+static void real_prom_printf(const char * fmt, ...)
+{
+	va_list ap;
+	int len;
+	char *c = prom_printfbuf;
+	int i;
+
+	va_start(ap, fmt);
+	len = vsnprintf(prom_printfbuf, PROM_PRINTFBUF_SIZE, fmt, ap);
+	va_end(ap);
+
+	/* output overflowed the buffer */
+	if (len < 0 || len > PROM_PRINTFBUF_SIZE)
+		len = PROM_PRINTFBUF_SIZE;
+
+	for (i=0; i < len; i++) {
+		if (*c == '\n')
+			prom_putc('\r');
+		prom_putc(*c++);
+	}
+}
+
+static void setup_prom_vectors(void)
+{
+	u32 version = *(u32 *)(RESET_VECTOR + 0x90);
+
+	if (version >= 307) {
+		prom_display = (void *)PROM_DISPLAY_ADDR;
+		prom_putc = (void *)PROM_PUTC_ADDR;
+		prom_printf = real_prom_printf;
+		prom_monitor = (void *)PROM_MONITOR_ADDR;
+	}
+	prom_printf("prom vectors set up\n");
+}
+
+static struct at93c_defs at93c_defs[N_MACHTYPES] = {
+	{(void *)AT93C_REG_100, (void *)AT93C_RDATA_REG_100, AT93C_RDATA_SHIFT_100,
+	AT93C_WDATA_SHIFT_100, AT93C_CS_M_100, AT93C_CLK_M_100},
+	{(void *)AT93C_REG_200, (void *)AT93C_RDATA_REG_200, AT93C_RDATA_SHIFT_200,
+	AT93C_WDATA_SHIFT_200, AT93C_CS_M_200, AT93C_CLK_M_200},
+};
+
+void __init prom_init(void)
+{
+	int argc = fw_arg0;
+	char **argv = (char **) fw_arg1;
+
+	setup_prom_vectors();
+
+	if (current_cpu_data.cputype == CPU_R5000) {
+	        prom_printf("LASAT 200 board\n");
+		mips_machtype = MACH_LASAT_200;
+                lasat_ndelay_divider = LASAT_200_DIVIDER;
+        } else {
+	        prom_printf("LASAT 100 board\n");
+		mips_machtype = MACH_LASAT_100;
+                lasat_ndelay_divider = LASAT_100_DIVIDER;
+        }
+
+	at93c = &at93c_defs[mips_machtype];
+
+	lasat_init_board_info();		/* Read info from EEPROM */
+
+	mips_machgroup = MACH_GROUP_LASAT;
+
+	/* Get the command line */
+	if (argc > 0) {
+		strncpy(arcs_cmdline, argv[0], CL_SIZE-1);
+		arcs_cmdline[CL_SIZE-1] = '\0';
+	}
+
+	/* Set the I/O base address */
+	set_io_port_base(KSEG1);
+
+	/* Set memory regions */
+	ioport_resource.start = 0;
+	ioport_resource.end = 0xffffffff;	/* Wrong, fixme.  */
+
+	add_memory_region(0, lasat_board_info.li_memsize, BOOT_MEM_RAM);
+}
+
+unsigned long __init prom_free_prom_memory(void)
+{
+	return 0;
+}
+
+const char *get_system_type(void)
+{
+	return lasat_board_info.li_bmstr;
+}
diff --git a/arch/mips/lasat/prom.h b/arch/mips/lasat/prom.h
new file mode 100644
index 0000000..07be7bf
--- /dev/null
+++ b/arch/mips/lasat/prom.h
@@ -0,0 +1,6 @@
+#ifndef PROM_H
+#define PROM_H
+extern void (* prom_display)(const char *string, int pos, int clear);
+extern void (* prom_monitor)(void);
+extern void (* prom_printf)(const char * fmt, ...);
+#endif
diff --git a/arch/mips/lasat/reset.c b/arch/mips/lasat/reset.c
new file mode 100644
index 0000000..37e4912
--- /dev/null
+++ b/arch/mips/lasat/reset.c
@@ -0,0 +1,67 @@
+/* 
+ * Thomas Horsten <thh@lasat.com>
+ * Copyright (C) 2000 LASAT Networks A/S.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Reset the LASAT board.
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <asm/lasat/lasat.h>
+#include "picvue.h"
+#include "prom.h"
+
+static void lasat_machine_restart(char *command);
+static void lasat_machine_halt(void);
+
+/* Used to set machine to boot in service mode via /proc interface */
+int lasat_boot_to_service = 0;
+
+static void lasat_machine_restart(char *command)
+{
+	local_irq_disable();
+
+	if (lasat_boot_to_service) {
+		printk("machine_restart: Rebooting to service mode\n");
+		*(volatile unsigned int *)0xa0000024 = 0xdeadbeef;
+		*(volatile unsigned int *)0xa00000fc = 0xfedeabba;
+	}
+	*lasat_misc->reset_reg = 0xbedead;
+	for (;;) ;
+}
+
+#define MESSAGE "System halted"
+static void lasat_machine_halt(void)
+{
+	local_irq_disable();
+
+	/* Disable interrupts and loop forever */
+	printk(KERN_NOTICE MESSAGE "\n");
+#ifdef CONFIG_PICVUE
+	pvc_clear();
+	pvc_write_string(MESSAGE, 0, 0);
+#endif
+	prom_monitor();
+	for (;;) ;
+}
+
+void lasat_reboot_setup(void)
+{
+	_machine_restart = lasat_machine_restart;
+	_machine_halt = lasat_machine_halt;
+	_machine_power_off = lasat_machine_halt;
+}
diff --git a/arch/mips/lasat/setup.c b/arch/mips/lasat/setup.c
new file mode 100644
index 0000000..e371ed5
--- /dev/null
+++ b/arch/mips/lasat/setup.c
@@ -0,0 +1,192 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * Thomas Horsten <thh@lasat.com>
+ * Copyright (C) 2000 LASAT Networks A/S.
+ *
+ * Brian Murphy <brian@murphy.dk>
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Lasat specific setup.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+
+#include <asm/time.h>
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/serial.h>
+#include <asm/lasat/lasat.h>
+#include <asm/lasat/serial.h>
+
+#ifdef CONFIG_PICVUE
+#include <linux/notifier.h>
+#endif
+
+#include "ds1603.h"
+#include <asm/lasat/ds1603.h>
+#include <asm/lasat/picvue.h>
+#include <asm/lasat/eeprom.h>
+
+#include "prom.h"
+
+int lasat_command_line = 0;
+void lasatint_init(void);
+
+extern void lasat_reboot_setup(void);
+extern void pcisetup(void);
+extern void edhac_init(void *, void *, void *);
+extern void addrflt_init(void);
+
+struct lasat_misc lasat_misc_info[N_MACHTYPES] = {
+	{(void *)KSEG1ADDR(0x1c840000), (void *)KSEG1ADDR(0x1c800000), 2},
+	{(void *)KSEG1ADDR(0x11080000), (void *)KSEG1ADDR(0x11000000), 6}
+};
+
+struct lasat_misc *lasat_misc = NULL;
+
+#ifdef CONFIG_DS1603
+static struct ds_defs ds_defs[N_MACHTYPES] = {
+	{ (void *)DS1603_REG_100, (void *)DS1603_REG_100,
+		DS1603_RST_100, DS1603_CLK_100, DS1603_DATA_100,
+		DS1603_DATA_SHIFT_100, 0, 0 },
+	{ (void *)DS1603_REG_200, (void *)DS1603_DATA_REG_200,
+		DS1603_RST_200, DS1603_CLK_200, DS1603_DATA_200,
+		DS1603_DATA_READ_SHIFT_200, 1, 2000 }
+};
+#endif
+
+#ifdef CONFIG_PICVUE
+#include "picvue.h"
+static struct pvc_defs pvc_defs[N_MACHTYPES] = {
+	{ (void *)PVC_REG_100, PVC_DATA_SHIFT_100, PVC_DATA_M_100,
+		PVC_E_100, PVC_RW_100, PVC_RS_100 },
+	{ (void *)PVC_REG_200, PVC_DATA_SHIFT_200, PVC_DATA_M_200,
+		PVC_E_200, PVC_RW_200, PVC_RS_200 }
+};
+#endif
+
+static int lasat_panic_display(struct notifier_block *this,
+			     unsigned long event, void *ptr)
+{
+#ifdef CONFIG_PICVUE
+	unsigned char *string = ptr;
+	if (string == NULL)
+		string = "Kernel Panic";
+	pvc_dump_string(string);
+#endif
+	return NOTIFY_DONE;
+}
+
+static int lasat_panic_prom_monitor(struct notifier_block *this,
+			     unsigned long event, void *ptr)
+{
+	prom_monitor();
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block lasat_panic_block[] = 
+{
+	{ lasat_panic_display, NULL, INT_MAX },
+	{ lasat_panic_prom_monitor, NULL, INT_MIN }
+};
+
+static void lasat_time_init(void)
+{
+	mips_hpt_frequency = lasat_board_info.li_cpu_hz / 2;
+}
+
+static void lasat_timer_setup(struct irqaction *irq)
+{
+
+	write_c0_compare(
+		read_c0_count() + 
+		mips_hpt_frequency / HZ);
+	change_c0_status(ST0_IM, IE_IRQ0 | IE_IRQ5);
+}
+
+#define DYNAMIC_SERIAL_INIT
+#ifdef DYNAMIC_SERIAL_INIT
+void __init serial_init(void)
+{
+#ifdef CONFIG_SERIAL_8250
+	struct uart_port s;
+
+	memset(&s, 0, sizeof(s));
+
+	s.flags = STD_COM_FLAGS;
+	s.iotype = SERIAL_IO_MEM;
+
+	if (mips_machtype == MACH_LASAT_100) {
+		s.uartclk = LASAT_BASE_BAUD_100 * 16;
+		s.irq = LASATINT_UART_100;
+		s.regshift = LASAT_UART_REGS_SHIFT_100;
+		s.membase = (char *)KSEG1ADDR(LASAT_UART_REGS_BASE_100);
+	} else {
+		s.uartclk = LASAT_BASE_BAUD_200 * 16;
+		s.irq = LASATINT_UART_200;
+		s.regshift = LASAT_UART_REGS_SHIFT_200;
+		s.membase = (char *)KSEG1ADDR(LASAT_UART_REGS_BASE_200);
+	}
+
+	if (early_serial_setup(&s) != 0)
+		printk(KERN_ERR "Serial setup failed!\n");
+#endif
+}
+#endif
+
+static int __init lasat_setup(void)
+{
+	int i;
+	lasat_misc  = &lasat_misc_info[mips_machtype];
+#ifdef CONFIG_PICVUE
+	picvue = &pvc_defs[mips_machtype];
+#endif
+
+	/* Set up panic notifier */
+	for (i = 0; i < sizeof(lasat_panic_block) / sizeof(struct notifier_block); i++)
+		notifier_chain_register(&panic_notifier_list, &lasat_panic_block[i]);
+
+	lasat_reboot_setup();
+
+	board_time_init = lasat_time_init;
+	board_timer_setup = lasat_timer_setup;
+
+#ifdef CONFIG_DS1603
+	ds1603 = &ds_defs[mips_machtype];
+	rtc_get_time = ds1603_read;
+	rtc_set_time = ds1603_set;
+#endif
+
+#ifdef DYNAMIC_SERIAL_INIT
+	serial_init();
+#endif
+	/* Switch from prom exception handler to normal mode */
+	change_c0_status(ST0_BEV,0);
+
+	prom_printf("Lasat specific initialization complete\n");
+
+        return 0;
+}
+
+early_initcall(lasat_setup);
diff --git a/arch/mips/lasat/sysctl.c b/arch/mips/lasat/sysctl.c
new file mode 100644
index 0000000..1c0cc62
--- /dev/null
+++ b/arch/mips/lasat/sysctl.c
@@ -0,0 +1,355 @@
+/*
+ * Thomas Horsten <thh@lasat.com>
+ * Copyright (C) 2000 LASAT Networks A/S.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Routines specific to the LASAT boards
+ */
+#include <linux/types.h>
+#include <asm/lasat/lasat.h>
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/sysctl.h>
+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/net.h>
+#include <linux/inet.h>
+#include <asm/uaccess.h>
+
+#include "sysctl.h"
+#include "ds1603.h"
+
+static DECLARE_MUTEX(lasat_info_sem);
+
+/* Strategy function to write EEPROM after changing string entry */ 
+int sysctl_lasatstring(ctl_table *table, int *name, int nlen,
+		void *oldval, size_t *oldlenp,
+		void *newval, size_t newlen, void **context)
+{
+	int r;
+	down(&lasat_info_sem);
+	r = sysctl_string(table, name, 
+			  nlen, oldval, oldlenp, newval, newlen, context);
+	if (r < 0) {
+		up(&lasat_info_sem);
+		return r;
+	}
+	if (newval && newlen) {
+		lasat_write_eeprom_info();
+	}
+	up(&lasat_info_sem);
+	return 1;
+}
+
+
+/* And the same for proc */
+int proc_dolasatstring(ctl_table *table, int write, struct file *filp,
+		       void *buffer, size_t *lenp, loff_t *ppos)
+{
+	int r;
+	down(&lasat_info_sem);
+	r = proc_dostring(table, write, filp, buffer, lenp, ppos);
+	if ( (!write) || r) {
+		up(&lasat_info_sem);
+		return r;
+	}
+	lasat_write_eeprom_info();
+	up(&lasat_info_sem);
+	return 0;
+}
+
+/* proc function to write EEPROM after changing int entry */ 
+int proc_dolasatint(ctl_table *table, int write, struct file *filp,
+		       void *buffer, size_t *lenp, loff_t *ppos)
+{
+	int r;
+	down(&lasat_info_sem);
+	r = proc_dointvec(table, write, filp, buffer, lenp, ppos);
+	if ( (!write) || r) {
+		up(&lasat_info_sem);
+		return r;
+	}
+	lasat_write_eeprom_info();
+	up(&lasat_info_sem);
+	return 0;
+}
+
+static int rtctmp;
+
+#ifdef CONFIG_DS1603
+/* proc function to read/write RealTime Clock */ 
+int proc_dolasatrtc(ctl_table *table, int write, struct file *filp,
+		       void *buffer, size_t *lenp, loff_t *ppos)
+{
+	int r;
+	down(&lasat_info_sem);
+	if (!write) {
+		rtctmp = ds1603_read();
+		/* check for time < 0 and set to 0 */
+		if (rtctmp < 0)
+			rtctmp = 0;
+	}
+	r = proc_dointvec(table, write, filp, buffer, lenp, ppos);
+	if ( (!write) || r) {
+		up(&lasat_info_sem);
+		return r;
+	}
+	ds1603_set(rtctmp);
+	up(&lasat_info_sem);
+	return 0;
+}
+#endif
+
+/* Sysctl for setting the IP addresses */
+int sysctl_lasat_intvec(ctl_table *table, int *name, int nlen,
+		    void *oldval, size_t *oldlenp,
+		    void *newval, size_t newlen, void **context)
+{
+	int r;
+	down(&lasat_info_sem);
+	r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen, context);
+	if (r < 0) {
+		up(&lasat_info_sem);
+		return r;
+	}
+	if (newval && newlen) {
+		lasat_write_eeprom_info();
+	}
+	up(&lasat_info_sem);
+	return 1;
+}
+
+#ifdef CONFIG_DS1603
+/* Same for RTC */
+int sysctl_lasat_rtc(ctl_table *table, int *name, int nlen,
+		    void *oldval, size_t *oldlenp,
+		    void *newval, size_t newlen, void **context)
+{
+	int r;
+	down(&lasat_info_sem);
+	rtctmp = ds1603_read();
+	if (rtctmp < 0)
+		rtctmp = 0;
+	r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen, context);
+	if (r < 0) {
+		up(&lasat_info_sem);
+		return r;
+	}
+	if (newval && newlen) {
+		ds1603_set(rtctmp);
+	}
+	up(&lasat_info_sem);
+	return 1;
+}
+#endif
+
+#ifdef CONFIG_INET
+static char lasat_bcastaddr[16];
+
+void update_bcastaddr(void)
+{
+	unsigned int ip;
+	
+	ip = (lasat_board_info.li_eeprom_info.ipaddr & 
+		lasat_board_info.li_eeprom_info.netmask) | 
+		~lasat_board_info.li_eeprom_info.netmask;
+
+	sprintf(lasat_bcastaddr, "%d.%d.%d.%d",
+			(ip      ) & 0xff,
+			(ip >>  8) & 0xff,
+			(ip >> 16) & 0xff,
+			(ip >> 24) & 0xff);
+}
+
+static char proc_lasat_ipbuf[32];
+/* Parsing of IP address */
+int proc_lasat_ip(ctl_table *table, int write, struct file *filp,
+		       void *buffer, size_t *lenp, loff_t *ppos)
+{
+	int len;
+        unsigned int ip;
+	char *p, c;
+
+	if (!table->data || !table->maxlen || !*lenp ||
+	    (*ppos && !write)) {
+		*lenp = 0;
+		return 0;
+	}
+
+	down(&lasat_info_sem);
+	if (write) {
+		len = 0;
+		p = buffer;
+		while (len < *lenp) {
+			if(get_user(c, p++)) {
+				up(&lasat_info_sem);
+				return -EFAULT;
+			}
+			if (c == 0 || c == '\n')
+				break;
+			len++;
+		}
+		if (len >= sizeof(proc_lasat_ipbuf)-1) 
+			len = sizeof(proc_lasat_ipbuf) - 1;
+		if (copy_from_user(proc_lasat_ipbuf, buffer, len))
+		{
+			up(&lasat_info_sem);
+			return -EFAULT;
+		}
+		proc_lasat_ipbuf[len] = 0;
+		*ppos += *lenp;
+		/* Now see if we can convert it to a valid IP */
+		ip = in_aton(proc_lasat_ipbuf);
+		*(unsigned int *)(table->data) = ip;
+		lasat_write_eeprom_info();
+	} else {
+		ip = *(unsigned int *)(table->data);
+		sprintf(proc_lasat_ipbuf, "%d.%d.%d.%d",
+			(ip      ) & 0xff,
+			(ip >>  8) & 0xff,
+			(ip >> 16) & 0xff,
+			(ip >> 24) & 0xff);
+		len = strlen(proc_lasat_ipbuf);
+		if (len > *lenp)
+			len = *lenp;
+		if (len)
+			if(copy_to_user(buffer, proc_lasat_ipbuf, len)) {
+				up(&lasat_info_sem);
+				return -EFAULT;
+			}
+		if (len < *lenp) {
+			if(put_user('\n', ((char *) buffer) + len)) {
+				up(&lasat_info_sem);
+				return -EFAULT;
+			}
+			len++;
+		}
+		*lenp = len;
+		*ppos += len;
+	}
+	update_bcastaddr();
+	up(&lasat_info_sem);
+	return 0;
+}
+#endif /* defined(CONFIG_INET) */
+
+static int sysctl_lasat_eeprom_value(ctl_table *table, int *name, int nlen, 
+				     void *oldval, size_t *oldlenp, 
+				     void *newval, size_t newlen,
+				     void **context)
+{
+	int r;
+
+	down(&lasat_info_sem);
+	r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen, context);
+	if (r < 0) {
+		up(&lasat_info_sem);
+		return r;
+	}
+
+	if (newval && newlen)
+	{
+		if (name && *name == LASAT_PRID)
+			lasat_board_info.li_eeprom_info.prid = *(int*)newval;
+
+		lasat_write_eeprom_info();
+		lasat_init_board_info();
+	}
+	up(&lasat_info_sem);
+
+	return 0;
+}
+
+int proc_lasat_eeprom_value(ctl_table *table, int write, struct file *filp,
+		       void *buffer, size_t *lenp, loff_t *ppos)
+{
+	int r;
+	down(&lasat_info_sem);
+	r = proc_dointvec(table, write, filp, buffer, lenp, ppos);
+	if ( (!write) || r) {
+		up(&lasat_info_sem);
+		return r;
+	}
+	if (filp && filp->f_dentry)
+	{
+		if (!strcmp(filp->f_dentry->d_name.name, "prid"))
+			lasat_board_info.li_eeprom_info.prid = lasat_board_info.li_prid;
+		if (!strcmp(filp->f_dentry->d_name.name, "debugaccess"))
+			lasat_board_info.li_eeprom_info.debugaccess = lasat_board_info.li_debugaccess;
+	}
+	lasat_write_eeprom_info();	
+	up(&lasat_info_sem);
+	return 0;
+}
+
+extern int lasat_boot_to_service;
+
+#ifdef CONFIG_SYSCTL
+
+static ctl_table lasat_table[] = {
+	{LASAT_CPU_HZ, "cpu-hz", &lasat_board_info.li_cpu_hz, sizeof(int),
+	 0444, NULL, &proc_dointvec, &sysctl_intvec},
+	{LASAT_BUS_HZ, "bus-hz", &lasat_board_info.li_bus_hz, sizeof(int),
+	 0444, NULL, &proc_dointvec, &sysctl_intvec},
+	{LASAT_MODEL, "bmid", &lasat_board_info.li_bmid, sizeof(int),
+	 0444, NULL, &proc_dointvec, &sysctl_intvec},
+	{LASAT_PRID, "prid", &lasat_board_info.li_prid, sizeof(int),
+	 0644, NULL, &proc_lasat_eeprom_value, &sysctl_lasat_eeprom_value},
+#ifdef CONFIG_INET
+	{LASAT_IPADDR, "ipaddr", &lasat_board_info.li_eeprom_info.ipaddr, sizeof(int),
+	 0644, NULL, &proc_lasat_ip, &sysctl_lasat_intvec},
+	{LASAT_NETMASK, "netmask", &lasat_board_info.li_eeprom_info.netmask, sizeof(int),
+	 0644, NULL, &proc_lasat_ip, &sysctl_lasat_intvec},
+	{LASAT_BCAST, "bcastaddr", &lasat_bcastaddr, 
+		sizeof(lasat_bcastaddr), 0600, NULL, 
+		&proc_dostring, &sysctl_string},
+#endif
+	{LASAT_PASSWORD, "passwd_hash", &lasat_board_info.li_eeprom_info.passwd_hash, sizeof(lasat_board_info.li_eeprom_info.passwd_hash),
+	 0600, NULL, &proc_dolasatstring, &sysctl_lasatstring},
+	{LASAT_SBOOT, "boot-service", &lasat_boot_to_service, sizeof(int),
+	 0644, NULL, &proc_dointvec, &sysctl_intvec},
+#ifdef CONFIG_DS1603
+	{LASAT_RTC, "rtc", &rtctmp, sizeof(int),
+	 0644, NULL, &proc_dolasatrtc, &sysctl_lasat_rtc},
+#endif
+	{LASAT_NAMESTR, "namestr", &lasat_board_info.li_namestr, sizeof(lasat_board_info.li_namestr),
+	 0444, NULL, &proc_dostring, &sysctl_string},
+	{LASAT_TYPESTR, "typestr", &lasat_board_info.li_typestr, sizeof(lasat_board_info.li_typestr),
+	 0444, NULL, &proc_dostring, &sysctl_string},
+	{0}
+};
+
+#define CTL_LASAT 1	// CTL_ANY ???
+static ctl_table lasat_root_table[] = {
+	{ CTL_LASAT, "lasat", NULL, 0, 0555, lasat_table },
+	{ 0 }
+};
+
+static int __init lasat_register_sysctl(void)
+{
+	struct ctl_table_header *lasat_table_header;
+
+	lasat_table_header =
+		register_sysctl_table(lasat_root_table, 0);
+
+	return 0;
+}
+
+__initcall(lasat_register_sysctl);
+#endif /* CONFIG_SYSCTL */
diff --git a/arch/mips/lasat/sysctl.h b/arch/mips/lasat/sysctl.h
new file mode 100644
index 0000000..4d139d2
--- /dev/null
+++ b/arch/mips/lasat/sysctl.h
@@ -0,0 +1,24 @@
+/*
+ * LASAT sysctl values
+ */
+
+#ifndef _LASAT_SYSCTL_H
+#define _LASAT_SYSCTL_H
+
+/* /proc/sys/lasat */
+enum {
+	LASAT_CPU_HZ=1,
+	LASAT_BUS_HZ,
+	LASAT_MODEL,
+	LASAT_PRID,
+	LASAT_IPADDR,
+	LASAT_NETMASK,
+	LASAT_BCAST,
+	LASAT_PASSWORD,
+	LASAT_SBOOT,
+	LASAT_RTC,
+	LASAT_NAMESTR,
+	LASAT_TYPESTR,
+};
+
+#endif /* _LASAT_SYSCTL_H */
diff --git a/arch/mips/lib-32/Makefile b/arch/mips/lib-32/Makefile
new file mode 100644
index 0000000..fd6a2ba
--- /dev/null
+++ b/arch/mips/lib-32/Makefile
@@ -0,0 +1,25 @@
+#
+# Makefile for MIPS-specific library files..
+#
+
+lib-y	+= csum_partial.o memset.o watch.o 
+
+obj-$(CONFIG_CPU_MIPS32)	+= dump_tlb.o
+obj-$(CONFIG_CPU_MIPS64)	+= dump_tlb.o
+obj-$(CONFIG_CPU_NEVADA)	+= dump_tlb.o
+obj-$(CONFIG_CPU_R10000)	+= dump_tlb.o
+obj-$(CONFIG_CPU_R3000)		+= r3k_dump_tlb.o
+obj-$(CONFIG_CPU_R4300)		+= dump_tlb.o
+obj-$(CONFIG_CPU_R4X00)		+= dump_tlb.o
+obj-$(CONFIG_CPU_R5000)		+= dump_tlb.o
+obj-$(CONFIG_CPU_R5432)		+= dump_tlb.o
+obj-$(CONFIG_CPU_R6000)		+=
+obj-$(CONFIG_CPU_R8000)		+=
+obj-$(CONFIG_CPU_RM7000)	+= dump_tlb.o
+obj-$(CONFIG_CPU_RM9000)	+= dump_tlb.o
+obj-$(CONFIG_CPU_SB1)		+= dump_tlb.o
+obj-$(CONFIG_CPU_TX39XX)	+= r3k_dump_tlb.o
+obj-$(CONFIG_CPU_TX49XX)	+= dump_tlb.o
+obj-$(CONFIG_CPU_VR41XX)	+= dump_tlb.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/lib-32/csum_partial.S b/arch/mips/lib-32/csum_partial.S
new file mode 100644
index 0000000..ea257db
--- /dev/null
+++ b/arch/mips/lib-32/csum_partial.S
@@ -0,0 +1,240 @@
+/*
+ * 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) 1998 Ralf Baechle
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+
+#define ADDC(sum,reg)			\
+	addu	sum, reg;		\
+	sltu	v1, sum, reg;		\
+	addu	sum, v1
+
+#define CSUM_BIGCHUNK(src, offset, sum, t0, t1, t2, t3) \
+	lw	t0, (offset + 0x00)(src); \
+	lw	t1, (offset + 0x04)(src); \
+	lw	t2, (offset + 0x08)(src); \
+	lw	t3, (offset + 0x0c)(src); \
+	ADDC(sum, t0);                    \
+	ADDC(sum, t1);                    \
+	ADDC(sum, t2);                    \
+	ADDC(sum, t3);                    \
+	lw	t0, (offset + 0x10)(src); \
+	lw	t1, (offset + 0x14)(src); \
+	lw	t2, (offset + 0x18)(src); \
+	lw	t3, (offset + 0x1c)(src); \
+	ADDC(sum, t0);                    \
+	ADDC(sum, t1);                    \
+	ADDC(sum, t2);                    \
+	ADDC(sum, t3);                    \
+
+/*
+ * a0: source address
+ * a1: length of the area to checksum
+ * a2: partial checksum
+ */
+
+#define src a0
+#define dest a1
+#define sum v0
+
+	.text
+	.set	noreorder
+
+/* unknown src alignment and < 8 bytes to go  */
+small_csumcpy:
+	move	a1, t2
+
+	andi	t0, a1, 4
+	beqz	t0, 1f
+	 andi	t0, a1, 2
+
+	/* Still a full word to go  */
+	ulw	t1, (src)
+	addiu	src, 4
+	ADDC(sum, t1)
+
+1:	move	t1, zero
+	beqz	t0, 1f
+	 andi	t0, a1, 1
+
+	/* Still a halfword to go  */
+	ulhu	t1, (src)
+	addiu	src, 2
+
+1:	beqz	t0, 1f
+	 sll	t1, t1, 16
+
+	lbu	t2, (src)
+	 nop
+
+#ifdef __MIPSEB__
+	sll	t2, t2, 8
+#endif
+	or	t1, t2
+
+1:	ADDC(sum, t1)
+
+	/* fold checksum */
+	sll	v1, sum, 16
+	addu	sum, v1
+	sltu	v1, sum, v1
+	srl	sum, sum, 16
+	addu	sum, v1
+
+	/* odd buffer alignment? */
+	beqz	t7, 1f
+	 nop
+	sll	v1, sum, 8
+	srl	sum, sum, 8
+	or	sum, v1
+	andi	sum, 0xffff
+1:
+	.set	reorder
+	/* Add the passed partial csum.  */
+	ADDC(sum, a2)
+	jr	ra
+	.set	noreorder
+
+/* ------------------------------------------------------------------------- */
+
+	.align	5
+LEAF(csum_partial)
+	move	sum, zero
+	move	t7, zero
+
+	sltiu	t8, a1, 0x8
+	bnez	t8, small_csumcpy		/* < 8 bytes to copy */
+	 move	t2, a1
+
+	beqz	a1, out
+	 andi	t7, src, 0x1			/* odd buffer? */
+
+hword_align:
+	beqz	t7, word_align
+	 andi	t8, src, 0x2
+
+	lbu	t0, (src)
+	subu	a1, a1, 0x1
+#ifdef __MIPSEL__
+	sll	t0, t0, 8
+#endif
+	ADDC(sum, t0)
+	addu	src, src, 0x1
+	andi	t8, src, 0x2
+
+word_align:
+	beqz	t8, dword_align
+	 sltiu	t8, a1, 56
+
+	lhu	t0, (src)
+	subu	a1, a1, 0x2
+	ADDC(sum, t0)
+	sltiu	t8, a1, 56
+	addu	src, src, 0x2
+
+dword_align:
+	bnez	t8, do_end_words
+	 move	t8, a1
+
+	andi	t8, src, 0x4
+	beqz	t8, qword_align
+	 andi	t8, src, 0x8
+
+	lw	t0, 0x00(src)
+	subu	a1, a1, 0x4
+	ADDC(sum, t0)
+	addu	src, src, 0x4
+	andi	t8, src, 0x8
+
+qword_align:
+	beqz	t8, oword_align
+	 andi	t8, src, 0x10
+
+	lw	t0, 0x00(src)
+	lw	t1, 0x04(src)
+	subu	a1, a1, 0x8
+	ADDC(sum, t0)
+	ADDC(sum, t1)
+	addu	src, src, 0x8
+	andi	t8, src, 0x10
+
+oword_align:
+	beqz	t8, begin_movement
+	 srl	t8, a1, 0x7
+
+	lw	t3, 0x08(src)
+	lw	t4, 0x0c(src)
+	lw	t0, 0x00(src)
+	lw	t1, 0x04(src)
+	ADDC(sum, t3)
+	ADDC(sum, t4)
+	ADDC(sum, t0)
+	ADDC(sum, t1)
+	subu	a1, a1, 0x10
+	addu	src, src, 0x10
+	srl	t8, a1, 0x7
+
+begin_movement:
+	beqz	t8, 1f
+	 andi	t2, a1, 0x40
+
+move_128bytes:
+	CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
+	CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4)
+	CSUM_BIGCHUNK(src, 0x40, sum, t0, t1, t3, t4)
+	CSUM_BIGCHUNK(src, 0x60, sum, t0, t1, t3, t4)
+	subu	t8, t8, 0x01
+	bnez	t8, move_128bytes
+	 addu	src, src, 0x80
+
+1:
+	beqz	t2, 1f
+	 andi	t2, a1, 0x20
+
+move_64bytes:
+	CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
+	CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4)
+	addu	src, src, 0x40
+
+1:
+	beqz	t2, do_end_words
+	 andi	t8, a1, 0x1c
+
+move_32bytes:
+	CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
+	andi	t8, a1, 0x1c
+	addu	src, src, 0x20
+
+do_end_words:
+	beqz	t8, maybe_end_cruft
+	 srl	t8, t8, 0x2
+
+end_words:
+	lw	t0, (src)
+	subu	t8, t8, 0x1
+	ADDC(sum, t0)
+	bnez	t8, end_words
+	 addu	src, src, 0x4
+
+maybe_end_cruft:
+	andi	t2, a1, 0x3
+
+small_memcpy:
+ j small_csumcpy; move a1, t2
+	beqz	t2, out
+	 move	a1, t2
+
+end_bytes:
+	lb	t0, (src)
+	subu	a1, a1, 0x1
+	bnez	a2, end_bytes
+	 addu	src, src, 0x1
+
+out:
+	jr	ra
+	 move	v0, sum
+	END(csum_partial)
diff --git a/arch/mips/lib-32/dump_tlb.c b/arch/mips/lib-32/dump_tlb.c
new file mode 100644
index 0000000..019ac8f
--- /dev/null
+++ b/arch/mips/lib-32/dump_tlb.c
@@ -0,0 +1,222 @@
+/*
+ * Dump R4x00 TLB for debugging purposes.
+ *
+ * Copyright (C) 1994, 1995 by Waldorf Electronics, written by Ralf Baechle.
+ * Copyright (C) 1999 by Silicon Graphics, Inc.
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cachectl.h>
+#include <asm/cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+static inline const char *msk2str(unsigned int mask)
+{
+	switch (mask) {
+	case PM_4K:	return "4kb";
+	case PM_16K:	return "16kb";
+	case PM_64K:	return "64kb";
+	case PM_256K:	return "256kb";
+#ifndef CONFIG_CPU_VR41XX
+	case PM_1M:	return "1Mb";
+	case PM_4M:	return "4Mb";
+	case PM_16M:	return "16Mb";
+	case PM_64M:	return "64Mb";
+	case PM_256M:	return "256Mb";
+#endif
+	}
+
+	return "unknown";
+}
+
+#define BARRIER()					\
+	__asm__ __volatile__(				\
+		".set\tnoreorder\n\t"			\
+		"nop;nop;nop;nop;nop;nop;nop\n\t"	\
+		".set\treorder");
+
+void dump_tlb(int first, int last)
+{
+	unsigned int pagemask, c0, c1, asid;
+	unsigned long long entrylo0, entrylo1;
+	unsigned long entryhi;
+	int	i;
+
+	asid = read_c0_entryhi() & 0xff;
+
+	printk("\n");
+	for (i = first; i <= last; i++) {
+		write_c0_index(i);
+		BARRIER();
+		tlb_read();
+		BARRIER();
+		pagemask = read_c0_pagemask();
+		entryhi  = read_c0_entryhi();
+		entrylo0 = read_c0_entrylo0();
+		entrylo1 = read_c0_entrylo1();
+
+		/* Unused entries have a virtual address in KSEG0.  */
+		if ((entryhi & 0xf0000000) != 0x80000000
+		    && (entryhi & 0xff) == asid) {
+			/*
+			 * Only print entries in use
+			 */
+			printk("Index: %2d pgmask=%s ", i, msk2str(pagemask));
+
+			c0 = (entrylo0 >> 3) & 7;
+			c1 = (entrylo1 >> 3) & 7;
+
+			printk("va=%08lx asid=%02lx\n",
+			       (entryhi & 0xffffe000), (entryhi & 0xff));
+			printk("\t\t\t[pa=%08Lx c=%d d=%d v=%d g=%Ld]\n",
+			       (entrylo0 << 6) & PAGE_MASK, c0,
+			       (entrylo0 & 4) ? 1 : 0,
+			       (entrylo0 & 2) ? 1 : 0,
+			       (entrylo0 & 1));
+			printk("\t\t\t[pa=%08Lx c=%d d=%d v=%d g=%Ld]\n",
+			       (entrylo1 << 6) & PAGE_MASK, c1,
+			       (entrylo1 & 4) ? 1 : 0,
+			       (entrylo1 & 2) ? 1 : 0,
+			       (entrylo1 & 1));
+			printk("\n");
+		}
+	}
+
+	write_c0_entryhi(asid);
+}
+
+void dump_tlb_all(void)
+{
+	dump_tlb(0, current_cpu_data.tlbsize - 1);
+}
+
+void dump_tlb_wired(void)
+{
+	int	wired;
+
+	wired = read_c0_wired();
+	printk("Wired: %d", wired);
+	dump_tlb(0, read_c0_wired());
+}
+
+void dump_tlb_addr(unsigned long addr)
+{
+	unsigned int flags, oldpid;
+	int index;
+
+	local_irq_save(flags);
+	oldpid = read_c0_entryhi() & 0xff;
+	BARRIER();
+	write_c0_entryhi((addr & PAGE_MASK) | oldpid);
+	BARRIER();
+	tlb_probe();
+	BARRIER();
+	index = read_c0_index();
+	write_c0_entryhi(oldpid);
+	local_irq_restore(flags);
+
+	if (index < 0) {
+		printk("No entry for address 0x%08lx in TLB\n", addr);
+		return;
+	}
+
+	printk("Entry %d maps address 0x%08lx\n", index, addr);
+	dump_tlb(index, index);
+}
+
+void dump_tlb_nonwired(void)
+{
+	dump_tlb(read_c0_wired(), current_cpu_data.tlbsize - 1);
+}
+
+void dump_list_process(struct task_struct *t, void *address)
+{
+	pgd_t	*page_dir, *pgd;
+	pmd_t	*pmd;
+	pte_t	*pte, page;
+	unsigned long addr, val;
+
+	addr = (unsigned long) address;
+
+	printk("Addr                 == %08lx\n", addr);
+	printk("task                 == %8p\n", t);
+	printk("task->mm             == %8p\n", t->mm);
+	//printk("tasks->mm.pgd        == %08x\n", (unsigned int) t->mm->pgd);
+
+	if (addr > KSEG0)
+		page_dir = pgd_offset_k(0);
+	else
+		page_dir = pgd_offset(t->mm, 0);
+	printk("page_dir == %08x\n", (unsigned int) page_dir);
+
+	if (addr > KSEG0)
+		pgd = pgd_offset_k(addr);
+	else
+		pgd = pgd_offset(t->mm, addr);
+	printk("pgd == %08x, ", (unsigned int) pgd);
+
+	pmd = pmd_offset(pgd, addr);
+	printk("pmd == %08x, ", (unsigned int) pmd);
+
+	pte = pte_offset(pmd, addr);
+	printk("pte == %08x, ", (unsigned int) pte);
+
+	page = *pte;
+#ifdef CONFIG_64BIT_PHYS_ADDR
+	printk("page == %08Lx\n", pte_val(page));
+#else
+	printk("page == %08lx\n", pte_val(page));
+#endif
+
+	val = pte_val(page);
+	if (val & _PAGE_PRESENT) printk("present ");
+	if (val & _PAGE_READ) printk("read ");
+	if (val & _PAGE_WRITE) printk("write ");
+	if (val & _PAGE_ACCESSED) printk("accessed ");
+	if (val & _PAGE_MODIFIED) printk("modified ");
+	if (val & _PAGE_R4KBUG) printk("r4kbug ");
+	if (val & _PAGE_GLOBAL) printk("global ");
+	if (val & _PAGE_VALID) printk("valid ");
+	printk("\n");
+}
+
+void dump_list_current(void *address)
+{
+	dump_list_process(current, address);
+}
+
+unsigned int vtop(void *address)
+{
+	pgd_t	*pgd;
+	pmd_t	*pmd;
+	pte_t	*pte;
+	unsigned int addr, paddr;
+
+	addr = (unsigned long) address;
+	pgd = pgd_offset(current->mm, addr);
+	pmd = pmd_offset(pgd, addr);
+	pte = pte_offset(pmd, addr);
+	paddr = (KSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
+	paddr |= (addr & ~PAGE_MASK);
+
+	return paddr;
+}
+
+void dump16(unsigned long *p)
+{
+	int i;
+
+	for (i = 0; i < 8; i++) {
+		printk("*%08lx == %08lx, ", (unsigned long)p, *p);
+		p++;
+		printk("*%08lx == %08lx\n", (unsigned long)p, *p);
+		p++;
+	}
+}
diff --git a/arch/mips/lib-32/memset.S b/arch/mips/lib-32/memset.S
new file mode 100644
index 0000000..ad9ff40
--- /dev/null
+++ b/arch/mips/lib-32/memset.S
@@ -0,0 +1,145 @@
+/*
+ * 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) 1998, 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <asm/asm.h>
+#include <asm/offset.h>
+#include <asm/regdef.h>
+
+#define EX(insn,reg,addr,handler)			\
+9:	insn	reg, addr;				\
+	.section __ex_table,"a"; 			\
+	PTR	9b, handler; 				\
+	.previous
+
+	.macro	f_fill64 dst, offset, val, fixup
+	EX(LONG_S, \val, (\offset +  0 * LONGSIZE)(\dst), \fixup)
+	EX(LONG_S, \val, (\offset +  1 * LONGSIZE)(\dst), \fixup)
+	EX(LONG_S, \val, (\offset +  2 * LONGSIZE)(\dst), \fixup)
+	EX(LONG_S, \val, (\offset +  3 * LONGSIZE)(\dst), \fixup)
+	EX(LONG_S, \val, (\offset +  4 * LONGSIZE)(\dst), \fixup)
+	EX(LONG_S, \val, (\offset +  5 * LONGSIZE)(\dst), \fixup)
+	EX(LONG_S, \val, (\offset +  6 * LONGSIZE)(\dst), \fixup)
+	EX(LONG_S, \val, (\offset +  7 * LONGSIZE)(\dst), \fixup)
+	EX(LONG_S, \val, (\offset +  8 * LONGSIZE)(\dst), \fixup)
+	EX(LONG_S, \val, (\offset +  9 * LONGSIZE)(\dst), \fixup)
+	EX(LONG_S, \val, (\offset + 10 * LONGSIZE)(\dst), \fixup)
+	EX(LONG_S, \val, (\offset + 11 * LONGSIZE)(\dst), \fixup)
+	EX(LONG_S, \val, (\offset + 12 * LONGSIZE)(\dst), \fixup)
+	EX(LONG_S, \val, (\offset + 13 * LONGSIZE)(\dst), \fixup)
+	EX(LONG_S, \val, (\offset + 14 * LONGSIZE)(\dst), \fixup)
+	EX(LONG_S, \val, (\offset + 15 * LONGSIZE)(\dst), \fixup)
+	.endm
+
+/*
+ * memset(void *s, int c, size_t n)
+ *
+ * a0: start of area to clear
+ * a1: char to fill with
+ * a2: size of area to clear
+ */
+	.set	noreorder
+	.align	5
+LEAF(memset)
+	beqz		a1, 1f
+	 move		v0, a0			/* result */
+
+	andi		a1, 0xff		/* spread fillword */
+	sll		t1, a1, 8
+	or		a1, t1
+	sll		t1, a1, 16
+	or		a1, t1
+1:
+
+FEXPORT(__bzero)
+	sltiu		t0, a2, LONGSIZE	/* very small region? */
+	bnez		t0, small_memset
+	 andi		t0, a0, LONGMASK	/* aligned? */
+
+	beqz		t0, 1f
+	 PTR_SUBU	t0, LONGSIZE		/* alignment in bytes */
+
+#ifdef __MIPSEB__
+	EX(swl, a1, (a0), first_fixup)		/* make word aligned */
+#endif
+#ifdef __MIPSEL__
+	EX(swr, a1, (a0), first_fixup)		/* make word aligned */
+#endif
+	PTR_SUBU	a0, t0			/* long align ptr */
+	PTR_ADDU	a2, t0			/* correct size */
+
+1:	ori		t1, a2, 0x3f		/* # of full blocks */
+	xori		t1, 0x3f
+	beqz		t1, memset_partial	/* no block to fill */
+	 andi		t0, a2, 0x3c
+
+	PTR_ADDU	t1, a0			/* end address */
+	.set		reorder
+1:	PTR_ADDIU	a0, 64
+	f_fill64 a0, -64, a1, fwd_fixup
+	bne		t1, a0, 1b
+	.set		noreorder
+
+memset_partial:
+	PTR_LA		t1, 2f			/* where to start */
+	PTR_SUBU	t1, t0
+	jr		t1
+	 PTR_ADDU	a0, t0			/* dest ptr */
+
+	.set		push
+	.set		noreorder
+	.set		nomacro
+	f_fill64 a0, -64, a1, partial_fixup	/* ... but first do longs ... */
+2:	.set		pop
+	andi		a2, LONGMASK		/* At most one long to go */
+
+	beqz		a2, 1f
+	 PTR_ADDU	a0, a2			/* What's left */
+#ifdef __MIPSEB__
+	EX(swr, a1, -1(a0), last_fixup)
+#endif
+#ifdef __MIPSEL__
+	EX(swl, a1, -1(a0), last_fixup)
+#endif
+1:	jr		ra
+	 move		a2, zero
+
+small_memset:
+	beqz		a2, 2f
+	 PTR_ADDU	t1, a0, a2
+
+1:	PTR_ADDIU	a0, 1			/* fill bytewise */
+	bne		t1, a0, 1b
+	 sb		a1, -1(a0)
+
+2:	jr		ra			/* done */
+	 move		a2, zero
+	END(memset)
+
+first_fixup:
+	jr	ra
+	 nop
+
+fwd_fixup:
+	PTR_L		t0, TI_TASK($28)
+	LONG_L		t0, THREAD_BUADDR(t0)
+	andi		a2, 0x3f
+	LONG_ADDU	a2, t1
+	jr		ra
+	 LONG_SUBU	a2, t0
+
+partial_fixup:
+	PTR_L		t0, TI_TASK($28)
+	LONG_L		t0, THREAD_BUADDR(t0)
+	andi		a2, LONGMASK
+	LONG_ADDU	a2, t1
+	jr		ra
+	 LONG_SUBU	a2, t0
+
+last_fixup:
+	jr		ra
+	 andi		v1, a2, LONGMASK
diff --git a/arch/mips/lib-32/r3k_dump_tlb.c b/arch/mips/lib-32/r3k_dump_tlb.c
new file mode 100644
index 0000000..a878224
--- /dev/null
+++ b/arch/mips/lib-32/r3k_dump_tlb.c
@@ -0,0 +1,176 @@
+/*
+ * Dump R3000 TLB for debugging purposes.
+ *
+ * Copyright (C) 1994, 1995 by Waldorf Electronics, written by Ralf Baechle.
+ * Copyright (C) 1999 by Silicon Graphics, Inc.
+ * Copyright (C) 1999 by Harald Koerfgen
+ */
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cachectl.h>
+#include <asm/cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+extern int r3k_have_wired_reg;	/* defined in tlb-r3k.c */
+
+void dump_tlb(int first, int last)
+{
+	int	i;
+	unsigned int asid;
+	unsigned long entryhi, entrylo0;
+
+	asid = read_c0_entryhi() & 0xfc0;
+
+	for (i = first; i <= last; i++) {
+		write_c0_index(i<<8);
+		__asm__ __volatile__(
+			".set\tnoreorder\n\t"
+			"tlbr\n\t"
+			"nop\n\t"
+			".set\treorder");
+		entryhi  = read_c0_entryhi();
+		entrylo0 = read_c0_entrylo0();
+
+		/* Unused entries have a virtual address of KSEG0.  */
+		if ((entryhi & 0xffffe000) != 0x80000000
+		    && (entryhi & 0xfc0) == asid) {
+			/*
+			 * Only print entries in use
+			 */
+			printk("Index: %2d ", i);
+
+			printk("va=%08lx asid=%08lx"
+			       "  [pa=%06lx n=%d d=%d v=%d g=%d]",
+			       (entryhi & 0xffffe000),
+			       entryhi & 0xfc0,
+			       entrylo0 & PAGE_MASK,
+			       (entrylo0 & (1 << 11)) ? 1 : 0,
+			       (entrylo0 & (1 << 10)) ? 1 : 0,
+			       (entrylo0 & (1 << 9)) ? 1 : 0,
+			       (entrylo0 & (1 << 8)) ? 1 : 0);
+		}
+	}
+	printk("\n");
+
+	write_c0_entryhi(asid);
+}
+
+void dump_tlb_all(void)
+{
+	dump_tlb(0, current_cpu_data.tlbsize - 1);
+}
+
+void dump_tlb_wired(void)
+{
+	int wired = r3k_have_wired_reg ? read_c0_wired() : 8;
+
+	printk("Wired: %d", wired);
+	dump_tlb(0, wired - 1);
+}
+
+void dump_tlb_addr(unsigned long addr)
+{
+	unsigned long flags, oldpid;
+	int index;
+
+	local_irq_save(flags);
+	oldpid = read_c0_entryhi() & 0xff;
+	write_c0_entryhi((addr & PAGE_MASK) | oldpid);
+	tlb_probe();
+	index = read_c0_index();
+	write_c0_entryhi(oldpid);
+	local_irq_restore(flags);
+
+	if (index < 0) {
+		printk("No entry for address 0x%08lx in TLB\n", addr);
+		return;
+	}
+
+	printk("Entry %d maps address 0x%08lx\n", index, addr);
+	dump_tlb(index, index);
+}
+
+void dump_tlb_nonwired(void)
+{
+	int wired = r3k_have_wired_reg ? read_c0_wired() : 8;
+	dump_tlb(wired, current_cpu_data.tlbsize - 1);
+}
+
+void dump_list_process(struct task_struct *t, void *address)
+{
+	pgd_t	*page_dir, *pgd;
+	pmd_t	*pmd;
+	pte_t	*pte, page;
+	unsigned int addr;
+	unsigned long val;
+
+	addr = (unsigned int) address;
+
+	printk("Addr                 == %08x\n", addr);
+	printk("tasks->mm.pgd        == %08x\n", (unsigned int) t->mm->pgd);
+
+	page_dir = pgd_offset(t->mm, 0);
+	printk("page_dir == %08x\n", (unsigned int) page_dir);
+
+	pgd = pgd_offset(t->mm, addr);
+	printk("pgd == %08x, ", (unsigned int) pgd);
+
+	pmd = pmd_offset(pgd, addr);
+	printk("pmd == %08x, ", (unsigned int) pmd);
+
+	pte = pte_offset(pmd, addr);
+	printk("pte == %08x, ", (unsigned int) pte);
+
+	page = *pte;
+	printk("page == %08x\n", (unsigned int) pte_val(page));
+
+	val = pte_val(page);
+	if (val & _PAGE_PRESENT) printk("present ");
+	if (val & _PAGE_READ) printk("read ");
+	if (val & _PAGE_WRITE) printk("write ");
+	if (val & _PAGE_ACCESSED) printk("accessed ");
+	if (val & _PAGE_MODIFIED) printk("modified ");
+	if (val & _PAGE_GLOBAL) printk("global ");
+	if (val & _PAGE_VALID) printk("valid ");
+	printk("\n");
+}
+
+void dump_list_current(void *address)
+{
+	dump_list_process(current, address);
+}
+
+unsigned int vtop(void *address)
+{
+	pgd_t	*pgd;
+	pmd_t	*pmd;
+	pte_t	*pte;
+	unsigned int addr, paddr;
+
+	addr = (unsigned long) address;
+	pgd = pgd_offset(current->mm, addr);
+	pmd = pmd_offset(pgd, addr);
+	pte = pte_offset(pmd, addr);
+	paddr = (KSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
+	paddr |= (addr & ~PAGE_MASK);
+
+	return paddr;
+}
+
+void dump16(unsigned long *p)
+{
+	int i;
+
+	for (i = 0; i < 8; i++) {
+		printk("*%08lx == %08lx, ", (unsigned long)p, *p);
+		p++;
+		printk("*%08lx == %08lx\n", (unsigned long)p, *p);
+		p++;
+	}
+}
diff --git a/arch/mips/lib-32/watch.S b/arch/mips/lib-32/watch.S
new file mode 100644
index 0000000..808b3af
--- /dev/null
+++ b/arch/mips/lib-32/watch.S
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ *
+ * Kernel debug stuff to use the Watch registers.
+ * Useful to find stack overflows, dangling pointers etc.
+ *
+ * Copyright (C) 1995, 1996, 1999 by Ralf Baechle
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+
+		.set	noreorder
+/*
+ * Parameter: a0 - logic address to watch
+ *                 Currently only KSEG0 addresses are allowed!
+ *            a1 - set bit #1 to trap on load references
+ *                     bit #0 to trap on store references
+ * Results  : none
+ */
+		LEAF(__watch_set)
+		li	t0, 0x80000000
+		subu	a0, t0
+		ori	a0, 7
+		xori	a0, 7
+		or	a0, a1
+		mtc0	a0, CP0_WATCHLO
+		sw	a0, watch_savelo
+
+		jr	ra
+		 mtc0	zero, CP0_WATCHHI
+		END(__watch_set)
+
+/*
+ * Parameter: none
+ * Results  : none
+ */
+		LEAF(__watch_clear)
+		jr	ra
+		 mtc0	zero, CP0_WATCHLO
+		END(__watch_clear)
+
+/*
+ * Parameter: none
+ * Results  : none
+ */
+		LEAF(__watch_reenable)
+		lw	t0, watch_savelo
+		jr	ra
+		 mtc0	t0, CP0_WATCHLO
+		END(__watch_reenable)
+
+/*
+ * Saved value of the c0_watchlo register for watch_reenable()
+ */
+		.data
+watch_savelo:	.word	0
+		.text
diff --git a/arch/mips/lib-64/Makefile b/arch/mips/lib-64/Makefile
new file mode 100644
index 0000000..fd6a2ba
--- /dev/null
+++ b/arch/mips/lib-64/Makefile
@@ -0,0 +1,25 @@
+#
+# Makefile for MIPS-specific library files..
+#
+
+lib-y	+= csum_partial.o memset.o watch.o 
+
+obj-$(CONFIG_CPU_MIPS32)	+= dump_tlb.o
+obj-$(CONFIG_CPU_MIPS64)	+= dump_tlb.o
+obj-$(CONFIG_CPU_NEVADA)	+= dump_tlb.o
+obj-$(CONFIG_CPU_R10000)	+= dump_tlb.o
+obj-$(CONFIG_CPU_R3000)		+= r3k_dump_tlb.o
+obj-$(CONFIG_CPU_R4300)		+= dump_tlb.o
+obj-$(CONFIG_CPU_R4X00)		+= dump_tlb.o
+obj-$(CONFIG_CPU_R5000)		+= dump_tlb.o
+obj-$(CONFIG_CPU_R5432)		+= dump_tlb.o
+obj-$(CONFIG_CPU_R6000)		+=
+obj-$(CONFIG_CPU_R8000)		+=
+obj-$(CONFIG_CPU_RM7000)	+= dump_tlb.o
+obj-$(CONFIG_CPU_RM9000)	+= dump_tlb.o
+obj-$(CONFIG_CPU_SB1)		+= dump_tlb.o
+obj-$(CONFIG_CPU_TX39XX)	+= r3k_dump_tlb.o
+obj-$(CONFIG_CPU_TX49XX)	+= dump_tlb.o
+obj-$(CONFIG_CPU_VR41XX)	+= dump_tlb.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/lib-64/csum_partial.S b/arch/mips/lib-64/csum_partial.S
new file mode 100644
index 0000000..25aba66
--- /dev/null
+++ b/arch/mips/lib-64/csum_partial.S
@@ -0,0 +1,242 @@
+/*
+ * 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.
+ *
+ * Quick'n'dirty IP checksum ...
+ *
+ * Copyright (C) 1998, 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+
+#define ADDC(sum,reg)						\
+	addu	sum, reg;					\
+	sltu	v1, sum, reg;					\
+	addu	sum, v1
+
+#define CSUM_BIGCHUNK(src, offset, sum, t0, t1, t2, t3)		\
+	lw	t0, (offset + 0x00)(src);			\
+	lw	t1, (offset + 0x04)(src);			\
+	lw	t2, (offset + 0x08)(src); 			\
+	lw	t3, (offset + 0x0c)(src); 			\
+	ADDC(sum, t0);						\
+	ADDC(sum, t1);						\
+	ADDC(sum, t2);						\
+	ADDC(sum, t3);						\
+	lw	t0, (offset + 0x10)(src);			\
+	lw	t1, (offset + 0x14)(src);			\
+	lw	t2, (offset + 0x18)(src);			\
+	lw	t3, (offset + 0x1c)(src);			\
+	ADDC(sum, t0);						\
+	ADDC(sum, t1);						\
+	ADDC(sum, t2);						\
+	ADDC(sum, t3);						\
+
+/*
+ * a0: source address
+ * a1: length of the area to checksum
+ * a2: partial checksum
+ */
+
+#define src a0
+#define sum v0
+
+	.text
+	.set	noreorder
+
+/* unknown src alignment and < 8 bytes to go  */
+small_csumcpy:
+	move	a1, ta2
+
+	andi	ta0, a1, 4
+	beqz	ta0, 1f
+	 andi	ta0, a1, 2
+
+	/* Still a full word to go  */
+	ulw	ta1, (src)
+	daddiu	src, 4
+	ADDC(sum, ta1)
+
+1:	move	ta1, zero
+	beqz	ta0, 1f
+	 andi	ta0, a1, 1
+
+	/* Still a halfword to go  */
+	ulhu	ta1, (src)
+	daddiu	src, 2
+
+1:	beqz	ta0, 1f
+	 sll	ta1, ta1, 16
+
+	lbu	ta2, (src)
+	 nop
+
+#ifdef __MIPSEB__
+	sll	ta2, ta2, 8
+#endif
+	or	ta1, ta2
+
+1:	ADDC(sum, ta1)
+
+	/* fold checksum */
+	sll	v1, sum, 16
+	addu	sum, v1
+	sltu	v1, sum, v1
+	srl	sum, sum, 16
+	addu	sum, v1
+
+	/* odd buffer alignment? */
+	beqz	t3, 1f
+	 nop
+	sll	v1, sum, 8
+	srl	sum, sum, 8
+	or	sum, v1
+	andi	sum, 0xffff
+1:
+	.set	reorder
+	/* Add the passed partial csum.  */
+	ADDC(sum, a2)
+	jr	ra
+	.set	noreorder
+
+/* ------------------------------------------------------------------------- */
+
+	.align	5
+LEAF(csum_partial)
+	move	sum, zero
+	move	t3, zero
+
+	sltiu	t8, a1, 0x8
+	bnez	t8, small_csumcpy		/* < 8 bytes to copy */
+	 move	ta2, a1
+
+	beqz	a1, out
+	 andi	t3, src, 0x1			/* odd buffer? */
+
+hword_align:
+	beqz	t3, word_align
+	 andi	t8, src, 0x2
+
+	lbu	ta0, (src)
+	dsubu	a1, a1, 0x1
+#ifdef __MIPSEL__
+	sll	ta0, ta0, 8
+#endif
+	ADDC(sum, ta0)
+	daddu	src, src, 0x1
+	andi	t8, src, 0x2
+
+word_align:
+	beqz	t8, dword_align
+	 sltiu	t8, a1, 56
+
+	lhu	ta0, (src)
+	dsubu	a1, a1, 0x2
+	ADDC(sum, ta0)
+	sltiu	t8, a1, 56
+	daddu	src, src, 0x2
+
+dword_align:
+	bnez	t8, do_end_words
+	 move	t8, a1
+
+	andi	t8, src, 0x4
+	beqz	t8, qword_align
+	 andi	t8, src, 0x8
+
+	lw	ta0, 0x00(src)
+	dsubu	a1, a1, 0x4
+	ADDC(sum, ta0)
+	daddu	src, src, 0x4
+	andi	t8, src, 0x8
+
+qword_align:
+	beqz	t8, oword_align
+	 andi	t8, src, 0x10
+
+	lw	ta0, 0x00(src)
+	lw	ta1, 0x04(src)
+	dsubu	a1, a1, 0x8
+	ADDC(sum, ta0)
+	ADDC(sum, ta1)
+	daddu	src, src, 0x8
+	andi	t8, src, 0x10
+
+oword_align:
+	beqz	t8, begin_movement
+	 dsrl	t8, a1, 0x7
+
+	lw	ta3, 0x08(src)
+	lw	t0, 0x0c(src)
+	lw	ta0, 0x00(src)
+	lw	ta1, 0x04(src)
+	ADDC(sum, ta3)
+	ADDC(sum, t0)
+	ADDC(sum, ta0)
+	ADDC(sum, ta1)
+	dsubu	a1, a1, 0x10
+	daddu	src, src, 0x10
+	dsrl	t8, a1, 0x7
+
+begin_movement:
+	beqz	t8, 1f
+	 andi	ta2, a1, 0x40
+
+move_128bytes:
+	CSUM_BIGCHUNK(src, 0x00, sum, ta0, ta1, ta3, t0)
+	CSUM_BIGCHUNK(src, 0x20, sum, ta0, ta1, ta3, t0)
+	CSUM_BIGCHUNK(src, 0x40, sum, ta0, ta1, ta3, t0)
+	CSUM_BIGCHUNK(src, 0x60, sum, ta0, ta1, ta3, t0)
+	dsubu	t8, t8, 0x01
+	bnez	t8, move_128bytes
+	 daddu	src, src, 0x80
+
+1:
+	beqz	ta2, 1f
+	 andi	ta2, a1, 0x20
+
+move_64bytes:
+	CSUM_BIGCHUNK(src, 0x00, sum, ta0, ta1, ta3, t0)
+	CSUM_BIGCHUNK(src, 0x20, sum, ta0, ta1, ta3, t0)
+	daddu	src, src, 0x40
+
+1:
+	beqz	ta2, do_end_words
+	 andi	t8, a1, 0x1c
+
+move_32bytes:
+	CSUM_BIGCHUNK(src, 0x00, sum, ta0, ta1, ta3, t0)
+	andi	t8, a1, 0x1c
+	daddu	src, src, 0x20
+
+do_end_words:
+	beqz	t8, maybe_end_cruft
+	 dsrl	t8, t8, 0x2
+
+end_words:
+	lw	ta0, (src)
+	dsubu	t8, t8, 0x1
+	ADDC(sum, ta0)
+	bnez	t8, end_words
+	 daddu	src, src, 0x4
+
+maybe_end_cruft:
+	andi	ta2, a1, 0x3
+
+small_memcpy:
+ j small_csumcpy; move a1, ta2		/* XXX ??? */
+	beqz	t2, out
+	 move	a1, ta2
+
+end_bytes:
+	lb	ta0, (src)
+	dsubu	a1, a1, 0x1
+	bnez	a2, end_bytes
+	 daddu	src, src, 0x1
+
+out:
+	jr	ra
+	 move	v0, sum
+	END(csum_partial)
diff --git a/arch/mips/lib-64/dump_tlb.c b/arch/mips/lib-64/dump_tlb.c
new file mode 100644
index 0000000..42f88e0
--- /dev/null
+++ b/arch/mips/lib-64/dump_tlb.c
@@ -0,0 +1,211 @@
+/*
+ * Dump R4x00 TLB for debugging purposes.
+ *
+ * Copyright (C) 1994, 1995 by Waldorf Electronics, written by Ralf Baechle.
+ * Copyright (C) 1999 by Silicon Graphics, Inc.
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cachectl.h>
+#include <asm/cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+static inline const char *msk2str(unsigned int mask)
+{
+	switch (mask) {
+	case PM_4K:	return "4kb";
+	case PM_16K:	return "16kb";
+	case PM_64K:	return "64kb";
+	case PM_256K:	return "256kb";
+#ifndef CONFIG_CPU_VR41XX
+	case PM_1M:	return "1Mb";
+	case PM_4M:	return "4Mb";
+	case PM_16M:	return "16Mb";
+	case PM_64M:	return "64Mb";
+	case PM_256M:	return "256Mb";
+#endif
+	}
+
+	return "unknown";
+}
+
+#define BARRIER()					\
+	__asm__ __volatile__(				\
+		".set\tnoreorder\n\t"			\
+		"nop;nop;nop;nop;nop;nop;nop\n\t"	\
+		".set\treorder");
+
+void dump_tlb(int first, int last)
+{
+	unsigned long s_entryhi, entryhi, entrylo0, entrylo1, asid;
+	unsigned int s_index, pagemask, c0, c1, i;
+
+	s_entryhi = read_c0_entryhi();
+	s_index = read_c0_index();
+	asid = s_entryhi & 0xff;
+
+	for (i = first; i <= last; i++) {
+		write_c0_index(i);
+		BARRIER();
+		tlb_read();
+		BARRIER();
+		pagemask = read_c0_pagemask();
+		entryhi  = read_c0_entryhi();
+		entrylo0 = read_c0_entrylo0();
+		entrylo1 = read_c0_entrylo1();
+
+		/* Unused entries have a virtual address of CKSEG0.  */
+		if ((entryhi & ~0x1ffffUL) != CKSEG0
+		    && (entryhi & 0xff) == asid) {
+			/*
+			 * Only print entries in use
+			 */
+			printk("Index: %2d pgmask=%s ", i, msk2str(pagemask));
+
+			c0 = (entrylo0 >> 3) & 7;
+			c1 = (entrylo1 >> 3) & 7;
+
+			printk("va=%011lx asid=%02lx\n",
+			       (entryhi & ~0x1fffUL),
+			       entryhi & 0xff);
+			printk("\t[pa=%011lx c=%d d=%d v=%d g=%ld] ",
+			       (entrylo0 << 6) & PAGE_MASK, c0,
+			       (entrylo0 & 4) ? 1 : 0,
+			       (entrylo0 & 2) ? 1 : 0,
+			       (entrylo0 & 1));
+			printk("[pa=%011lx c=%d d=%d v=%d g=%ld]\n",
+			       (entrylo1 << 6) & PAGE_MASK, c1,
+			       (entrylo1 & 4) ? 1 : 0,
+			       (entrylo1 & 2) ? 1 : 0,
+			       (entrylo1 & 1));
+		}
+	}
+	printk("\n");
+
+	write_c0_entryhi(s_entryhi);
+	write_c0_index(s_index);
+}
+
+void dump_tlb_all(void)
+{
+	dump_tlb(0, current_cpu_data.tlbsize - 1);
+}
+
+void dump_tlb_wired(void)
+{
+	int	wired;
+
+	wired = read_c0_wired();
+	printk("Wired: %d", wired);
+	dump_tlb(0, read_c0_wired());
+}
+
+void dump_tlb_addr(unsigned long addr)
+{
+	unsigned int flags, oldpid;
+	int index;
+
+	local_irq_save(flags);
+	oldpid = read_c0_entryhi() & 0xff;
+	BARRIER();
+	write_c0_entryhi((addr & PAGE_MASK) | oldpid);
+	BARRIER();
+	tlb_probe();
+	BARRIER();
+	index = read_c0_index();
+	write_c0_entryhi(oldpid);
+	local_irq_restore(flags);
+
+	if (index < 0) {
+		printk("No entry for address 0x%08lx in TLB\n", addr);
+		return;
+	}
+
+	printk("Entry %d maps address 0x%08lx\n", index, addr);
+	dump_tlb(index, index);
+}
+
+void dump_tlb_nonwired(void)
+{
+	dump_tlb(read_c0_wired(), current_cpu_data.tlbsize - 1);
+}
+
+void dump_list_process(struct task_struct *t, void *address)
+{
+	pgd_t	*page_dir, *pgd;
+	pmd_t	*pmd;
+	pte_t	*pte, page;
+	unsigned long addr, val;
+
+	addr = (unsigned long) address;
+
+	printk("Addr                 == %08lx\n", addr);
+	printk("tasks->mm.pgd        == %08lx\n", (unsigned long) t->mm->pgd);
+
+	page_dir = pgd_offset(t->mm, 0);
+	printk("page_dir == %016lx\n", (unsigned long) page_dir);
+
+	pgd = pgd_offset(t->mm, addr);
+	printk("pgd == %016lx\n", (unsigned long) pgd);
+
+	pmd = pmd_offset(pgd, addr);
+	printk("pmd == %016lx\n", (unsigned long) pmd);
+
+	pte = pte_offset(pmd, addr);
+	printk("pte == %016lx\n", (unsigned long) pte);
+
+	page = *pte;
+	printk("page == %08lx\n", pte_val(page));
+
+	val = pte_val(page);
+	if (val & _PAGE_PRESENT) printk("present ");
+	if (val & _PAGE_READ) printk("read ");
+	if (val & _PAGE_WRITE) printk("write ");
+	if (val & _PAGE_ACCESSED) printk("accessed ");
+	if (val & _PAGE_MODIFIED) printk("modified ");
+	if (val & _PAGE_R4KBUG) printk("r4kbug ");
+	if (val & _PAGE_GLOBAL) printk("global ");
+	if (val & _PAGE_VALID) printk("valid ");
+	printk("\n");
+}
+
+void dump_list_current(void *address)
+{
+	dump_list_process(current, address);
+}
+
+unsigned int vtop(void *address)
+{
+	pgd_t	*pgd;
+	pmd_t	*pmd;
+	pte_t	*pte;
+	unsigned int addr, paddr;
+
+	addr = (unsigned long) address;
+	pgd = pgd_offset(current->mm, addr);
+	pmd = pmd_offset(pgd, addr);
+	pte = pte_offset(pmd, addr);
+	paddr = (CKSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
+	paddr |= (addr & ~PAGE_MASK);
+
+	return paddr;
+}
+
+void dump16(unsigned long *p)
+{
+	int i;
+
+	for (i = 0; i < 8; i++) {
+		printk("*%08lx == %08lx, ", (unsigned long)p, *p);
+		p++;
+		printk("*%08lx == %08lx\n", (unsigned long)p, *p);
+		p++;
+	}
+}
diff --git a/arch/mips/lib-64/memset.S b/arch/mips/lib-64/memset.S
new file mode 100644
index 0000000..242f197
--- /dev/null
+++ b/arch/mips/lib-64/memset.S
@@ -0,0 +1,142 @@
+/*
+ * 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) 1998, 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <asm/asm.h>
+#include <asm/offset.h>
+#include <asm/regdef.h>
+
+#define EX(insn,reg,addr,handler)			\
+9:	insn	reg, addr;				\
+	.section __ex_table,"a"; 			\
+	PTR	9b, handler; 				\
+	.previous
+
+	.macro	f_fill64 dst, offset, val, fixup
+	EX(LONG_S, \val, (\offset +  0 * LONGSIZE)(\dst), \fixup)
+	EX(LONG_S, \val, (\offset +  1 * LONGSIZE)(\dst), \fixup)
+	EX(LONG_S, \val, (\offset +  2 * LONGSIZE)(\dst), \fixup)
+	EX(LONG_S, \val, (\offset +  3 * LONGSIZE)(\dst), \fixup)
+	EX(LONG_S, \val, (\offset +  4 * LONGSIZE)(\dst), \fixup)
+	EX(LONG_S, \val, (\offset +  5 * LONGSIZE)(\dst), \fixup)
+	EX(LONG_S, \val, (\offset +  6 * LONGSIZE)(\dst), \fixup)
+	EX(LONG_S, \val, (\offset +  7 * LONGSIZE)(\dst), \fixup)
+	.endm
+
+/*
+ * memset(void *s, int c, size_t n)
+ *
+ * a0: start of area to clear
+ * a1: char to fill with
+ * a2: size of area to clear
+ */
+	.set	noreorder
+	.align	5
+LEAF(memset)
+	beqz		a1, 1f
+	 move		v0, a0			/* result */
+
+	andi		a1, 0xff		/* spread fillword */
+	dsll		t1, a1, 8
+	or		a1, t1
+	dsll		t1, a1, 16
+	or		a1, t1
+	dsll		t1, a1, 32
+	or		a1, t1
+1:
+
+FEXPORT(__bzero)
+	sltiu		t0, a2, LONGSIZE	/* very small region? */
+	bnez		t0, small_memset
+	 andi		t0, a0, LONGMASK	/* aligned? */
+
+	beqz		t0, 1f
+	 PTR_SUBU	t0, LONGSIZE		/* alignment in bytes */
+
+#ifdef __MIPSEB__
+	EX(sdl, a1, (a0), first_fixup)		/* make dword aligned */
+#endif
+#ifdef __MIPSEL__
+	EX(sdr, a1, (a0), first_fixup)		/* make dword aligned */
+#endif
+	PTR_SUBU	a0, t0			/* long align ptr */
+	PTR_ADDU	a2, t0			/* correct size */
+
+1:	ori		t1, a2, 0x3f		/* # of full blocks */
+	xori		t1, 0x3f
+	beqz		t1, memset_partial	/* no block to fill */
+	 andi		t0, a2, 0x38
+
+	PTR_ADDU	t1, a0			/* end address */
+	.set		reorder
+1:	PTR_ADDIU	a0, 64
+	f_fill64 a0, -64, a1, fwd_fixup
+	bne		t1, a0, 1b
+	.set		noreorder
+
+memset_partial:
+	PTR_LA		t1, 2f			/* where to start */
+	.set		noat
+	dsrl		AT, t0, 1
+	PTR_SUBU	t1, AT
+	.set		noat
+	jr		t1
+	 PTR_ADDU	a0, t0			/* dest ptr */
+
+	.set		push
+	.set		noreorder
+	.set		nomacro
+	f_fill64 a0, -64, a1, partial_fixup	/* ... but first do longs ... */
+2:	.set		pop
+	andi		a2, LONGMASK		/* At most one long to go */
+
+	beqz		a2, 1f
+	 PTR_ADDU	a0, a2			/* What's left */
+#ifdef __MIPSEB__
+	EX(sdr, a1, -1(a0), last_fixup)
+#endif
+#ifdef __MIPSEL__
+	EX(sdl, a1, -1(a0), last_fixup)
+#endif
+1:	jr		ra
+	 move		a2, zero
+
+small_memset:
+	beqz		a2, 2f
+	 PTR_ADDU	t1, a0, a2
+
+1:	PTR_ADDIU	a0, 1			/* fill bytewise */
+	bne		t1, a0, 1b
+	 sb		a1, -1(a0)
+
+2:	jr		ra			/* done */
+	 move		a2, zero
+	END(memset)
+
+first_fixup:
+	jr	ra
+	 nop
+
+fwd_fixup:
+	PTR_L		t0, TI_TASK($28)
+	LONG_L		t0, THREAD_BUADDR(t0)
+	andi		a2, 0x3f
+	LONG_ADDU	a2, t1
+	jr		ra
+	 LONG_SUBU	a2, t0
+
+partial_fixup:
+	PTR_L		t0, TI_TASK($28)
+	LONG_L		t0, THREAD_BUADDR(t0)
+	andi		a2, LONGMASK
+	LONG_ADDU	a2, t1
+	jr		ra
+	 LONG_SUBU	a2, t0
+
+last_fixup:
+	jr		ra
+	 andi		v1, a2, LONGMASK
diff --git a/arch/mips/lib-64/watch.S b/arch/mips/lib-64/watch.S
new file mode 100644
index 0000000..f914340
--- /dev/null
+++ b/arch/mips/lib-64/watch.S
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ *
+ * Kernel debug stuff to use the Watch registers.
+ * Useful to find stack overflows, dangling pointers etc.
+ *
+ * Copyright (C) 1995, 1996, 1999, 2001 by Ralf Baechle
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+
+		.set	noreorder
+/*
+ * Parameter: a0 - physical address to watch
+ *            a1 - set bit #1 to trap on load references
+ *                     bit #0 to trap on store references
+ * Results  : none
+ */
+		LEAF(__watch_set)
+		ori	a0, 7
+		xori	a0, 7
+		or	a0, a1
+		mtc0	a0, CP0_WATCHLO
+		sd	a0, watch_savelo
+		dsrl32	a0, a0, 0
+
+		jr	ra
+		 mtc0	zero, CP0_WATCHHI
+		END(__watch_set)
+
+/*
+ * Parameter: none
+ * Results  : none
+ */
+		LEAF(__watch_clear)
+		jr	ra
+		 mtc0	zero, CP0_WATCHLO
+		END(__watch_clear)
+
+/*
+ * Parameter: none
+ * Results  : none
+ */
+		LEAF(__watch_reenable)
+		ld	t0, watch_savelo
+		jr	ra
+		 mtc0	t0, CP0_WATCHLO
+		END(__watch_reenable)
+
+/*
+ * Saved value of the c0_watchlo register for watch_reenable()
+ */
+		.local	watch_savelo
+		.comm	watch_savelo, 8, 8
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
new file mode 100644
index 0000000..21b92b9
--- /dev/null
+++ b/arch/mips/lib/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for MIPS-specific library files..
+#
+
+lib-y	+= csum_partial_copy.o dec_and_lock.o memcpy.o promlib.o \
+	   strlen_user.o strncpy_user.o strnlen_user.o
+
+obj-y	+= iomap.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/lib/csum_partial_copy.c b/arch/mips/lib/csum_partial_copy.c
new file mode 100644
index 0000000..ffed0a6
--- /dev/null
+++ b/arch/mips/lib/csum_partial_copy.c
@@ -0,0 +1,49 @@
+/*
+ * 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) 1994, 1995 Waldorf Electronics GmbH
+ * Copyright (C) 1998, 1999 Ralf Baechle
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <asm/byteorder.h>
+#include <asm/string.h>
+#include <asm/uaccess.h>
+#include <net/checksum.h>
+
+/*
+ * copy while checksumming, otherwise like csum_partial
+ */
+unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst,
+	int len, unsigned int sum)
+{
+	/*
+	 * It's 2:30 am and I don't feel like doing it real ...
+	 * This is lots slower than the real thing (tm)
+	 */
+	sum = csum_partial(src, len, sum);
+	memcpy(dst, src, len);
+
+	return sum;
+}
+
+/*
+ * Copy from userspace and compute checksum.  If we catch an exception
+ * then zero the rest of the buffer.
+ */
+unsigned int csum_partial_copy_from_user (const unsigned char *src, unsigned char *dst,
+	int len, unsigned int sum, int *err_ptr)
+{
+	int missing;
+
+	might_sleep();
+	missing = copy_from_user(dst, src, len);
+	if (missing) {
+		memset(dst + len - missing, 0, missing);
+		*err_ptr = -EFAULT;
+	}
+
+	return csum_partial(dst, len, sum);
+}
diff --git a/arch/mips/lib/dec_and_lock.c b/arch/mips/lib/dec_and_lock.c
new file mode 100644
index 0000000..e44e957
--- /dev/null
+++ b/arch/mips/lib/dec_and_lock.c
@@ -0,0 +1,55 @@
+/*
+ * MIPS version of atomic_dec_and_lock() using cmpxchg
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <asm/atomic.h>
+#include <asm/system.h>
+
+/*
+ * This is an implementation of the notion of "decrement a
+ * reference count, and return locked if it decremented to zero".
+ *
+ * This implementation can be used on any architecture that
+ * has a cmpxchg, and where atomic->value is an int holding
+ * the value of the atomic (i.e. the high bits aren't used
+ * for a lock or anything like that).
+ *
+ * N.B. ATOMIC_DEC_AND_LOCK gets defined in include/linux/spinlock.h
+ * if spinlocks are empty and thus atomic_dec_and_lock is defined
+ * to be atomic_dec_and_test - in that case we don't need it
+ * defined here as well.
+ */
+
+#ifndef ATOMIC_DEC_AND_LOCK
+int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
+{
+	int counter;
+	int newcount;
+
+	for (;;) {
+		counter = atomic_read(atomic);
+		newcount = counter - 1;
+		if (!newcount)
+			break;		/* do it the slow way */
+
+		newcount = cmpxchg(&atomic->counter, counter, newcount);
+		if (newcount == counter)
+			return 0;
+	}
+
+	spin_lock(lock);
+	if (atomic_dec_and_test(atomic))
+		return 1;
+	spin_unlock(lock);
+	return 0;
+}
+
+EXPORT_SYMBOL(_atomic_dec_and_lock);
+#endif /* ATOMIC_DEC_AND_LOCK */
diff --git a/arch/mips/lib/iomap.c b/arch/mips/lib/iomap.c
new file mode 100644
index 0000000..b5d5fa8
--- /dev/null
+++ b/arch/mips/lib/iomap.c
@@ -0,0 +1,78 @@
+/*
+ *  iomap.c, Memory Mapped I/O routines for MIPS architecture.
+ *
+ *  This code is based on lib/iomap.c, by Linus Torvalds.
+ *
+ *  Copyright (C) 2004-2005  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+
+#include <asm/io.h>
+
+void __iomem *ioport_map(unsigned long port, unsigned int nr)
+{
+	unsigned long end;
+
+	end = port + nr - 1UL;
+	if (ioport_resource.start > port ||
+	    ioport_resource.end < end || port > end)
+		return NULL;
+
+	return (void __iomem *)(mips_io_port_base + port);
+}
+
+void ioport_unmap(void __iomem *addr)
+{
+}
+EXPORT_SYMBOL(ioport_map);
+EXPORT_SYMBOL(ioport_unmap);
+
+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
+{
+	unsigned long start, len, flags;
+
+	if (dev == NULL)
+		return NULL;
+
+	start = pci_resource_start(dev, bar);
+	len = pci_resource_len(dev, bar);
+	if (!start || !len)
+		return NULL;
+
+	if (maxlen != 0 && len > maxlen)
+		len = maxlen;
+
+	flags = pci_resource_flags(dev, bar);
+	if (flags & IORESOURCE_IO)
+		return ioport_map(start, len);
+	if (flags & IORESOURCE_MEM) {
+		if (flags & IORESOURCE_CACHEABLE)
+			return ioremap_cacheable_cow(start, len);
+		return ioremap_nocache(start, len);
+	}
+
+	return NULL;
+}
+
+void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
+{
+	iounmap(addr);
+}
+EXPORT_SYMBOL(pci_iomap);
+EXPORT_SYMBOL(pci_iounmap);
diff --git a/arch/mips/lib/memcpy.S b/arch/mips/lib/memcpy.S
new file mode 100644
index 0000000..afa8eae
--- /dev/null
+++ b/arch/mips/lib/memcpy.S
@@ -0,0 +1,508 @@
+/*
+ * 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.
+ *
+ * Unified implementation of memcpy, memmove and the __copy_user backend.
+ *
+ * Copyright (C) 1998, 99, 2000, 01, 2002 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc.
+ * Copyright (C) 2002 Broadcom, Inc.
+ *   memcpy/copy_user author: Mark Vandevoorde
+ *
+ * Mnemonic names for arguments to memcpy/__copy_user
+ */
+#include <linux/config.h>
+#include <asm/asm.h>
+#include <asm/offset.h>
+#include <asm/regdef.h>
+
+#define dst a0
+#define src a1
+#define len a2
+
+/*
+ * Spec
+ *
+ * memcpy copies len bytes from src to dst and sets v0 to dst.
+ * It assumes that
+ *   - src and dst don't overlap
+ *   - src is readable
+ *   - dst is writable
+ * memcpy uses the standard calling convention
+ *
+ * __copy_user copies up to len bytes from src to dst and sets a2 (len) to
+ * the number of uncopied bytes due to an exception caused by a read or write.
+ * __copy_user assumes that src and dst don't overlap, and that the call is
+ * implementing one of the following:
+ *   copy_to_user
+ *     - src is readable  (no exceptions when reading src)
+ *   copy_from_user
+ *     - dst is writable  (no exceptions when writing dst)
+ * __copy_user uses a non-standard calling convention; see
+ * include/asm-mips/uaccess.h
+ *
+ * When an exception happens on a load, the handler must
+ # ensure that all of the destination buffer is overwritten to prevent
+ * leaking information to user mode programs.
+ */
+
+/*
+ * Implementation
+ */
+
+/*
+ * The exception handler for loads requires that:
+ *  1- AT contain the address of the byte just past the end of the source
+ *     of the copy,
+ *  2- src_entry <= src < AT, and
+ *  3- (dst - src) == (dst_entry - src_entry),
+ * The _entry suffix denotes values when __copy_user was called.
+ *
+ * (1) is set up up by uaccess.h and maintained by not writing AT in copy_user
+ * (2) is met by incrementing src by the number of bytes copied
+ * (3) is met by not doing loads between a pair of increments of dst and src
+ *
+ * The exception handlers for stores adjust len (if necessary) and return.
+ * These handlers do not need to overwrite any data.
+ *
+ * For __rmemcpy and memmove an exception is always a kernel bug, therefore
+ * they're not protected.
+ */
+
+#define EXC(inst_reg,addr,handler)		\
+9:	inst_reg, addr;				\
+	.section __ex_table,"a";		\
+	PTR	9b, handler;			\
+	.previous
+
+/*
+ * Only on the 64-bit kernel we can made use of 64-bit registers.
+ */
+#ifdef CONFIG_MIPS64
+#define USE_DOUBLE
+#endif
+
+#ifdef USE_DOUBLE
+
+#define LOAD   ld
+#define LOADL  ldl
+#define LOADR  ldr
+#define STOREL sdl
+#define STORER sdr
+#define STORE  sd
+#define ADD    daddu
+#define SUB    dsubu
+#define SRL    dsrl
+#define SRA    dsra
+#define SLL    dsll
+#define SLLV   dsllv
+#define SRLV   dsrlv
+#define NBYTES 8
+#define LOG_NBYTES 3
+
+/* 
+ * As we are sharing code base with the mips32 tree (which use the o32 ABI
+ * register definitions). We need to redefine the register definitions from
+ * the n64 ABI register naming to the o32 ABI register naming.
+ */
+#undef t0
+#undef t1
+#undef t2
+#undef t3
+#define t0	$8
+#define t1	$9
+#define t2	$10
+#define t3	$11
+#define t4	$12
+#define t5	$13
+#define t6	$14
+#define t7	$15
+	
+#else
+
+#define LOAD   lw
+#define LOADL  lwl
+#define LOADR  lwr
+#define STOREL swl
+#define STORER swr
+#define STORE  sw
+#define ADD    addu
+#define SUB    subu
+#define SRL    srl
+#define SLL    sll
+#define SRA    sra
+#define SLLV   sllv
+#define SRLV   srlv
+#define NBYTES 4
+#define LOG_NBYTES 2
+
+#endif /* USE_DOUBLE */
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+#define LDFIRST LOADR
+#define LDREST  LOADL
+#define STFIRST STORER
+#define STREST  STOREL
+#define SHIFT_DISCARD SLLV
+#else
+#define LDFIRST LOADL
+#define LDREST  LOADR
+#define STFIRST STOREL
+#define STREST  STORER
+#define SHIFT_DISCARD SRLV
+#endif
+
+#define FIRST(unit) ((unit)*NBYTES)
+#define REST(unit)  (FIRST(unit)+NBYTES-1)
+#define UNIT(unit)  FIRST(unit)
+
+#define ADDRMASK (NBYTES-1)
+
+	.text
+	.set	noreorder
+	.set	noat
+
+/*
+ * A combined memcpy/__copy_user
+ * __copy_user sets len to 0 for success; else to an upper bound of
+ * the number of uncopied bytes.
+ * memcpy sets v0 to dst.
+ */
+	.align	5
+LEAF(memcpy)					/* a0=dst a1=src a2=len */
+	move	v0, dst				/* return value */
+__memcpy:
+FEXPORT(__copy_user)
+	/*
+	 * Note: dst & src may be unaligned, len may be 0
+	 * Temps
+	 */
+#define rem t8
+
+	/*
+	 * The "issue break"s below are very approximate.
+	 * Issue delays for dcache fills will perturb the schedule, as will
+	 * load queue full replay traps, etc.
+	 *
+	 * If len < NBYTES use byte operations.
+	 */
+	PREF(	0, 0(src) )
+	PREF(	1, 0(dst) )
+	sltu	t2, len, NBYTES
+	and	t1, dst, ADDRMASK
+	PREF(	0, 1*32(src) )
+	PREF(	1, 1*32(dst) )
+	bnez	t2, copy_bytes_checklen
+	 and	t0, src, ADDRMASK
+	PREF(	0, 2*32(src) )
+	PREF(	1, 2*32(dst) )
+	bnez	t1, dst_unaligned
+	 nop
+	bnez	t0, src_unaligned_dst_aligned
+	/*
+	 * use delay slot for fall-through
+	 * src and dst are aligned; need to compute rem
+	 */
+both_aligned:
+	 SRL	t0, len, LOG_NBYTES+3    # +3 for 8 units/iter
+	beqz	t0, cleanup_both_aligned # len < 8*NBYTES
+	 and	rem, len, (8*NBYTES-1)	 # rem = len % (8*NBYTES)
+	PREF(	0, 3*32(src) )
+	PREF(	1, 3*32(dst) )
+	.align	4
+1:
+EXC(	LOAD	t0, UNIT(0)(src),	l_exc)
+EXC(	LOAD	t1, UNIT(1)(src),	l_exc_copy)
+EXC(	LOAD	t2, UNIT(2)(src),	l_exc_copy)
+EXC(	LOAD	t3, UNIT(3)(src),	l_exc_copy)
+	SUB	len, len, 8*NBYTES
+EXC(	LOAD	t4, UNIT(4)(src),	l_exc_copy)
+EXC(	LOAD	t7, UNIT(5)(src),	l_exc_copy)
+EXC(	STORE	t0, UNIT(0)(dst),	s_exc_p8u)
+EXC(	STORE	t1, UNIT(1)(dst),	s_exc_p7u)
+EXC(	LOAD	t0, UNIT(6)(src),	l_exc_copy)
+EXC(	LOAD	t1, UNIT(7)(src),	l_exc_copy)
+	ADD	src, src, 8*NBYTES
+	ADD	dst, dst, 8*NBYTES
+EXC(	STORE	t2, UNIT(-6)(dst),	s_exc_p6u)
+EXC(	STORE	t3, UNIT(-5)(dst),	s_exc_p5u)
+EXC(	STORE	t4, UNIT(-4)(dst),	s_exc_p4u)
+EXC(	STORE	t7, UNIT(-3)(dst),	s_exc_p3u)
+EXC(	STORE	t0, UNIT(-2)(dst),	s_exc_p2u)
+EXC(	STORE	t1, UNIT(-1)(dst),	s_exc_p1u)
+	PREF(	0, 8*32(src) )
+	PREF(	1, 8*32(dst) )
+	bne	len, rem, 1b
+	 nop
+
+	/*
+	 * len == rem == the number of bytes left to copy < 8*NBYTES
+	 */
+cleanup_both_aligned:
+	beqz	len, done
+	 sltu	t0, len, 4*NBYTES
+	bnez	t0, less_than_4units
+	 and	rem, len, (NBYTES-1)	# rem = len % NBYTES
+	/*
+	 * len >= 4*NBYTES
+	 */
+EXC(	LOAD	t0, UNIT(0)(src),	l_exc)
+EXC(	LOAD	t1, UNIT(1)(src),	l_exc_copy)
+EXC(	LOAD	t2, UNIT(2)(src),	l_exc_copy)
+EXC(	LOAD	t3, UNIT(3)(src),	l_exc_copy)
+	SUB	len, len, 4*NBYTES
+	ADD	src, src, 4*NBYTES
+EXC(	STORE	t0, UNIT(0)(dst),	s_exc_p4u)
+EXC(	STORE	t1, UNIT(1)(dst),	s_exc_p3u)
+EXC(	STORE	t2, UNIT(2)(dst),	s_exc_p2u)
+EXC(	STORE	t3, UNIT(3)(dst),	s_exc_p1u)
+	beqz	len, done
+	 ADD	dst, dst, 4*NBYTES
+less_than_4units:
+	/*
+	 * rem = len % NBYTES
+	 */
+	beq	rem, len, copy_bytes
+	 nop
+1:
+EXC(	LOAD	t0, 0(src),		l_exc)
+	ADD	src, src, NBYTES
+	SUB	len, len, NBYTES
+EXC(	STORE	t0, 0(dst),		s_exc_p1u)
+	bne	rem, len, 1b
+	 ADD	dst, dst, NBYTES
+
+	/*
+	 * src and dst are aligned, need to copy rem bytes (rem < NBYTES)
+	 * A loop would do only a byte at a time with possible branch
+	 * mispredicts.  Can't do an explicit LOAD dst,mask,or,STORE
+	 * because can't assume read-access to dst.  Instead, use
+	 * STREST dst, which doesn't require read access to dst.
+	 *
+	 * This code should perform better than a simple loop on modern,
+	 * wide-issue mips processors because the code has fewer branches and
+	 * more instruction-level parallelism.
+	 */
+#define bits t2
+	beqz	len, done
+	 ADD	t1, dst, len	# t1 is just past last byte of dst
+	li	bits, 8*NBYTES
+	SLL	rem, len, 3	# rem = number of bits to keep
+EXC(	LOAD	t0, 0(src),		l_exc)
+	SUB	bits, bits, rem	# bits = number of bits to discard
+	SHIFT_DISCARD t0, t0, bits
+EXC(	STREST	t0, -1(t1),		s_exc)
+	jr	ra
+	 move	len, zero
+dst_unaligned:
+	/*
+	 * dst is unaligned
+	 * t0 = src & ADDRMASK
+	 * t1 = dst & ADDRMASK; T1 > 0
+	 * len >= NBYTES
+	 *
+	 * Copy enough bytes to align dst
+	 * Set match = (src and dst have same alignment)
+	 */
+#define match rem
+EXC(	LDFIRST	t3, FIRST(0)(src),	l_exc)
+	ADD	t2, zero, NBYTES
+EXC(	LDREST	t3, REST(0)(src),	l_exc_copy)
+	SUB	t2, t2, t1	# t2 = number of bytes copied
+	xor	match, t0, t1
+EXC(	STFIRST t3, FIRST(0)(dst),	s_exc)
+	beq	len, t2, done
+	 SUB	len, len, t2
+	ADD	dst, dst, t2
+	beqz	match, both_aligned
+	 ADD	src, src, t2
+
+src_unaligned_dst_aligned:
+	SRL	t0, len, LOG_NBYTES+2    # +2 for 4 units/iter
+	PREF(	0, 3*32(src) )
+	beqz	t0, cleanup_src_unaligned
+	 and	rem, len, (4*NBYTES-1)   # rem = len % 4*NBYTES
+	PREF(	1, 3*32(dst) )
+1:
+/*
+ * Avoid consecutive LD*'s to the same register since some mips
+ * implementations can't issue them in the same cycle.
+ * It's OK to load FIRST(N+1) before REST(N) because the two addresses
+ * are to the same unit (unless src is aligned, but it's not).
+ */
+EXC(	LDFIRST	t0, FIRST(0)(src),	l_exc)
+EXC(	LDFIRST	t1, FIRST(1)(src),	l_exc_copy)
+	SUB     len, len, 4*NBYTES
+EXC(	LDREST	t0, REST(0)(src),	l_exc_copy)
+EXC(	LDREST	t1, REST(1)(src),	l_exc_copy)
+EXC(	LDFIRST	t2, FIRST(2)(src),	l_exc_copy)
+EXC(	LDFIRST	t3, FIRST(3)(src),	l_exc_copy)
+EXC(	LDREST	t2, REST(2)(src),	l_exc_copy)
+EXC(	LDREST	t3, REST(3)(src),	l_exc_copy)
+	PREF(	0, 9*32(src) )		# 0 is PREF_LOAD  (not streamed)
+	ADD	src, src, 4*NBYTES
+#ifdef CONFIG_CPU_SB1
+	nop				# improves slotting
+#endif
+EXC(	STORE	t0, UNIT(0)(dst),	s_exc_p4u)
+EXC(	STORE	t1, UNIT(1)(dst),	s_exc_p3u)
+EXC(	STORE	t2, UNIT(2)(dst),	s_exc_p2u)
+EXC(	STORE	t3, UNIT(3)(dst),	s_exc_p1u)
+	PREF(	1, 9*32(dst) )     	# 1 is PREF_STORE (not streamed)
+	bne	len, rem, 1b
+	 ADD	dst, dst, 4*NBYTES
+
+cleanup_src_unaligned:
+	beqz	len, done
+	 and	rem, len, NBYTES-1  # rem = len % NBYTES
+	beq	rem, len, copy_bytes
+	 nop
+1:
+EXC(	LDFIRST t0, FIRST(0)(src),	l_exc)
+EXC(	LDREST	t0, REST(0)(src),	l_exc_copy)
+	ADD	src, src, NBYTES
+	SUB	len, len, NBYTES
+EXC(	STORE	t0, 0(dst),		s_exc_p1u)
+	bne	len, rem, 1b
+	 ADD	dst, dst, NBYTES
+
+copy_bytes_checklen:
+	beqz	len, done
+	 nop
+copy_bytes:
+	/* 0 < len < NBYTES  */
+#define COPY_BYTE(N)			\
+EXC(	lb	t0, N(src), l_exc);	\
+	SUB	len, len, 1;		\
+	beqz	len, done;		\
+EXC(	 sb	t0, N(dst), s_exc_p1)
+
+	COPY_BYTE(0)
+	COPY_BYTE(1)
+#ifdef USE_DOUBLE
+	COPY_BYTE(2)
+	COPY_BYTE(3)
+	COPY_BYTE(4)
+	COPY_BYTE(5)
+#endif
+EXC(	lb	t0, NBYTES-2(src), l_exc)
+	SUB	len, len, 1
+	jr	ra
+EXC(	 sb	t0, NBYTES-2(dst), s_exc_p1)
+done:
+	jr	ra
+	 nop
+	END(memcpy)
+
+l_exc_copy:
+	/*
+	 * Copy bytes from src until faulting load address (or until a
+	 * lb faults)
+	 *
+	 * When reached by a faulting LDFIRST/LDREST, THREAD_BUADDR($28)
+	 * may be more than a byte beyond the last address.
+	 * Hence, the lb below may get an exception.
+	 *
+	 * Assumes src < THREAD_BUADDR($28)
+	 */
+	LOAD	t0, TI_TASK($28)
+	 nop
+	LOAD	t0, THREAD_BUADDR(t0)
+1:
+EXC(	lb	t1, 0(src),	l_exc)
+	ADD	src, src, 1
+	sb	t1, 0(dst)	# can't fault -- we're copy_from_user
+	bne	src, t0, 1b
+	 ADD	dst, dst, 1
+l_exc:
+	LOAD	t0, TI_TASK($28)
+	 nop
+	LOAD	t0, THREAD_BUADDR(t0)	# t0 is just past last good address
+	 nop
+	SUB	len, AT, t0		# len number of uncopied bytes
+	/*
+	 * Here's where we rely on src and dst being incremented in tandem,
+	 *   See (3) above.
+	 * dst += (fault addr - src) to put dst at first byte to clear
+	 */
+	ADD	dst, t0			# compute start address in a1
+	SUB	dst, src
+	/*
+	 * Clear len bytes starting at dst.  Can't call __bzero because it
+	 * might modify len.  An inefficient loop for these rare times...
+	 */
+	beqz	len, done
+	 SUB	src, len, 1
+1:	sb	zero, 0(dst)
+	ADD	dst, dst, 1
+	bnez	src, 1b
+	 SUB	src, src, 1
+	jr	ra
+	 nop
+
+
+#define SEXC(n)				\
+s_exc_p ## n ## u:			\
+	jr	ra;			\
+	 ADD	len, len, n*NBYTES
+
+SEXC(8)
+SEXC(7)
+SEXC(6)
+SEXC(5)
+SEXC(4)
+SEXC(3)
+SEXC(2)
+SEXC(1)
+
+s_exc_p1:
+	jr	ra
+	 ADD	len, len, 1
+s_exc:
+	jr	ra
+	 nop
+
+	.align	5
+LEAF(memmove)
+	ADD	t0, a0, a2
+	ADD	t1, a1, a2
+	sltu	t0, a1, t0			# dst + len <= src -> memcpy
+	sltu	t1, a0, t1			# dst >= src + len -> memcpy
+	and	t0, t1
+	beqz	t0, __memcpy
+	 move	v0, a0				/* return value */
+	beqz	a2, r_out
+	END(memmove)
+
+	/* fall through to __rmemcpy */
+LEAF(__rmemcpy)					/* a0=dst a1=src a2=len */
+	 sltu	t0, a1, a0
+	beqz	t0, r_end_bytes_up		# src >= dst
+	 nop
+	ADD	a0, a2				# dst = dst + len
+	ADD	a1, a2				# src = src + len
+
+r_end_bytes:
+	lb	t0, -1(a1)
+	SUB	a2, a2, 0x1
+	sb	t0, -1(a0)
+	SUB	a1, a1, 0x1
+	bnez	a2, r_end_bytes
+	 SUB	a0, a0, 0x1
+
+r_out:
+	jr	ra
+	 move	a2, zero
+
+r_end_bytes_up:
+	lb	t0, (a1)
+	SUB	a2, a2, 0x1
+	sb	t0, (a0)
+	ADD	a1, a1, 0x1
+	bnez	a2, r_end_bytes_up
+	 ADD	a0, a0, 0x1
+
+	jr	ra
+	 move	a2, zero
+	END(__rmemcpy)
diff --git a/arch/mips/lib/promlib.c b/arch/mips/lib/promlib.c
new file mode 100644
index 0000000..dddfe98
--- /dev/null
+++ b/arch/mips/lib/promlib.c
@@ -0,0 +1,24 @@
+#include <stdarg.h>
+#include <linux/kernel.h>
+
+extern void prom_putchar(char);
+
+void prom_printf(char *fmt, ...)
+{
+	va_list args;
+	char ppbuf[1024];
+	char *bptr;
+
+	va_start(args, fmt);
+	vsprintf(ppbuf, fmt, args);
+
+	bptr = ppbuf;
+
+	while (*bptr != 0) {
+		if (*bptr == '\n')
+			prom_putchar('\r');
+
+		prom_putchar(*bptr++);
+	}
+	va_end(args);
+}
diff --git a/arch/mips/lib/strlen_user.S b/arch/mips/lib/strlen_user.S
new file mode 100644
index 0000000..07660e8
--- /dev/null
+++ b/arch/mips/lib/strlen_user.S
@@ -0,0 +1,39 @@
+/*
+ * 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) 1996, 1998, 1999, 2004 by Ralf Baechle
+ * Copyright (c) 1999 Silicon Graphics, Inc.
+ */
+#include <asm/asm.h>
+#include <asm/offset.h>
+#include <asm/regdef.h>
+
+#define EX(insn,reg,addr,handler)			\
+9:	insn	reg, addr;				\
+	.section __ex_table,"a";			\
+	PTR	9b, handler;				\
+	.previous
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 for error
+ */
+LEAF(__strlen_user_asm)
+	LONG_L		v0, TI_ADDR_LIMIT($28)	# pointer ok?
+	and		v0, a0
+	bnez		v0, fault
+
+FEXPORT(__strlen_user_nocheck_asm)
+	move		v0, a0
+1:	EX(lb, t0, (v0), fault)
+	PTR_ADDIU	v0, 1
+	bnez		t0, 1b
+	PTR_SUBU	v0, a0
+	jr		ra
+	END(__strlen_user_asm)
+
+fault:	move		v0, zero
+	jr		ra
diff --git a/arch/mips/lib/strncpy_user.S b/arch/mips/lib/strncpy_user.S
new file mode 100644
index 0000000..14bed17
--- /dev/null
+++ b/arch/mips/lib/strncpy_user.S
@@ -0,0 +1,58 @@
+/*
+ * 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) 1996, 1999 by Ralf Baechle
+ */
+#include <linux/errno.h>
+#include <asm/asm.h>
+#include <asm/offset.h>
+#include <asm/regdef.h>
+
+#define EX(insn,reg,addr,handler)			\
+9:	insn	reg, addr;				\
+	.section __ex_table,"a";			\
+	PTR	9b, handler;				\
+	.previous
+
+/*
+ * Returns: -EFAULT if exception before terminator, N if the entire
+ * buffer filled, else strlen.
+ */
+
+/*
+ * Ugly special case have to check: we might get passed a user space
+ * pointer which wraps into the kernel space.  We don't deal with that.  If
+ * it happens at most some bytes of the exceptions handlers will be copied.
+ */
+
+LEAF(__strncpy_from_user_asm)
+	LONG_L		v0, TI_ADDR_LIMIT($28)	# pointer ok?
+	and		v0, a1
+	bnez		v0, fault
+
+FEXPORT(__strncpy_from_user_nocheck_asm)
+	move		v0, zero
+	move		v1, a1
+	.set		noreorder
+1:	EX(lbu, t0, (v1), fault)
+	PTR_ADDIU	v1, 1
+	beqz		t0, 2f
+	 sb		t0, (a0)
+	PTR_ADDIU	v0, 1
+	bne		v0, a2, 1b
+	 PTR_ADDIU	a0, 1
+	.set		reorder
+2:	PTR_ADDU	t0, a1, v0
+	xor		t0, a1
+	bltz		t0, fault
+	jr		ra			# return n
+	END(__strncpy_from_user_asm)
+
+fault:	li		v0, -EFAULT
+	jr		ra
+
+	.section	__ex_table,"a"
+	PTR		1b, fault
+	.previous
diff --git a/arch/mips/lib/strnlen_user.S b/arch/mips/lib/strnlen_user.S
new file mode 100644
index 0000000..6e7a8ee
--- /dev/null
+++ b/arch/mips/lib/strnlen_user.S
@@ -0,0 +1,45 @@
+/*
+ * 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) 1996, 1998, 1999, 2004 by Ralf Baechle
+ * Copyright (c) 1999 Silicon Graphics, Inc.
+ */
+#include <asm/asm.h>
+#include <asm/offset.h>
+#include <asm/regdef.h>
+
+#define EX(insn,reg,addr,handler)			\
+9:	insn	reg, addr;				\
+	.section __ex_table,"a";			\
+	PTR	9b, handler;				\
+	.previous
+
+/*
+ * Return the size of a string including the ending NUL character upto a
+ * maximum of a1 or 0 in case of error.
+ *
+ * Note: for performance reasons we deliberately accept that a user may
+ *       make strlen_user and strnlen_user access the first few KSEG0
+ *       bytes.  There's nothing secret there.  On 64-bit accessing beyond
+ *       the maximum is a tad hairier ...
+ */
+LEAF(__strnlen_user_asm)
+	LONG_L		v0, TI_ADDR_LIMIT($28)	# pointer ok?
+	and		v0, a0
+	bnez		v0, fault
+
+FEXPORT(__strnlen_user_nocheck_asm)
+	move		v0, a0
+	PTR_ADDU	a1, a0			# stop pointer
+1:	beq		v0, a1, 1f		# limit reached?
+	EX(lb, t0, (v0), fault)
+	PTR_ADDU	v0, 1
+	bnez		t0, 1b
+1:	PTR_SUBU	v0, a0
+	jr		ra
+	END(__strnlen_user_asm)
+
+fault:	move		v0, zero
+	jr		ra
diff --git a/arch/mips/math-emu/Makefile b/arch/mips/math-emu/Makefile
new file mode 100644
index 0000000..121a848
--- /dev/null
+++ b/arch/mips/math-emu/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for the Linux/MIPS kernel FPU emulation.
+#
+
+obj-y	:= cp1emu.o ieee754m.o ieee754d.o ieee754dp.o ieee754sp.o ieee754.o \
+	   ieee754xcpt.o dp_frexp.o dp_modf.o dp_div.o dp_mul.o dp_sub.o \
+	   dp_add.o dp_fsp.o dp_cmp.o dp_logb.o dp_scalb.o dp_simple.o \
+	   dp_tint.o dp_fint.o dp_tlong.o dp_flong.o sp_frexp.o sp_modf.o \
+	   sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_logb.o \
+	   sp_scalb.o sp_simple.o sp_tint.o sp_fint.o sp_tlong.o sp_flong.o \
+	   dp_sqrt.o sp_sqrt.o kernel_linkage.o dsemul.o
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
new file mode 100644
index 0000000..20a552b
--- /dev/null
+++ b/arch/mips/math-emu/cp1emu.c
@@ -0,0 +1,1322 @@
+/*
+ * cp1emu.c: a MIPS coprocessor 1 (fpu) instruction emulator
+ *
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000  MIPS Technologies, Inc.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * A complete emulator for MIPS coprocessor 1 instructions.  This is
+ * required for #float(switch) or #float(trap), where it catches all
+ * COP1 instructions via the "CoProcessor Unusable" exception.
+ *
+ * More surprisingly it is also required for #float(ieee), to help out
+ * the hardware fpu at the boundaries of the IEEE-754 representation
+ * (denormalised values, infinities, underflow, etc).  It is made
+ * quite nasty because emulation of some non-COP1 instructions is
+ * required, e.g. in branch delay slots.
+ *
+ * Note if you know that you won't have an fpu, then you'll get much
+ * better performance by compiling with -msoft-float!
+ */
+#include <linux/sched.h>
+
+#include <asm/inst.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/cpu-features.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/signal.h>
+#include <asm/mipsregs.h>
+#include <asm/fpu_emulator.h>
+#include <asm/uaccess.h>
+#include <asm/branch.h>
+
+#include "ieee754.h"
+#include "dsemul.h"
+
+/* Strap kernel emulator for full MIPS IV emulation */
+
+#ifdef __mips
+#undef __mips
+#endif
+#define __mips 4
+
+/* Function which emulates a floating point instruction. */
+
+static int fpu_emu(struct pt_regs *, struct mips_fpu_soft_struct *,
+	mips_instruction);
+
+#if __mips >= 4 && __mips != 32
+static int fpux_emu(struct pt_regs *,
+	struct mips_fpu_soft_struct *, mips_instruction);
+#endif
+
+/* Further private data for which no space exists in mips_fpu_soft_struct */
+
+struct mips_fpu_emulator_private fpuemuprivate;
+
+/* Control registers */
+
+#define FPCREG_RID	0	/* $0  = revision id */
+#define FPCREG_CSR	31	/* $31 = csr */
+
+/* Convert Mips rounding mode (0..3) to IEEE library modes. */
+static const unsigned char ieee_rm[4] = {
+	IEEE754_RN, IEEE754_RZ, IEEE754_RU, IEEE754_RD
+};
+
+#if __mips >= 4
+/* convert condition code register number to csr bit */
+static const unsigned int fpucondbit[8] = {
+	FPU_CSR_COND0,
+	FPU_CSR_COND1,
+	FPU_CSR_COND2,
+	FPU_CSR_COND3,
+	FPU_CSR_COND4,
+	FPU_CSR_COND5,
+	FPU_CSR_COND6,
+	FPU_CSR_COND7
+};
+#endif
+
+
+/*
+ * Redundant with logic already in kernel/branch.c,
+ * embedded in compute_return_epc.  At some point,
+ * a single subroutine should be used across both
+ * modules.
+ */
+static int isBranchInstr(mips_instruction * i)
+{
+	switch (MIPSInst_OPCODE(*i)) {
+	case spec_op:
+		switch (MIPSInst_FUNC(*i)) {
+		case jalr_op:
+		case jr_op:
+			return 1;
+		}
+		break;
+
+	case bcond_op:
+		switch (MIPSInst_RT(*i)) {
+		case bltz_op:
+		case bgez_op:
+		case bltzl_op:
+		case bgezl_op:
+		case bltzal_op:
+		case bgezal_op:
+		case bltzall_op:
+		case bgezall_op:
+			return 1;
+		}
+		break;
+
+	case j_op:
+	case jal_op:
+	case jalx_op:
+	case beq_op:
+	case bne_op:
+	case blez_op:
+	case bgtz_op:
+	case beql_op:
+	case bnel_op:
+	case blezl_op:
+	case bgtzl_op:
+		return 1;
+
+	case cop0_op:
+	case cop1_op:
+	case cop2_op:
+	case cop1x_op:
+		if (MIPSInst_RS(*i) == bc_op)
+			return 1;
+		break;
+	}
+
+	return 0;
+}
+
+/*
+ * In the Linux kernel, we support selection of FPR format on the
+ * basis of the Status.FR bit.  This does imply that, if a full 32
+ * FPRs are desired, there needs to be a flip-flop that can be written
+ * to one at that bit position.  In any case, O32 MIPS ABI uses
+ * only the even FPRs (Status.FR = 0).
+ */
+
+#define CP0_STATUS_FR_SUPPORT
+
+#ifdef CP0_STATUS_FR_SUPPORT
+#define FR_BIT ST0_FR
+#else
+#define FR_BIT 0
+#endif
+
+#define SIFROMREG(si,x)	((si) = \
+			(xcp->cp0_status & FR_BIT) || !(x & 1) ? \
+			(int)ctx->fpr[x] : \
+			(int)(ctx->fpr[x & ~1] >> 32 ))
+#define SITOREG(si,x)	(ctx->fpr[x & ~((xcp->cp0_status & FR_BIT) == 0)] = \
+			(xcp->cp0_status & FR_BIT) || !(x & 1) ? \
+			ctx->fpr[x & ~1] >> 32 << 32 | (u32)(si) : \
+			ctx->fpr[x & ~1] << 32 >> 32 | (u64)(si) << 32)
+
+#define DIFROMREG(di,x)	((di) = \
+			ctx->fpr[x & ~((xcp->cp0_status & FR_BIT) == 0)])
+#define DITOREG(di,x)	(ctx->fpr[x & ~((xcp->cp0_status & FR_BIT) == 0)] \
+			= (di))
+
+#define SPFROMREG(sp,x)	SIFROMREG((sp).bits,x)
+#define SPTOREG(sp,x)	SITOREG((sp).bits,x)
+#define DPFROMREG(dp,x)	DIFROMREG((dp).bits,x)
+#define DPTOREG(dp,x)	DITOREG((dp).bits,x)
+
+/*
+ * Emulate the single floating point instruction pointed at by EPC.
+ * Two instructions if the instruction is in a branch delay slot.
+ */
+
+static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
+{
+	mips_instruction ir;
+	vaddr_t emulpc, contpc;
+	unsigned int cond;
+
+	if (get_user(ir, (mips_instruction *) xcp->cp0_epc)) {
+		fpuemuprivate.stats.errors++;
+		return SIGBUS;
+	}
+
+	/* XXX NEC Vr54xx bug workaround */
+	if ((xcp->cp0_cause & CAUSEF_BD) && !isBranchInstr(&ir))
+		xcp->cp0_cause &= ~CAUSEF_BD;
+
+	if (xcp->cp0_cause & CAUSEF_BD) {
+		/*
+		 * The instruction to be emulated is in a branch delay slot
+		 * which means that we have to  emulate the branch instruction
+		 * BEFORE we do the cop1 instruction.
+		 *
+		 * This branch could be a COP1 branch, but in that case we
+		 * would have had a trap for that instruction, and would not
+		 * come through this route.
+		 *
+		 * Linux MIPS branch emulator operates on context, updating the
+		 * cp0_epc.
+		 */
+		emulpc = REG_TO_VA(xcp->cp0_epc + 4);	/* Snapshot emulation target */
+
+		if (__compute_return_epc(xcp)) {
+#ifdef CP1DBG
+			printk("failed to emulate branch at %p\n",
+				REG_TO_VA(xcp->cp0_epc));
+#endif
+			return SIGILL;
+		}
+		if (get_user(ir, (mips_instruction *) emulpc)) {
+			fpuemuprivate.stats.errors++;
+			return SIGBUS;
+		}
+		/* __compute_return_epc() will have updated cp0_epc */
+		contpc = REG_TO_VA xcp->cp0_epc;
+		/* In order not to confuse ptrace() et al, tweak context */
+		xcp->cp0_epc = VA_TO_REG emulpc - 4;
+	}
+	else {
+		emulpc = REG_TO_VA xcp->cp0_epc;
+		contpc = REG_TO_VA(xcp->cp0_epc + 4);
+	}
+
+      emul:
+	fpuemuprivate.stats.emulated++;
+	switch (MIPSInst_OPCODE(ir)) {
+#ifndef SINGLE_ONLY_FPU
+	case ldc1_op:{
+		u64 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
+			MIPSInst_SIMM(ir));
+		u64 val;
+
+		fpuemuprivate.stats.loads++;
+		if (get_user(val, va)) {
+			fpuemuprivate.stats.errors++;
+			return SIGBUS;
+		}
+		DITOREG(val, MIPSInst_RT(ir));
+		break;
+	}
+
+	case sdc1_op:{
+		u64 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
+			MIPSInst_SIMM(ir));
+		u64 val;
+
+		fpuemuprivate.stats.stores++;
+		DIFROMREG(val, MIPSInst_RT(ir));
+		if (put_user(val, va)) {
+			fpuemuprivate.stats.errors++;
+			return SIGBUS;
+		}
+		break;
+	}
+#endif
+
+	case lwc1_op:{
+		u32 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
+			MIPSInst_SIMM(ir));
+		u32 val;
+
+		fpuemuprivate.stats.loads++;
+		if (get_user(val, va)) {
+			fpuemuprivate.stats.errors++;
+			return SIGBUS;
+		}
+#ifdef SINGLE_ONLY_FPU
+		if (MIPSInst_RT(ir) & 1) {
+			/* illegal register in single-float mode */
+			return SIGILL;
+		}
+#endif
+		SITOREG(val, MIPSInst_RT(ir));
+		break;
+	}
+
+	case swc1_op:{
+		u32 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
+			MIPSInst_SIMM(ir));
+		u32 val;
+
+		fpuemuprivate.stats.stores++;
+#ifdef SINGLE_ONLY_FPU
+		if (MIPSInst_RT(ir) & 1) {
+			/* illegal register in single-float mode */
+			return SIGILL;
+		}
+#endif
+		SIFROMREG(val, MIPSInst_RT(ir));
+		if (put_user(val, va)) {
+			fpuemuprivate.stats.errors++;
+			return SIGBUS;
+		}
+		break;
+	}
+
+	case cop1_op:
+		switch (MIPSInst_RS(ir)) {
+
+#if __mips64 && !defined(SINGLE_ONLY_FPU)
+		case dmfc_op:
+			/* copregister fs -> gpr[rt] */
+			if (MIPSInst_RT(ir) != 0) {
+				DIFROMREG(xcp->regs[MIPSInst_RT(ir)],
+					MIPSInst_RD(ir));
+			}
+			break;
+
+		case dmtc_op:
+			/* copregister fs <- rt */
+			DITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
+			break;
+#endif
+
+		case mfc_op:
+			/* copregister rd -> gpr[rt] */
+#ifdef SINGLE_ONLY_FPU
+			if (MIPSInst_RD(ir) & 1) {
+				/* illegal register in single-float mode */
+				return SIGILL;
+			}
+#endif
+			if (MIPSInst_RT(ir) != 0) {
+				SIFROMREG(xcp->regs[MIPSInst_RT(ir)],
+					MIPSInst_RD(ir));
+			}
+			break;
+
+		case mtc_op:
+			/* copregister rd <- rt */
+#ifdef SINGLE_ONLY_FPU
+			if (MIPSInst_RD(ir) & 1) {
+				/* illegal register in single-float mode */
+				return SIGILL;
+			}
+#endif
+			SITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
+			break;
+
+		case cfc_op:{
+			/* cop control register rd -> gpr[rt] */
+			u32 value;
+
+			if (ir == CP1UNDEF) {
+				return do_dsemulret(xcp);
+			}
+			if (MIPSInst_RD(ir) == FPCREG_CSR) {
+				value = ctx->fcr31;
+#ifdef CSRTRACE
+				printk("%p gpr[%d]<-csr=%08x\n",
+					REG_TO_VA(xcp->cp0_epc),
+					MIPSInst_RT(ir), value);
+#endif
+			}
+			else if (MIPSInst_RD(ir) == FPCREG_RID)
+				value = 0;
+			else
+				value = 0;
+			if (MIPSInst_RT(ir))
+				xcp->regs[MIPSInst_RT(ir)] = value;
+			break;
+		}
+
+		case ctc_op:{
+			/* copregister rd <- rt */
+			u32 value;
+
+			if (MIPSInst_RT(ir) == 0)
+				value = 0;
+			else
+				value = xcp->regs[MIPSInst_RT(ir)];
+
+			/* we only have one writable control reg
+			 */
+			if (MIPSInst_RD(ir) == FPCREG_CSR) {
+#ifdef CSRTRACE
+				printk("%p gpr[%d]->csr=%08x\n",
+					REG_TO_VA(xcp->cp0_epc),
+					MIPSInst_RT(ir), value);
+#endif
+				ctx->fcr31 = value;
+				/* copy new rounding mode and
+				   flush bit to ieee library state! */
+				ieee754_csr.nod = (ctx->fcr31 & 0x1000000) != 0;
+				ieee754_csr.rm = ieee_rm[value & 0x3];
+			}
+			if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
+				return SIGFPE;
+			}
+			break;
+		}
+
+		case bc_op:{
+			int likely = 0;
+
+			if (xcp->cp0_cause & CAUSEF_BD)
+				return SIGILL;
+
+#if __mips >= 4
+			cond = ctx->fcr31 & fpucondbit[MIPSInst_RT(ir) >> 2];
+#else
+			cond = ctx->fcr31 & FPU_CSR_COND;
+#endif
+			switch (MIPSInst_RT(ir) & 3) {
+			case bcfl_op:
+				likely = 1;
+			case bcf_op:
+				cond = !cond;
+				break;
+			case bctl_op:
+				likely = 1;
+			case bct_op:
+				break;
+			default:
+				/* thats an illegal instruction */
+				return SIGILL;
+			}
+
+			xcp->cp0_cause |= CAUSEF_BD;
+			if (cond) {
+				/* branch taken: emulate dslot
+				 * instruction
+				 */
+				xcp->cp0_epc += 4;
+				contpc = REG_TO_VA
+					(xcp->cp0_epc +
+					(MIPSInst_SIMM(ir) << 2));
+
+				if (get_user(ir, (mips_instruction *)
+						REG_TO_VA xcp->cp0_epc)) {
+					fpuemuprivate.stats.errors++;
+					return SIGBUS;
+				}
+
+				switch (MIPSInst_OPCODE(ir)) {
+				case lwc1_op:
+				case swc1_op:
+#if (__mips >= 2 || __mips64) && !defined(SINGLE_ONLY_FPU)
+				case ldc1_op:
+				case sdc1_op:
+#endif
+				case cop1_op:
+#if __mips >= 4 && __mips != 32
+				case cop1x_op:
+#endif
+					/* its one of ours */
+					goto emul;
+#if __mips >= 4
+				case spec_op:
+					if (MIPSInst_FUNC(ir) == movc_op)
+						goto emul;
+					break;
+#endif
+				}
+
+				/*
+				 * Single step the non-cp1
+				 * instruction in the dslot
+				 */
+				return mips_dsemul(xcp, ir, VA_TO_REG contpc);
+			}
+			else {
+				/* branch not taken */
+				if (likely) {
+					/*
+					 * branch likely nullifies
+					 * dslot if not taken
+					 */
+					xcp->cp0_epc += 4;
+					contpc += 4;
+					/*
+					 * else continue & execute
+					 * dslot as normal insn
+					 */
+				}
+			}
+			break;
+		}
+
+		default:
+			if (!(MIPSInst_RS(ir) & 0x10))
+				return SIGILL;
+			{
+				int sig;
+
+				/* a real fpu computation instruction */
+				if ((sig = fpu_emu(xcp, ctx, ir)))
+					return sig;
+			}
+		}
+		break;
+
+#if __mips >= 4 && __mips != 32
+	case cop1x_op:{
+		int sig;
+
+		if ((sig = fpux_emu(xcp, ctx, ir)))
+			return sig;
+		break;
+	}
+#endif
+
+#if __mips >= 4
+	case spec_op:
+		if (MIPSInst_FUNC(ir) != movc_op)
+			return SIGILL;
+		cond = fpucondbit[MIPSInst_RT(ir) >> 2];
+		if (((ctx->fcr31 & cond) != 0) == ((MIPSInst_RT(ir) & 1) != 0))
+			xcp->regs[MIPSInst_RD(ir)] =
+				xcp->regs[MIPSInst_RS(ir)];
+		break;
+#endif
+
+	default:
+		return SIGILL;
+	}
+
+	/* we did it !! */
+	xcp->cp0_epc = VA_TO_REG(contpc);
+	xcp->cp0_cause &= ~CAUSEF_BD;
+	return 0;
+}
+
+/*
+ * Conversion table from MIPS compare ops 48-63
+ * cond = ieee754dp_cmp(x,y,IEEE754_UN,sig);
+ */
+static const unsigned char cmptab[8] = {
+	0,			/* cmp_0 (sig) cmp_sf */
+	IEEE754_CUN,		/* cmp_un (sig) cmp_ngle */
+	IEEE754_CEQ,		/* cmp_eq (sig) cmp_seq */
+	IEEE754_CEQ | IEEE754_CUN,	/* cmp_ueq (sig) cmp_ngl  */
+	IEEE754_CLT,		/* cmp_olt (sig) cmp_lt */
+	IEEE754_CLT | IEEE754_CUN,	/* cmp_ult (sig) cmp_nge */
+	IEEE754_CLT | IEEE754_CEQ,	/* cmp_ole (sig) cmp_le */
+	IEEE754_CLT | IEEE754_CEQ | IEEE754_CUN,	/* cmp_ule (sig) cmp_ngt */
+};
+
+
+#if __mips >= 4 && __mips != 32
+
+/*
+ * Additional MIPS4 instructions
+ */
+
+#define DEF3OP(name, p, f1, f2, f3) \
+static ieee754##p fpemu_##p##_##name (ieee754##p r, ieee754##p s, \
+    ieee754##p t) \
+{ \
+	struct ieee754_csr ieee754_csr_save; \
+	s = f1 (s, t); \
+	ieee754_csr_save = ieee754_csr; \
+	s = f2 (s, r); \
+	ieee754_csr_save.cx |= ieee754_csr.cx; \
+	ieee754_csr_save.sx |= ieee754_csr.sx; \
+	s = f3 (s); \
+	ieee754_csr.cx |= ieee754_csr_save.cx; \
+	ieee754_csr.sx |= ieee754_csr_save.sx; \
+	return s; \
+}
+
+static ieee754dp fpemu_dp_recip(ieee754dp d)
+{
+	return ieee754dp_div(ieee754dp_one(0), d);
+}
+
+static ieee754dp fpemu_dp_rsqrt(ieee754dp d)
+{
+	return ieee754dp_div(ieee754dp_one(0), ieee754dp_sqrt(d));
+}
+
+static ieee754sp fpemu_sp_recip(ieee754sp s)
+{
+	return ieee754sp_div(ieee754sp_one(0), s);
+}
+
+static ieee754sp fpemu_sp_rsqrt(ieee754sp s)
+{
+	return ieee754sp_div(ieee754sp_one(0), ieee754sp_sqrt(s));
+}
+
+DEF3OP(madd, sp, ieee754sp_mul, ieee754sp_add,);
+DEF3OP(msub, sp, ieee754sp_mul, ieee754sp_sub,);
+DEF3OP(nmadd, sp, ieee754sp_mul, ieee754sp_add, ieee754sp_neg);
+DEF3OP(nmsub, sp, ieee754sp_mul, ieee754sp_sub, ieee754sp_neg);
+DEF3OP(madd, dp, ieee754dp_mul, ieee754dp_add,);
+DEF3OP(msub, dp, ieee754dp_mul, ieee754dp_sub,);
+DEF3OP(nmadd, dp, ieee754dp_mul, ieee754dp_add, ieee754dp_neg);
+DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg);
+
+static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
+	mips_instruction ir)
+{
+	unsigned rcsr = 0;	/* resulting csr */
+
+	fpuemuprivate.stats.cp1xops++;
+
+	switch (MIPSInst_FMA_FFMT(ir)) {
+	case s_fmt:{		/* 0 */
+
+		ieee754sp(*handler) (ieee754sp, ieee754sp, ieee754sp);
+		ieee754sp fd, fr, fs, ft;
+		u32 *va;
+		u32 val;
+
+		switch (MIPSInst_FUNC(ir)) {
+		case lwxc1_op:
+			va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
+				xcp->regs[MIPSInst_FT(ir)]);
+
+			fpuemuprivate.stats.loads++;
+			if (get_user(val, va)) {
+				fpuemuprivate.stats.errors++;
+				return SIGBUS;
+			}
+#ifdef SINGLE_ONLY_FPU
+			if (MIPSInst_FD(ir) & 1) {
+				/* illegal register in single-float
+				 * mode
+				 */
+				return SIGILL;
+			}
+#endif
+			SITOREG(val, MIPSInst_FD(ir));
+			break;
+
+		case swxc1_op:
+			va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
+				xcp->regs[MIPSInst_FT(ir)]);
+
+			fpuemuprivate.stats.stores++;
+#ifdef SINGLE_ONLY_FPU
+			if (MIPSInst_FS(ir) & 1) {
+				/* illegal register in single-float
+				 * mode
+				 */
+				return SIGILL;
+			}
+#endif
+
+			SIFROMREG(val, MIPSInst_FS(ir));
+			if (put_user(val, va)) {
+				fpuemuprivate.stats.errors++;
+				return SIGBUS;
+			}
+			break;
+
+		case madd_s_op:
+			handler = fpemu_sp_madd;
+			goto scoptop;
+		case msub_s_op:
+			handler = fpemu_sp_msub;
+			goto scoptop;
+		case nmadd_s_op:
+			handler = fpemu_sp_nmadd;
+			goto scoptop;
+		case nmsub_s_op:
+			handler = fpemu_sp_nmsub;
+			goto scoptop;
+
+		      scoptop:
+			SPFROMREG(fr, MIPSInst_FR(ir));
+			SPFROMREG(fs, MIPSInst_FS(ir));
+			SPFROMREG(ft, MIPSInst_FT(ir));
+			fd = (*handler) (fr, fs, ft);
+			SPTOREG(fd, MIPSInst_FD(ir));
+
+		      copcsr:
+			if (ieee754_cxtest(IEEE754_INEXACT))
+				rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
+			if (ieee754_cxtest(IEEE754_UNDERFLOW))
+				rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;
+			if (ieee754_cxtest(IEEE754_OVERFLOW))
+				rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
+			if (ieee754_cxtest(IEEE754_INVALID_OPERATION))
+				rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
+
+			ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr;
+			if (ieee754_csr.nod)
+				ctx->fcr31 |= 0x1000000;
+			if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
+				/*printk ("SIGFPE: fpu csr = %08x\n",
+				   ctx->fcr31); */
+				return SIGFPE;
+			}
+
+			break;
+
+		default:
+			return SIGILL;
+		}
+		break;
+	}
+
+#ifndef SINGLE_ONLY_FPU
+	case d_fmt:{		/* 1 */
+		ieee754dp(*handler) (ieee754dp, ieee754dp, ieee754dp);
+		ieee754dp fd, fr, fs, ft;
+		u64 *va;
+		u64 val;
+
+		switch (MIPSInst_FUNC(ir)) {
+		case ldxc1_op:
+			va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
+				xcp->regs[MIPSInst_FT(ir)]);
+
+			fpuemuprivate.stats.loads++;
+			if (get_user(val, va)) {
+				fpuemuprivate.stats.errors++;
+				return SIGBUS;
+			}
+			DITOREG(val, MIPSInst_FD(ir));
+			break;
+
+		case sdxc1_op:
+			va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
+				xcp->regs[MIPSInst_FT(ir)]);
+
+			fpuemuprivate.stats.stores++;
+			DIFROMREG(val, MIPSInst_FS(ir));
+			if (put_user(val, va)) {
+				fpuemuprivate.stats.errors++;
+				return SIGBUS;
+			}
+			break;
+
+		case madd_d_op:
+			handler = fpemu_dp_madd;
+			goto dcoptop;
+		case msub_d_op:
+			handler = fpemu_dp_msub;
+			goto dcoptop;
+		case nmadd_d_op:
+			handler = fpemu_dp_nmadd;
+			goto dcoptop;
+		case nmsub_d_op:
+			handler = fpemu_dp_nmsub;
+			goto dcoptop;
+
+		      dcoptop:
+			DPFROMREG(fr, MIPSInst_FR(ir));
+			DPFROMREG(fs, MIPSInst_FS(ir));
+			DPFROMREG(ft, MIPSInst_FT(ir));
+			fd = (*handler) (fr, fs, ft);
+			DPTOREG(fd, MIPSInst_FD(ir));
+			goto copcsr;
+
+		default:
+			return SIGILL;
+		}
+		break;
+	}
+#endif
+
+	case 0x7:		/* 7 */
+		if (MIPSInst_FUNC(ir) != pfetch_op) {
+			return SIGILL;
+		}
+		/* ignore prefx operation */
+		break;
+
+	default:
+		return SIGILL;
+	}
+
+	return 0;
+}
+#endif
+
+
+
+/*
+ * Emulate a single COP1 arithmetic instruction.
+ */
+static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
+	mips_instruction ir)
+{
+	int rfmt;		/* resulting format */
+	unsigned rcsr = 0;	/* resulting csr */
+	unsigned cond;
+	union {
+		ieee754dp d;
+		ieee754sp s;
+		int w;
+#if __mips64
+		s64 l;
+#endif
+	} rv;			/* resulting value */
+
+	fpuemuprivate.stats.cp1ops++;
+	switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) {
+	case s_fmt:{		/* 0 */
+		union {
+			ieee754sp(*b) (ieee754sp, ieee754sp);
+			ieee754sp(*u) (ieee754sp);
+		} handler;
+
+		switch (MIPSInst_FUNC(ir)) {
+			/* binary ops */
+		case fadd_op:
+			handler.b = ieee754sp_add;
+			goto scopbop;
+		case fsub_op:
+			handler.b = ieee754sp_sub;
+			goto scopbop;
+		case fmul_op:
+			handler.b = ieee754sp_mul;
+			goto scopbop;
+		case fdiv_op:
+			handler.b = ieee754sp_div;
+			goto scopbop;
+
+			/* unary  ops */
+#if __mips >= 2 || __mips64
+		case fsqrt_op:
+			handler.u = ieee754sp_sqrt;
+			goto scopuop;
+#endif
+#if __mips >= 4 && __mips != 32
+		case frsqrt_op:
+			handler.u = fpemu_sp_rsqrt;
+			goto scopuop;
+		case frecip_op:
+			handler.u = fpemu_sp_recip;
+			goto scopuop;
+#endif
+#if __mips >= 4
+		case fmovc_op:
+			cond = fpucondbit[MIPSInst_FT(ir) >> 2];
+			if (((ctx->fcr31 & cond) != 0) !=
+				((MIPSInst_FT(ir) & 1) != 0))
+				return 0;
+			SPFROMREG(rv.s, MIPSInst_FS(ir));
+			break;
+		case fmovz_op:
+			if (xcp->regs[MIPSInst_FT(ir)] != 0)
+				return 0;
+			SPFROMREG(rv.s, MIPSInst_FS(ir));
+			break;
+		case fmovn_op:
+			if (xcp->regs[MIPSInst_FT(ir)] == 0)
+				return 0;
+			SPFROMREG(rv.s, MIPSInst_FS(ir));
+			break;
+#endif
+		case fabs_op:
+			handler.u = ieee754sp_abs;
+			goto scopuop;
+		case fneg_op:
+			handler.u = ieee754sp_neg;
+			goto scopuop;
+		case fmov_op:
+			/* an easy one */
+			SPFROMREG(rv.s, MIPSInst_FS(ir));
+			goto copcsr;
+
+			/* binary op on handler */
+		      scopbop:
+			{
+				ieee754sp fs, ft;
+
+				SPFROMREG(fs, MIPSInst_FS(ir));
+				SPFROMREG(ft, MIPSInst_FT(ir));
+
+				rv.s = (*handler.b) (fs, ft);
+				goto copcsr;
+			}
+		      scopuop:
+			{
+				ieee754sp fs;
+
+				SPFROMREG(fs, MIPSInst_FS(ir));
+				rv.s = (*handler.u) (fs);
+				goto copcsr;
+			}
+		      copcsr:
+			if (ieee754_cxtest(IEEE754_INEXACT))
+				rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
+			if (ieee754_cxtest(IEEE754_UNDERFLOW))
+				rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;
+			if (ieee754_cxtest(IEEE754_OVERFLOW))
+				rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
+			if (ieee754_cxtest(IEEE754_ZERO_DIVIDE))
+				rcsr |= FPU_CSR_DIV_X | FPU_CSR_DIV_S;
+			if (ieee754_cxtest(IEEE754_INVALID_OPERATION))
+				rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
+			break;
+
+			/* unary conv ops */
+		case fcvts_op:
+			return SIGILL;	/* not defined */
+		case fcvtd_op:{
+#ifdef SINGLE_ONLY_FPU
+			return SIGILL;	/* not defined */
+#else
+			ieee754sp fs;
+
+			SPFROMREG(fs, MIPSInst_FS(ir));
+			rv.d = ieee754dp_fsp(fs);
+			rfmt = d_fmt;
+			goto copcsr;
+		}
+#endif
+		case fcvtw_op:{
+			ieee754sp fs;
+
+			SPFROMREG(fs, MIPSInst_FS(ir));
+			rv.w = ieee754sp_tint(fs);
+			rfmt = w_fmt;
+			goto copcsr;
+		}
+
+#if __mips >= 2 || __mips64
+		case fround_op:
+		case ftrunc_op:
+		case fceil_op:
+		case ffloor_op:{
+			unsigned int oldrm = ieee754_csr.rm;
+			ieee754sp fs;
+
+			SPFROMREG(fs, MIPSInst_FS(ir));
+			ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
+			rv.w = ieee754sp_tint(fs);
+			ieee754_csr.rm = oldrm;
+			rfmt = w_fmt;
+			goto copcsr;
+		}
+#endif /* __mips >= 2 */
+
+#if __mips64 && !defined(SINGLE_ONLY_FPU)
+		case fcvtl_op:{
+			ieee754sp fs;
+
+			SPFROMREG(fs, MIPSInst_FS(ir));
+			rv.l = ieee754sp_tlong(fs);
+			rfmt = l_fmt;
+			goto copcsr;
+		}
+
+		case froundl_op:
+		case ftruncl_op:
+		case fceill_op:
+		case ffloorl_op:{
+			unsigned int oldrm = ieee754_csr.rm;
+			ieee754sp fs;
+
+			SPFROMREG(fs, MIPSInst_FS(ir));
+			ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
+			rv.l = ieee754sp_tlong(fs);
+			ieee754_csr.rm = oldrm;
+			rfmt = l_fmt;
+			goto copcsr;
+		}
+#endif /* __mips64 && !fpu(single) */
+
+		default:
+			if (MIPSInst_FUNC(ir) >= fcmp_op) {
+				unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;
+				ieee754sp fs, ft;
+
+				SPFROMREG(fs, MIPSInst_FS(ir));
+				SPFROMREG(ft, MIPSInst_FT(ir));
+				rv.w = ieee754sp_cmp(fs, ft,
+					cmptab[cmpop & 0x7], cmpop & 0x8);
+				rfmt = -1;
+				if ((cmpop & 0x8) && ieee754_cxtest
+					(IEEE754_INVALID_OPERATION))
+					rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
+				else
+					goto copcsr;
+
+			}
+			else {
+				return SIGILL;
+			}
+			break;
+		}
+		break;
+	}
+
+#ifndef SINGLE_ONLY_FPU
+	case d_fmt:{
+		union {
+			ieee754dp(*b) (ieee754dp, ieee754dp);
+			ieee754dp(*u) (ieee754dp);
+		} handler;
+
+		switch (MIPSInst_FUNC(ir)) {
+			/* binary ops */
+		case fadd_op:
+			handler.b = ieee754dp_add;
+			goto dcopbop;
+		case fsub_op:
+			handler.b = ieee754dp_sub;
+			goto dcopbop;
+		case fmul_op:
+			handler.b = ieee754dp_mul;
+			goto dcopbop;
+		case fdiv_op:
+			handler.b = ieee754dp_div;
+			goto dcopbop;
+
+			/* unary  ops */
+#if __mips >= 2 || __mips64
+		case fsqrt_op:
+			handler.u = ieee754dp_sqrt;
+			goto dcopuop;
+#endif
+#if __mips >= 4 && __mips != 32
+		case frsqrt_op:
+			handler.u = fpemu_dp_rsqrt;
+			goto dcopuop;
+		case frecip_op:
+			handler.u = fpemu_dp_recip;
+			goto dcopuop;
+#endif
+#if __mips >= 4
+		case fmovc_op:
+			cond = fpucondbit[MIPSInst_FT(ir) >> 2];
+			if (((ctx->fcr31 & cond) != 0) !=
+				((MIPSInst_FT(ir) & 1) != 0))
+				return 0;
+			DPFROMREG(rv.d, MIPSInst_FS(ir));
+			break;
+		case fmovz_op:
+			if (xcp->regs[MIPSInst_FT(ir)] != 0)
+				return 0;
+			DPFROMREG(rv.d, MIPSInst_FS(ir));
+			break;
+		case fmovn_op:
+			if (xcp->regs[MIPSInst_FT(ir)] == 0)
+				return 0;
+			DPFROMREG(rv.d, MIPSInst_FS(ir));
+			break;
+#endif
+		case fabs_op:
+			handler.u = ieee754dp_abs;
+			goto dcopuop;
+
+		case fneg_op:
+			handler.u = ieee754dp_neg;
+			goto dcopuop;
+
+		case fmov_op:
+			/* an easy one */
+			DPFROMREG(rv.d, MIPSInst_FS(ir));
+			goto copcsr;
+
+			/* binary op on handler */
+		      dcopbop:{
+				ieee754dp fs, ft;
+
+				DPFROMREG(fs, MIPSInst_FS(ir));
+				DPFROMREG(ft, MIPSInst_FT(ir));
+
+				rv.d = (*handler.b) (fs, ft);
+				goto copcsr;
+			}
+		      dcopuop:{
+				ieee754dp fs;
+
+				DPFROMREG(fs, MIPSInst_FS(ir));
+				rv.d = (*handler.u) (fs);
+				goto copcsr;
+			}
+
+			/* unary conv ops */
+		case fcvts_op:{
+			ieee754dp fs;
+
+			DPFROMREG(fs, MIPSInst_FS(ir));
+			rv.s = ieee754sp_fdp(fs);
+			rfmt = s_fmt;
+			goto copcsr;
+		}
+		case fcvtd_op:
+			return SIGILL;	/* not defined */
+
+		case fcvtw_op:{
+			ieee754dp fs;
+
+			DPFROMREG(fs, MIPSInst_FS(ir));
+			rv.w = ieee754dp_tint(fs);	/* wrong */
+			rfmt = w_fmt;
+			goto copcsr;
+		}
+
+#if __mips >= 2 || __mips64
+		case fround_op:
+		case ftrunc_op:
+		case fceil_op:
+		case ffloor_op:{
+			unsigned int oldrm = ieee754_csr.rm;
+			ieee754dp fs;
+
+			DPFROMREG(fs, MIPSInst_FS(ir));
+			ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
+			rv.w = ieee754dp_tint(fs);
+			ieee754_csr.rm = oldrm;
+			rfmt = w_fmt;
+			goto copcsr;
+		}
+#endif
+
+#if __mips64 && !defined(SINGLE_ONLY_FPU)
+		case fcvtl_op:{
+			ieee754dp fs;
+
+			DPFROMREG(fs, MIPSInst_FS(ir));
+			rv.l = ieee754dp_tlong(fs);
+			rfmt = l_fmt;
+			goto copcsr;
+		}
+
+		case froundl_op:
+		case ftruncl_op:
+		case fceill_op:
+		case ffloorl_op:{
+			unsigned int oldrm = ieee754_csr.rm;
+			ieee754dp fs;
+
+			DPFROMREG(fs, MIPSInst_FS(ir));
+			ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
+			rv.l = ieee754dp_tlong(fs);
+			ieee754_csr.rm = oldrm;
+			rfmt = l_fmt;
+			goto copcsr;
+		}
+#endif /* __mips >= 3 && !fpu(single) */
+
+		default:
+			if (MIPSInst_FUNC(ir) >= fcmp_op) {
+				unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;
+				ieee754dp fs, ft;
+
+				DPFROMREG(fs, MIPSInst_FS(ir));
+				DPFROMREG(ft, MIPSInst_FT(ir));
+				rv.w = ieee754dp_cmp(fs, ft,
+					cmptab[cmpop & 0x7], cmpop & 0x8);
+				rfmt = -1;
+				if ((cmpop & 0x8)
+					&&
+					ieee754_cxtest
+					(IEEE754_INVALID_OPERATION))
+					rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
+				else
+					goto copcsr;
+
+			}
+			else {
+				return SIGILL;
+			}
+			break;
+		}
+		break;
+	}
+#endif /* ifndef SINGLE_ONLY_FPU */
+
+	case w_fmt:{
+		ieee754sp fs;
+
+		switch (MIPSInst_FUNC(ir)) {
+		case fcvts_op:
+			/* convert word to single precision real */
+			SPFROMREG(fs, MIPSInst_FS(ir));
+			rv.s = ieee754sp_fint(fs.bits);
+			rfmt = s_fmt;
+			goto copcsr;
+#ifndef SINGLE_ONLY_FPU
+		case fcvtd_op:
+			/* convert word to double precision real */
+			SPFROMREG(fs, MIPSInst_FS(ir));
+			rv.d = ieee754dp_fint(fs.bits);
+			rfmt = d_fmt;
+			goto copcsr;
+#endif
+		default:
+			return SIGILL;
+		}
+		break;
+	}
+
+#if __mips64 && !defined(SINGLE_ONLY_FPU)
+	case l_fmt:{
+		switch (MIPSInst_FUNC(ir)) {
+		case fcvts_op:
+			/* convert long to single precision real */
+			rv.s = ieee754sp_flong(ctx->fpr[MIPSInst_FS(ir)]);
+			rfmt = s_fmt;
+			goto copcsr;
+		case fcvtd_op:
+			/* convert long to double precision real */
+			rv.d = ieee754dp_flong(ctx->fpr[MIPSInst_FS(ir)]);
+			rfmt = d_fmt;
+			goto copcsr;
+		default:
+			return SIGILL;
+		}
+		break;
+	}
+#endif
+
+	default:
+		return SIGILL;
+	}
+
+	/*
+	 * Update the fpu CSR register for this operation.
+	 * If an exception is required, generate a tidy SIGFPE exception,
+	 * without updating the result register.
+	 * Note: cause exception bits do not accumulate, they are rewritten
+	 * for each op; only the flag/sticky bits accumulate.
+	 */
+	ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr;
+	if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
+		/*printk ("SIGFPE: fpu csr = %08x\n",ctx->fcr31); */
+		return SIGFPE;
+	}
+
+	/*
+	 * Now we can safely write the result back to the register file.
+	 */
+	switch (rfmt) {
+	case -1:{
+#if __mips >= 4
+		cond = fpucondbit[MIPSInst_FD(ir) >> 2];
+#else
+		cond = FPU_CSR_COND;
+#endif
+		if (rv.w)
+			ctx->fcr31 |= cond;
+		else
+			ctx->fcr31 &= ~cond;
+		break;
+	}
+#ifndef SINGLE_ONLY_FPU
+	case d_fmt:
+		DPTOREG(rv.d, MIPSInst_FD(ir));
+		break;
+#endif
+	case s_fmt:
+		SPTOREG(rv.s, MIPSInst_FD(ir));
+		break;
+	case w_fmt:
+		SITOREG(rv.w, MIPSInst_FD(ir));
+		break;
+#if __mips64 && !defined(SINGLE_ONLY_FPU)
+	case l_fmt:
+		DITOREG(rv.l, MIPSInst_FD(ir));
+		break;
+#endif
+	default:
+		return SIGILL;
+	}
+
+	return 0;
+}
+
+int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp,
+	struct mips_fpu_soft_struct *ctx)
+{
+	gpreg_t oldepc, prevepc;
+	mips_instruction insn;
+	int sig = 0;
+
+	oldepc = xcp->cp0_epc;
+	do {
+		prevepc = xcp->cp0_epc;
+
+		if (get_user(insn, (mips_instruction *) xcp->cp0_epc)) {
+			fpuemuprivate.stats.errors++;
+			return SIGBUS;
+		}
+		if (insn == 0)
+			xcp->cp0_epc += 4;	/* skip nops */
+		else {
+			/* Update ieee754_csr. Only relevant if we have a
+			   h/w FPU */
+			ieee754_csr.nod = (ctx->fcr31 & 0x1000000) != 0;
+			ieee754_csr.rm = ieee_rm[ctx->fcr31 & 0x3];
+			ieee754_csr.cx = (ctx->fcr31 >> 12) & 0x1f;
+			sig = cop1Emulate(xcp, ctx);
+		}
+
+		if (cpu_has_fpu)
+			break;
+		if (sig)
+			break;
+
+		cond_resched();
+	} while (xcp->cp0_epc > prevepc);
+
+	/* SIGILL indicates a non-fpu instruction */
+	if (sig == SIGILL && xcp->cp0_epc != oldepc)
+		/* but if epc has advanced, then ignore it */
+		sig = 0;
+
+	return sig;
+}
diff --git a/arch/mips/math-emu/dp_add.c b/arch/mips/math-emu/dp_add.c
new file mode 100644
index 0000000..bcf73bb
--- /dev/null
+++ b/arch/mips/math-emu/dp_add.c
@@ -0,0 +1,183 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ */
+
+
+#include "ieee754dp.h"
+
+ieee754dp ieee754dp_add(ieee754dp x, ieee754dp y)
+{
+	COMPXDP;
+	COMPYDP;
+
+	EXPLODEXDP;
+	EXPLODEYDP;
+
+	CLEARCX;
+
+	FLUSHXDP;
+	FLUSHYDP;
+
+	switch (CLPAIR(xc, yc)) {
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754dp_nanxcpt(ieee754dp_indef(), "add", x, y);
+
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
+		return y;
+
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
+		return x;
+
+
+		/* Infinity handling
+		 */
+
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+		if (xs == ys)
+			return x;
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754dp_xcpt(ieee754dp_indef(), "add", x, y);
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
+		return y;
+
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
+		return x;
+
+		/* Zero handling
+		 */
+
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+		if (xs == ys)
+			return x;
+		else
+			return ieee754dp_zero(ieee754_csr.rm ==
+					      IEEE754_RD);
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
+		return x;
+
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
+		return y;
+
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
+		DPDNORMX;
+
+		/* FALL THROUGH */
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
+		DPDNORMY;
+		break;
+
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
+		DPDNORMX;
+		break;
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
+		break;
+	}
+	assert(xm & DP_HIDDEN_BIT);
+	assert(ym & DP_HIDDEN_BIT);
+
+	/* provide guard,round and stick bit space */
+	xm <<= 3;
+	ym <<= 3;
+
+	if (xe > ye) {
+		/* have to shift y fraction right to align
+		 */
+		int s = xe - ye;
+		ym = XDPSRS(ym, s);
+		ye += s;
+	} else if (ye > xe) {
+		/* have to shift x fraction right to align
+		 */
+		int s = ye - xe;
+		xm = XDPSRS(xm, s);
+		xe += s;
+	}
+	assert(xe == ye);
+	assert(xe <= DP_EMAX);
+
+	if (xs == ys) {
+		/* generate 28 bit result of adding two 27 bit numbers
+		 * leaving result in xm,xs,xe
+		 */
+		xm = xm + ym;
+		xe = xe;
+		xs = xs;
+
+		if (xm >> (DP_MBITS + 1 + 3)) {	/* carry out */
+			xm = XDPSRS1(xm);
+			xe++;
+		}
+	} else {
+		if (xm >= ym) {
+			xm = xm - ym;
+			xe = xe;
+			xs = xs;
+		} else {
+			xm = ym - xm;
+			xe = xe;
+			xs = ys;
+		}
+		if (xm == 0)
+			return ieee754dp_zero(ieee754_csr.rm ==
+					      IEEE754_RD);
+
+		/* normalize to rounding precision */
+		while ((xm >> (DP_MBITS + 3)) == 0) {
+			xm <<= 1;
+			xe--;
+		}
+
+	}
+	DPNORMRET2(xs, xe, xm, "add", x, y);
+}
diff --git a/arch/mips/math-emu/dp_cmp.c b/arch/mips/math-emu/dp_cmp.c
new file mode 100644
index 0000000..8ab4f32
--- /dev/null
+++ b/arch/mips/math-emu/dp_cmp.c
@@ -0,0 +1,67 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cmp, int sig)
+{
+	COMPXDP;
+	COMPYDP;
+
+	EXPLODEXDP;
+	EXPLODEYDP;
+	FLUSHXDP;
+	FLUSHYDP;
+	CLEARCX;	/* Even clear inexact flag here */
+
+	if (ieee754dp_isnan(x) || ieee754dp_isnan(y)) {
+		if (sig || xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
+			SETCX(IEEE754_INVALID_OPERATION);
+		if (cmp & IEEE754_CUN)
+			return 1;
+		if (cmp & (IEEE754_CLT | IEEE754_CGT)) {
+			if (sig && SETANDTESTCX(IEEE754_INVALID_OPERATION))
+				return ieee754si_xcpt(0, "fcmpf", x);
+		}
+		return 0;
+	} else {
+		s64 vx = x.bits;
+		s64 vy = y.bits;
+
+		if (vx < 0)
+			vx = -vx ^ DP_SIGN_BIT;
+		if (vy < 0)
+			vy = -vy ^ DP_SIGN_BIT;
+
+		if (vx < vy)
+			return (cmp & IEEE754_CLT) != 0;
+		else if (vx == vy)
+			return (cmp & IEEE754_CEQ) != 0;
+		else
+			return (cmp & IEEE754_CGT) != 0;
+	}
+}
diff --git a/arch/mips/math-emu/dp_div.c b/arch/mips/math-emu/dp_div.c
new file mode 100644
index 0000000..6acedce
--- /dev/null
+++ b/arch/mips/math-emu/dp_div.c
@@ -0,0 +1,157 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+ieee754dp ieee754dp_div(ieee754dp x, ieee754dp y)
+{
+	COMPXDP;
+	COMPYDP;
+
+	EXPLODEXDP;
+	EXPLODEYDP;
+
+	CLEARCX;
+
+	FLUSHXDP;
+	FLUSHYDP;
+
+	switch (CLPAIR(xc, yc)) {
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754dp_nanxcpt(ieee754dp_indef(), "div", x, y);
+
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
+		return y;
+
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
+		return x;
+
+
+		/* Infinity handling
+		 */
+
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754dp_xcpt(ieee754dp_indef(), "div", x, y);
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
+		return ieee754dp_zero(xs ^ ys);
+
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
+		return ieee754dp_inf(xs ^ ys);
+
+		/* Zero handling
+		 */
+
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754dp_xcpt(ieee754dp_indef(), "div", x, y);
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
+		SETCX(IEEE754_ZERO_DIVIDE);
+		return ieee754dp_xcpt(ieee754dp_inf(xs ^ ys), "div", x, y);
+
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
+		return ieee754dp_zero(xs == ys ? 0 : 1);
+
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
+		DPDNORMX;
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
+		DPDNORMY;
+		break;
+
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
+		DPDNORMX;
+		break;
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
+		break;
+	}
+	assert(xm & DP_HIDDEN_BIT);
+	assert(ym & DP_HIDDEN_BIT);
+
+	/* provide rounding space */
+	xm <<= 3;
+	ym <<= 3;
+
+	{
+		/* now the dirty work */
+
+		u64 rm = 0;
+		int re = xe - ye;
+		u64 bm;
+
+		for (bm = DP_MBIT(DP_MBITS + 2); bm; bm >>= 1) {
+			if (xm >= ym) {
+				xm -= ym;
+				rm |= bm;
+				if (xm == 0)
+					break;
+			}
+			xm <<= 1;
+		}
+		rm <<= 1;
+		if (xm)
+			rm |= 1;	/* have remainder, set sticky */
+
+		assert(rm);
+
+		/* normalise rm to rounding precision ?
+		 */
+		while ((rm >> (DP_MBITS + 3)) == 0) {
+			rm <<= 1;
+			re--;
+		}
+
+		DPNORMRET2(xs == ys ? 0 : 1, re, rm, "div", x, y);
+	}
+}
diff --git a/arch/mips/math-emu/dp_fint.c b/arch/mips/math-emu/dp_fint.c
new file mode 100644
index 0000000..0065dea
--- /dev/null
+++ b/arch/mips/math-emu/dp_fint.c
@@ -0,0 +1,80 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+ieee754dp ieee754dp_fint(int x)
+{
+	COMPXDP;
+
+	CLEARCX;
+
+	xc = ( 0 ? xc : xc );
+
+	if (x == 0)
+		return ieee754dp_zero(0);
+	if (x == 1 || x == -1)
+		return ieee754dp_one(x < 0);
+	if (x == 10 || x == -10)
+		return ieee754dp_ten(x < 0);
+
+	xs = (x < 0);
+	if (xs) {
+		if (x == (1 << 31))
+			xm = ((unsigned) 1 << 31);	/* max neg can't be safely negated */
+		else
+			xm = -x;
+	} else {
+		xm = x;
+	}
+
+#if 1
+	/* normalize - result can never be inexact or overflow */
+	xe = DP_MBITS;
+	while ((xm >> DP_MBITS) == 0) {
+		xm <<= 1;
+		xe--;
+	}
+	return builddp(xs, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
+#else
+	/* normalize */
+	xe = DP_MBITS + 3;
+	while ((xm >> (DP_MBITS + 3)) == 0) {
+		xm <<= 1;
+		xe--;
+	}
+	DPNORMRET1(xs, xe, xm, "fint", x);
+#endif
+}
+
+ieee754dp ieee754dp_funs(unsigned int u)
+{
+	if ((int) u < 0)
+		return ieee754dp_add(ieee754dp_1e31(),
+				     ieee754dp_fint(u & ~(1 << 31)));
+	return ieee754dp_fint(u);
+}
diff --git a/arch/mips/math-emu/dp_flong.c b/arch/mips/math-emu/dp_flong.c
new file mode 100644
index 0000000..cb105b1
--- /dev/null
+++ b/arch/mips/math-emu/dp_flong.c
@@ -0,0 +1,78 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+ieee754dp ieee754dp_flong(s64 x)
+{
+	COMPXDP;
+
+	CLEARCX;
+
+	xc = ( 0 ? xc : xc );
+
+	if (x == 0)
+		return ieee754dp_zero(0);
+	if (x == 1 || x == -1)
+		return ieee754dp_one(x < 0);
+	if (x == 10 || x == -10)
+		return ieee754dp_ten(x < 0);
+
+	xs = (x < 0);
+	if (xs) {
+		if (x == (1ULL << 63))
+			xm = (1ULL << 63);	/* max neg can't be safely negated */
+		else
+			xm = -x;
+	} else {
+		xm = x;
+	}
+
+	/* normalize */
+	xe = DP_MBITS + 3;
+	if (xm >> (DP_MBITS + 1 + 3)) {
+		/* shunt out overflow bits */
+		while (xm >> (DP_MBITS + 1 + 3)) {
+			XDPSRSX1();
+		}
+	} else {
+		/* normalize in grs extended double precision */
+		while ((xm >> (DP_MBITS + 3)) == 0) {
+			xm <<= 1;
+			xe--;
+		}
+	}
+	DPNORMRET1(xs, xe, xm, "dp_flong", x);
+}
+
+ieee754dp ieee754dp_fulong(u64 u)
+{
+	if ((s64) u < 0)
+		return ieee754dp_add(ieee754dp_1e63(),
+				     ieee754dp_flong(u & ~(1ULL << 63)));
+	return ieee754dp_flong(u);
+}
diff --git a/arch/mips/math-emu/dp_frexp.c b/arch/mips/math-emu/dp_frexp.c
new file mode 100644
index 0000000..e650cb1
--- /dev/null
+++ b/arch/mips/math-emu/dp_frexp.c
@@ -0,0 +1,53 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+/* close to ieeep754dp_logb
+*/
+ieee754dp ieee754dp_frexp(ieee754dp x, int *eptr)
+{
+	COMPXDP;
+	CLEARCX;
+	EXPLODEXDP;
+
+	switch (xc) {
+	case IEEE754_CLASS_SNAN:
+	case IEEE754_CLASS_QNAN:
+	case IEEE754_CLASS_INF:
+	case IEEE754_CLASS_ZERO:
+		*eptr = 0;
+		return x;
+	case IEEE754_CLASS_DNORM:
+		DPDNORMX;
+		break;
+	case IEEE754_CLASS_NORM:
+		break;
+	}
+	*eptr = xe + 1;
+	return builddp(xs, -1 + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
+}
diff --git a/arch/mips/math-emu/dp_fsp.c b/arch/mips/math-emu/dp_fsp.c
new file mode 100644
index 0000000..494d19a
--- /dev/null
+++ b/arch/mips/math-emu/dp_fsp.c
@@ -0,0 +1,74 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+ieee754dp ieee754dp_fsp(ieee754sp x)
+{
+	COMPXSP;
+
+	EXPLODEXSP;
+
+	CLEARCX;
+
+	FLUSHXSP;
+
+	switch (xc) {
+	case IEEE754_CLASS_SNAN:
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754dp_nanxcpt(ieee754dp_indef(), "fsp");
+	case IEEE754_CLASS_QNAN:
+		return ieee754dp_nanxcpt(builddp(xs,
+						 DP_EMAX + 1 + DP_EBIAS,
+						 ((u64) xm
+						  << (DP_MBITS -
+						      SP_MBITS))), "fsp",
+					 x);
+	case IEEE754_CLASS_INF:
+		return ieee754dp_inf(xs);
+	case IEEE754_CLASS_ZERO:
+		return ieee754dp_zero(xs);
+	case IEEE754_CLASS_DNORM:
+		/* normalize */
+		while ((xm >> SP_MBITS) == 0) {
+			xm <<= 1;
+			xe--;
+		}
+		break;
+	case IEEE754_CLASS_NORM:
+		break;
+	}
+
+	/* CANT possibly overflow,underflow, or need rounding
+	 */
+
+	/* drop the hidden bit */
+	xm &= ~SP_HIDDEN_BIT;
+
+	return builddp(xs, xe + DP_EBIAS,
+		       (u64) xm << (DP_MBITS - SP_MBITS));
+}
diff --git a/arch/mips/math-emu/dp_logb.c b/arch/mips/math-emu/dp_logb.c
new file mode 100644
index 0000000..6033886
--- /dev/null
+++ b/arch/mips/math-emu/dp_logb.c
@@ -0,0 +1,54 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+ieee754dp ieee754dp_logb(ieee754dp x)
+{
+	COMPXDP;
+
+	CLEARCX;
+
+	EXPLODEXDP;
+
+	switch (xc) {
+	case IEEE754_CLASS_SNAN:
+		return ieee754dp_nanxcpt(x, "logb", x);
+	case IEEE754_CLASS_QNAN:
+		return x;
+	case IEEE754_CLASS_INF:
+		return ieee754dp_inf(0);
+	case IEEE754_CLASS_ZERO:
+		return ieee754dp_inf(1);
+	case IEEE754_CLASS_DNORM:
+		DPDNORMX;
+		break;
+	case IEEE754_CLASS_NORM:
+		break;
+	}
+	return ieee754dp_fint(xe);
+}
diff --git a/arch/mips/math-emu/dp_modf.c b/arch/mips/math-emu/dp_modf.c
new file mode 100644
index 0000000..25861a4
--- /dev/null
+++ b/arch/mips/math-emu/dp_modf.c
@@ -0,0 +1,80 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+/* modf function is always exact for a finite number
+*/
+ieee754dp ieee754dp_modf(ieee754dp x, ieee754dp * ip)
+{
+	COMPXDP;
+
+	CLEARCX;
+
+	EXPLODEXDP;
+
+	switch (xc) {
+	case IEEE754_CLASS_SNAN:
+	case IEEE754_CLASS_QNAN:
+	case IEEE754_CLASS_INF:
+	case IEEE754_CLASS_ZERO:
+		*ip = x;
+		return x;
+	case IEEE754_CLASS_DNORM:
+		/* far to small */
+		*ip = ieee754dp_zero(xs);
+		return x;
+	case IEEE754_CLASS_NORM:
+		break;
+	}
+	if (xe < 0) {
+		*ip = ieee754dp_zero(xs);
+		return x;
+	}
+	if (xe >= DP_MBITS) {
+		*ip = x;
+		return ieee754dp_zero(xs);
+	}
+	/* generate ipart mantissa by clearing bottom bits
+	 */
+	*ip = builddp(xs, xe + DP_EBIAS,
+		      ((xm >> (DP_MBITS - xe)) << (DP_MBITS - xe)) &
+		      ~DP_HIDDEN_BIT);
+
+	/* generate fpart mantissa by clearing top bits
+	 * and normalizing (must be able to normalize)
+	 */
+	xm = (xm << (64 - (DP_MBITS - xe))) >> (64 - (DP_MBITS - xe));
+	if (xm == 0)
+		return ieee754dp_zero(xs);
+
+	while ((xm >> DP_MBITS) == 0) {
+		xm <<= 1;
+		xe--;
+	}
+	return builddp(xs, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
+}
diff --git a/arch/mips/math-emu/dp_mul.c b/arch/mips/math-emu/dp_mul.c
new file mode 100644
index 0000000..f237390
--- /dev/null
+++ b/arch/mips/math-emu/dp_mul.c
@@ -0,0 +1,177 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+ieee754dp ieee754dp_mul(ieee754dp x, ieee754dp y)
+{
+	COMPXDP;
+	COMPYDP;
+
+	EXPLODEXDP;
+	EXPLODEYDP;
+
+	CLEARCX;
+
+	FLUSHXDP;
+	FLUSHYDP;
+
+	switch (CLPAIR(xc, yc)) {
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754dp_nanxcpt(ieee754dp_indef(), "mul", x, y);
+
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
+		return y;
+
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
+		return x;
+
+
+		/* Infinity handling */
+
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754dp_xcpt(ieee754dp_indef(), "mul", x, y);
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+		return ieee754dp_inf(xs ^ ys);
+
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
+		return ieee754dp_zero(xs ^ ys);
+
+
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
+		DPDNORMX;
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
+		DPDNORMY;
+		break;
+
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
+		DPDNORMX;
+		break;
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
+		break;
+	}
+	/* rm = xm * ym, re = xe+ye basicly */
+	assert(xm & DP_HIDDEN_BIT);
+	assert(ym & DP_HIDDEN_BIT);
+	{
+		int re = xe + ye;
+		int rs = xs ^ ys;
+		u64 rm;
+
+		/* shunt to top of word */
+		xm <<= 64 - (DP_MBITS + 1);
+		ym <<= 64 - (DP_MBITS + 1);
+
+		/* multiply 32bits xm,ym to give high 32bits rm with stickness
+		 */
+
+		/* 32 * 32 => 64 */
+#define DPXMULT(x,y)	((u64)(x) * (u64)y)
+
+		{
+			unsigned lxm = xm;
+			unsigned hxm = xm >> 32;
+			unsigned lym = ym;
+			unsigned hym = ym >> 32;
+			u64 lrm;
+			u64 hrm;
+
+			lrm = DPXMULT(lxm, lym);
+			hrm = DPXMULT(hxm, hym);
+
+			{
+				u64 t = DPXMULT(lxm, hym);
+				{
+					u64 at =
+					    lrm + (t << 32);
+					hrm += at < lrm;
+					lrm = at;
+				}
+				hrm = hrm + (t >> 32);
+			}
+
+			{
+				u64 t = DPXMULT(hxm, lym);
+				{
+					u64 at =
+					    lrm + (t << 32);
+					hrm += at < lrm;
+					lrm = at;
+				}
+				hrm = hrm + (t >> 32);
+			}
+			rm = hrm | (lrm != 0);
+		}
+
+		/*
+		 * sticky shift down to normal rounding precision
+		 */
+		if ((s64) rm < 0) {
+			rm =
+			    (rm >> (64 - (DP_MBITS + 1 + 3))) |
+			    ((rm << (DP_MBITS + 1 + 3)) != 0);
+			re++;
+		} else {
+			rm =
+			    (rm >> (64 - (DP_MBITS + 1 + 3 + 1))) |
+			    ((rm << (DP_MBITS + 1 + 3 + 1)) != 0);
+		}
+		assert(rm & (DP_HIDDEN_BIT << 3));
+		DPNORMRET2(rs, re, rm, "mul", x, y);
+	}
+}
diff --git a/arch/mips/math-emu/dp_scalb.c b/arch/mips/math-emu/dp_scalb.c
new file mode 100644
index 0000000..b84e633
--- /dev/null
+++ b/arch/mips/math-emu/dp_scalb.c
@@ -0,0 +1,58 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+ieee754dp ieee754dp_scalb(ieee754dp x, int n)
+{
+	COMPXDP;
+
+	CLEARCX;
+
+	EXPLODEXDP;
+
+	switch (xc) {
+	case IEEE754_CLASS_SNAN:
+		return ieee754dp_nanxcpt(x, "scalb", x, n);
+	case IEEE754_CLASS_QNAN:
+	case IEEE754_CLASS_INF:
+	case IEEE754_CLASS_ZERO:
+		return x;
+	case IEEE754_CLASS_DNORM:
+		DPDNORMX;
+		break;
+	case IEEE754_CLASS_NORM:
+		break;
+	}
+	DPNORMRET2(xs, xe + n, xm << 3, "scalb", x, n);
+}
+
+
+ieee754dp ieee754dp_ldexp(ieee754dp x, int n)
+{
+	return ieee754dp_scalb(x, n);
+}
diff --git a/arch/mips/math-emu/dp_simple.c b/arch/mips/math-emu/dp_simple.c
new file mode 100644
index 0000000..495c1ac
--- /dev/null
+++ b/arch/mips/math-emu/dp_simple.c
@@ -0,0 +1,84 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+int ieee754dp_finite(ieee754dp x)
+{
+	return DPBEXP(x) != DP_EMAX + 1 + DP_EBIAS;
+}
+
+ieee754dp ieee754dp_copysign(ieee754dp x, ieee754dp y)
+{
+	CLEARCX;
+	DPSIGN(x) = DPSIGN(y);
+	return x;
+}
+
+
+ieee754dp ieee754dp_neg(ieee754dp x)
+{
+	COMPXDP;
+
+	EXPLODEXDP;
+	CLEARCX;
+	FLUSHXDP;
+
+	if (xc == IEEE754_CLASS_SNAN) {
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754dp_nanxcpt(ieee754dp_indef(), "neg");
+	}
+
+	if (ieee754dp_isnan(x))	/* but not infinity */
+		return ieee754dp_nanxcpt(x, "neg", x);
+
+	/* quick fix up */
+	DPSIGN(x) ^= 1;
+	return x;
+}
+
+
+ieee754dp ieee754dp_abs(ieee754dp x)
+{
+	COMPXDP;
+
+	EXPLODEXDP;
+	CLEARCX;
+	FLUSHXDP;
+
+	if (xc == IEEE754_CLASS_SNAN) {
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754dp_nanxcpt(ieee754dp_indef(), "neg");
+	}
+
+	if (ieee754dp_isnan(x))	/* but not infinity */
+		return ieee754dp_nanxcpt(x, "abs", x);
+
+	/* quick fix up */
+	DPSIGN(x) = 0;
+	return x;
+}
diff --git a/arch/mips/math-emu/dp_sqrt.c b/arch/mips/math-emu/dp_sqrt.c
new file mode 100644
index 0000000..c35e871
--- /dev/null
+++ b/arch/mips/math-emu/dp_sqrt.c
@@ -0,0 +1,165 @@
+/* IEEE754 floating point arithmetic
+ * double precision square root
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+static const unsigned table[] = {
+	0, 1204, 3062, 5746, 9193, 13348, 18162, 23592,
+	29598, 36145, 43202, 50740, 58733, 67158, 75992,
+	85215, 83599, 71378, 60428, 50647, 41945, 34246,
+	27478, 21581, 16499, 12183, 8588, 5674, 3403,
+	1742, 661, 130
+};
+
+ieee754dp ieee754dp_sqrt(ieee754dp x)
+{
+	struct ieee754_csr oldcsr;
+	ieee754dp y, z, t;
+	unsigned scalx, yh;
+	COMPXDP;
+
+	EXPLODEXDP;
+	CLEARCX;
+	FLUSHXDP;
+
+	/* x == INF or NAN? */
+	switch (xc) {
+	case IEEE754_CLASS_QNAN:
+		/* sqrt(Nan) = Nan */
+		return ieee754dp_nanxcpt(x, "sqrt");
+	case IEEE754_CLASS_SNAN:
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754dp_nanxcpt(ieee754dp_indef(), "sqrt");
+	case IEEE754_CLASS_ZERO:
+		/* sqrt(0) = 0 */
+		return x;
+	case IEEE754_CLASS_INF:
+		if (xs) {
+			/* sqrt(-Inf) = Nan */
+			SETCX(IEEE754_INVALID_OPERATION);
+			return ieee754dp_nanxcpt(ieee754dp_indef(), "sqrt");
+		}
+		/* sqrt(+Inf) = Inf */
+		return x;
+	case IEEE754_CLASS_DNORM:
+		DPDNORMX;
+		/* fall through */
+	case IEEE754_CLASS_NORM:
+		if (xs) {
+			/* sqrt(-x) = Nan */
+			SETCX(IEEE754_INVALID_OPERATION);
+			return ieee754dp_nanxcpt(ieee754dp_indef(), "sqrt");
+		}
+		break;
+	}
+
+	/* save old csr; switch off INX enable & flag; set RN rounding */
+	oldcsr = ieee754_csr;
+	ieee754_csr.mx &= ~IEEE754_INEXACT;
+	ieee754_csr.sx &= ~IEEE754_INEXACT;
+	ieee754_csr.rm = IEEE754_RN;
+
+	/* adjust exponent to prevent overflow */
+	scalx = 0;
+	if (xe > 512) {		/* x > 2**-512? */
+		xe -= 512;	/* x = x / 2**512 */
+		scalx += 256;
+	} else if (xe < -512) {	/* x < 2**-512? */
+		xe += 512;	/* x = x * 2**512 */
+		scalx -= 256;
+	}
+
+	y = x = builddp(0, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
+
+	/* magic initial approximation to almost 8 sig. bits */
+	yh = y.bits >> 32;
+	yh = (yh >> 1) + 0x1ff80000;
+	yh = yh - table[(yh >> 15) & 31];
+	y.bits = ((u64) yh << 32) | (y.bits & 0xffffffff);
+
+	/* Heron's rule once with correction to improve to ~18 sig. bits */
+	/* t=x/y; y=y+t; py[n0]=py[n0]-0x00100006; py[n1]=0; */
+	t = ieee754dp_div(x, y);
+	y = ieee754dp_add(y, t);
+	y.bits -= 0x0010000600000000LL;
+	y.bits &= 0xffffffff00000000LL;
+
+	/* triple to almost 56 sig. bits: y ~= sqrt(x) to within 1 ulp */
+	/* t=y*y; z=t;  pt[n0]+=0x00100000; t+=z; z=(x-z)*y; */
+	z = t = ieee754dp_mul(y, y);
+	t.parts.bexp += 0x001;
+	t = ieee754dp_add(t, z);
+	z = ieee754dp_mul(ieee754dp_sub(x, z), y);
+
+	/* t=z/(t+x) ;  pt[n0]+=0x00100000; y+=t; */
+	t = ieee754dp_div(z, ieee754dp_add(t, x));
+	t.parts.bexp += 0x001;
+	y = ieee754dp_add(y, t);
+
+	/* twiddle last bit to force y correctly rounded */
+
+	/* set RZ, clear INEX flag */
+	ieee754_csr.rm = IEEE754_RZ;
+	ieee754_csr.sx &= ~IEEE754_INEXACT;
+
+	/* t=x/y; ...chopped quotient, possibly inexact */
+	t = ieee754dp_div(x, y);
+
+	if (ieee754_csr.sx & IEEE754_INEXACT || t.bits != y.bits) {
+
+		if (!(ieee754_csr.sx & IEEE754_INEXACT))
+			/* t = t-ulp */
+			t.bits -= 1;
+
+		/* add inexact to result status */
+		oldcsr.cx |= IEEE754_INEXACT;
+		oldcsr.sx |= IEEE754_INEXACT;
+
+		switch (oldcsr.rm) {
+		case IEEE754_RP:
+			y.bits += 1;
+			/* drop through */
+		case IEEE754_RN:
+			t.bits += 1;
+			break;
+		}
+
+		/* y=y+t; ...chopped sum */
+		y = ieee754dp_add(y, t);
+
+		/* adjust scalx for correctly rounded sqrt(x) */
+		scalx -= 1;
+	}
+
+	/* py[n0]=py[n0]+scalx; ...scale back y */
+	y.parts.bexp += scalx;
+
+	/* restore rounding mode, possibly set inexact */
+	ieee754_csr = oldcsr;
+
+	return y;
+}
diff --git a/arch/mips/math-emu/dp_sub.c b/arch/mips/math-emu/dp_sub.c
new file mode 100644
index 0000000..b30c5b1
--- /dev/null
+++ b/arch/mips/math-emu/dp_sub.c
@@ -0,0 +1,191 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+ieee754dp ieee754dp_sub(ieee754dp x, ieee754dp y)
+{
+	COMPXDP;
+	COMPYDP;
+
+	EXPLODEXDP;
+	EXPLODEYDP;
+
+	CLEARCX;
+
+	FLUSHXDP;
+	FLUSHYDP;
+
+	switch (CLPAIR(xc, yc)) {
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754dp_nanxcpt(ieee754dp_indef(), "sub", x, y);
+
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
+		return y;
+
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
+		return x;
+
+
+		/* Infinity handling
+		 */
+
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+		if (xs != ys)
+			return x;
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754dp_xcpt(ieee754dp_indef(), "sub", x, y);
+
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
+		return ieee754dp_inf(ys ^ 1);
+
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
+		return x;
+
+		/* Zero handling
+		 */
+
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+		if (xs != ys)
+			return x;
+		else
+			return ieee754dp_zero(ieee754_csr.rm ==
+					      IEEE754_RD);
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
+		return x;
+
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
+		/* quick fix up */
+		DPSIGN(y) ^= 1;
+		return y;
+
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
+		DPDNORMX;
+		/* FAAL THOROUGH */
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
+		/* normalize ym,ye */
+		DPDNORMY;
+		break;
+
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
+		/* normalize xm,xe */
+		DPDNORMX;
+		break;
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
+		break;
+	}
+	/* flip sign of y and handle as add */
+	ys ^= 1;
+
+	assert(xm & DP_HIDDEN_BIT);
+	assert(ym & DP_HIDDEN_BIT);
+
+
+	/* provide guard,round and stick bit dpace */
+	xm <<= 3;
+	ym <<= 3;
+
+	if (xe > ye) {
+		/* have to shift y fraction right to align
+		 */
+		int s = xe - ye;
+		ym = XDPSRS(ym, s);
+		ye += s;
+	} else if (ye > xe) {
+		/* have to shift x fraction right to align
+		 */
+		int s = ye - xe;
+		xm = XDPSRS(xm, s);
+		xe += s;
+	}
+	assert(xe == ye);
+	assert(xe <= DP_EMAX);
+
+	if (xs == ys) {
+		/* generate 28 bit result of adding two 27 bit numbers
+		 */
+		xm = xm + ym;
+		xe = xe;
+		xs = xs;
+
+		if (xm >> (DP_MBITS + 1 + 3)) {	/* carry out */
+			xm = XDPSRS1(xm);	/* shift preserving sticky */
+			xe++;
+		}
+	} else {
+		if (xm >= ym) {
+			xm = xm - ym;
+			xe = xe;
+			xs = xs;
+		} else {
+			xm = ym - xm;
+			xe = xe;
+			xs = ys;
+		}
+		if (xm == 0) {
+			if (ieee754_csr.rm == IEEE754_RD)
+				return ieee754dp_zero(1);	/* round negative inf. => sign = -1 */
+			else
+				return ieee754dp_zero(0);	/* other round modes   => sign = 1 */
+		}
+
+		/* normalize to rounding precision
+		 */
+		while ((xm >> (DP_MBITS + 3)) == 0) {
+			xm <<= 1;
+			xe--;
+		}
+	}
+	DPNORMRET2(xs, xe, xm, "sub", x, y);
+}
diff --git a/arch/mips/math-emu/dp_tint.c b/arch/mips/math-emu/dp_tint.c
new file mode 100644
index 0000000..77b2b7c
--- /dev/null
+++ b/arch/mips/math-emu/dp_tint.c
@@ -0,0 +1,124 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include <linux/kernel.h>
+#include "ieee754dp.h"
+
+int ieee754dp_tint(ieee754dp x)
+{
+	COMPXDP;
+
+	CLEARCX;
+
+	EXPLODEXDP;
+	FLUSHXDP;
+
+	switch (xc) {
+	case IEEE754_CLASS_SNAN:
+	case IEEE754_CLASS_QNAN:
+	case IEEE754_CLASS_INF:
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x);
+	case IEEE754_CLASS_ZERO:
+		return 0;
+	case IEEE754_CLASS_DNORM:
+	case IEEE754_CLASS_NORM:
+		break;
+	}
+	if (xe > 31) {
+		/* Set invalid. We will only use overflow for floating
+		   point overflow */
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x);
+	}
+	/* oh gawd */
+	if (xe > DP_MBITS) {
+		xm <<= xe - DP_MBITS;
+	} else if (xe < DP_MBITS) {
+		u64 residue;
+		int round;
+		int sticky;
+		int odd;
+
+		if (xe < -1) {
+			residue = xm;
+			round = 0;
+			sticky = residue != 0;
+			xm = 0;
+		}
+		else {
+			residue = xm << (64 - DP_MBITS + xe);
+			round = (residue >> 63) != 0;
+			sticky = (residue << 1) != 0;
+			xm >>= DP_MBITS - xe;
+		}
+		/* Note: At this point upper 32 bits of xm are guaranteed
+		   to be zero */
+		odd = (xm & 0x1) != 0x0;
+		switch (ieee754_csr.rm) {
+		case IEEE754_RN:
+			if (round && (sticky || odd))
+				xm++;
+			break;
+		case IEEE754_RZ:
+			break;
+		case IEEE754_RU:	/* toward +Infinity */
+			if ((round || sticky) && !xs)
+				xm++;
+			break;
+		case IEEE754_RD:	/* toward -Infinity */
+			if ((round || sticky) && xs)
+				xm++;
+			break;
+		}
+		/* look for valid corner case 0x80000000 */
+		if ((xm >> 31) != 0 && (xs == 0 || xm != 0x80000000)) {
+			/* This can happen after rounding */
+			SETCX(IEEE754_INVALID_OPERATION);
+			return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x);
+		}
+		if (round || sticky)
+			SETCX(IEEE754_INEXACT);
+	}
+	if (xs)
+		return -xm;
+	else
+		return xm;
+}
+
+
+unsigned int ieee754dp_tuns(ieee754dp x)
+{
+	ieee754dp hb = ieee754dp_1e31();
+
+	/* what if x < 0 ?? */
+	if (ieee754dp_lt(x, hb))
+		return (unsigned) ieee754dp_tint(x);
+
+	return (unsigned) ieee754dp_tint(ieee754dp_sub(x, hb)) |
+	    ((unsigned) 1 << 31);
+}
diff --git a/arch/mips/math-emu/dp_tlong.c b/arch/mips/math-emu/dp_tlong.c
new file mode 100644
index 0000000..d71113e
--- /dev/null
+++ b/arch/mips/math-emu/dp_tlong.c
@@ -0,0 +1,127 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+s64 ieee754dp_tlong(ieee754dp x)
+{
+	COMPXDP;
+
+	CLEARCX;
+
+	EXPLODEXDP;
+	FLUSHXDP;
+
+	switch (xc) {
+	case IEEE754_CLASS_SNAN:
+	case IEEE754_CLASS_QNAN:
+	case IEEE754_CLASS_INF:
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x);
+	case IEEE754_CLASS_ZERO:
+		return 0;
+	case IEEE754_CLASS_DNORM:
+	case IEEE754_CLASS_NORM:
+		break;
+	}
+	if (xe >= 63) {
+		/* look for valid corner case */
+		if (xe == 63 && xs && xm == DP_HIDDEN_BIT)
+			return -0x8000000000000000LL;
+		/* Set invalid. We will only use overflow for floating
+		   point overflow */
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x);
+	}
+	/* oh gawd */
+	if (xe > DP_MBITS) {
+		xm <<= xe - DP_MBITS;
+	} else if (xe < DP_MBITS) {
+		u64 residue;
+		int round;
+		int sticky;
+		int odd;
+
+		if (xe < -1) {
+			residue = xm;
+			round = 0;
+			sticky = residue != 0;
+			xm = 0;
+		}
+		else {
+			/* Shifting a u64 64 times does not work,
+			* so we do it in two steps. Be aware that xe
+			* may be -1 */
+			residue = xm << (xe + 1);
+			residue <<= 63 - DP_MBITS;
+			round = (residue >> 63) != 0;
+			sticky = (residue << 1) != 0;
+			xm >>= DP_MBITS - xe;
+		}
+		odd = (xm & 0x1) != 0x0;
+		switch (ieee754_csr.rm) {
+		case IEEE754_RN:
+			if (round && (sticky || odd))
+				xm++;
+			break;
+		case IEEE754_RZ:
+			break;
+		case IEEE754_RU:	/* toward +Infinity */
+			if ((round || sticky) && !xs)
+				xm++;
+			break;
+		case IEEE754_RD:	/* toward -Infinity */
+			if ((round || sticky) && xs)
+				xm++;
+			break;
+		}
+		if ((xm >> 63) != 0) {
+			/* This can happen after rounding */
+			SETCX(IEEE754_INVALID_OPERATION);
+			return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x);
+		}
+		if (round || sticky)
+			SETCX(IEEE754_INEXACT);
+	}
+	if (xs)
+		return -xm;
+	else
+		return xm;
+}
+
+
+u64 ieee754dp_tulong(ieee754dp x)
+{
+	ieee754dp hb = ieee754dp_1e63();
+
+	/* what if x < 0 ?? */
+	if (ieee754dp_lt(x, hb))
+		return (u64) ieee754dp_tlong(x);
+
+	return (u64) ieee754dp_tlong(ieee754dp_sub(x, hb)) |
+	    (1ULL << 63);
+}
diff --git a/arch/mips/math-emu/dsemul.c b/arch/mips/math-emu/dsemul.c
new file mode 100644
index 0000000..aa989c2
--- /dev/null
+++ b/arch/mips/math-emu/dsemul.c
@@ -0,0 +1,172 @@
+#include <linux/compiler.h>
+#include <linux/mm.h>
+#include <linux/signal.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+
+#include <asm/asm.h>
+#include <asm/bootinfo.h>
+#include <asm/byteorder.h>
+#include <asm/cpu.h>
+#include <asm/inst.h>
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+#include <asm/branch.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/cacheflush.h>
+
+#include <asm/fpu_emulator.h>
+
+#include "ieee754.h"
+#include "dsemul.h"
+
+/* Strap kernel emulator for full MIPS IV emulation */
+
+#ifdef __mips
+#undef __mips
+#endif
+#define __mips 4
+
+extern struct mips_fpu_emulator_private fpuemuprivate;
+
+
+/*
+ * Emulate the arbritrary instruction ir at xcp->cp0_epc.  Required when
+ * we have to emulate the instruction in a COP1 branch delay slot.  Do
+ * not change cp0_epc due to the instruction
+ *
+ * According to the spec:
+ * 1) it shouldnt be a branch :-)
+ * 2) it can be a COP instruction :-(
+ * 3) if we are tring to run a protected memory space we must take
+ *    special care on memory access instructions :-(
+ */
+
+/*
+ * "Trampoline" return routine to catch exception following
+ *  execution of delay-slot instruction execution.
+ */
+
+struct emuframe {
+	mips_instruction	emul;
+	mips_instruction	badinst;
+	mips_instruction	cookie;
+	gpreg_t			epc;
+};
+
+int mips_dsemul(struct pt_regs *regs, mips_instruction ir, gpreg_t cpc)
+{
+	extern asmlinkage void handle_dsemulret(void);
+	mips_instruction *dsemul_insns;
+	struct emuframe *fr;
+	int err;
+
+	if (ir == 0) {		/* a nop is easy */
+		regs->cp0_epc = cpc;
+		regs->cp0_cause &= ~CAUSEF_BD;
+		return 0;
+	}
+#ifdef DSEMUL_TRACE
+	printk("dsemul %lx %lx\n", regs->cp0_epc, cpc);
+
+#endif
+
+	/*
+	 * The strategy is to push the instruction onto the user stack
+	 * and put a trap after it which we can catch and jump to
+	 * the required address any alternative apart from full
+	 * instruction emulation!!.
+	 *
+	 * Algorithmics used a system call instruction, and
+	 * borrowed that vector.  MIPS/Linux version is a bit
+	 * more heavyweight in the interests of portability and
+	 * multiprocessor support.  For Linux we generate a
+	 * an unaligned access and force an address error exception.
+	 *
+	 * For embedded systems (stand-alone) we prefer to use a
+	 * non-existing CP1 instruction. This prevents us from emulating
+	 * branches, but gives us a cleaner interface to the exception
+	 * handler (single entry point).
+	 */
+
+	/* Ensure that the two instructions are in the same cache line */
+	dsemul_insns = (mips_instruction *) REG_TO_VA ((regs->regs[29] - sizeof(struct emuframe)) & ~0x7);
+	fr = (struct emuframe *) dsemul_insns;
+
+	/* Verify that the stack pointer is not competely insane */
+	if (unlikely(!access_ok(VERIFY_WRITE, fr, sizeof(struct emuframe))))
+		return SIGBUS;
+
+	err = __put_user(ir, &fr->emul);
+	err |= __put_user((mips_instruction)BADINST, &fr->badinst);
+	err |= __put_user((mips_instruction)BD_COOKIE, &fr->cookie);
+	err |= __put_user(cpc, &fr->epc);
+
+	if (unlikely(err)) {
+		fpuemuprivate.stats.errors++;
+		return SIGBUS;
+	}
+
+	regs->cp0_epc = VA_TO_REG & fr->emul;
+
+	flush_cache_sigtramp((unsigned long)&fr->badinst);
+
+	return SIGILL;		/* force out of emulation loop */
+}
+
+int do_dsemulret(struct pt_regs *xcp)
+{
+	struct emuframe *fr;
+	gpreg_t epc;
+	u32 insn, cookie;
+	int err = 0;
+
+	fr = (struct emuframe *) (xcp->cp0_epc - sizeof(mips_instruction));
+
+	/*
+	 * If we can't even access the area, something is very wrong, but we'll
+	 * leave that to the default handling
+	 */
+	if (!access_ok(VERIFY_READ, fr, sizeof(struct emuframe)))
+		return 0;
+
+	/*
+	 * Do some sanity checking on the stackframe:
+	 *
+	 *  - Is the instruction pointed to by the EPC an BADINST?
+	 *  - Is the following memory word the BD_COOKIE?
+	 */
+	err = __get_user(insn, &fr->badinst);
+	err |= __get_user(cookie, &fr->cookie);
+
+	if (unlikely(err || (insn != BADINST) || (cookie != BD_COOKIE))) {
+		fpuemuprivate.stats.errors++;
+		return 0;
+	}
+
+	/*
+	 * At this point, we are satisfied that it's a BD emulation trap.  Yes,
+	 * a user might have deliberately put two malformed and useless
+	 * instructions in a row in his program, in which case he's in for a
+	 * nasty surprise - the next instruction will be treated as a
+	 * continuation address!  Alas, this seems to be the only way that we
+	 * can handle signals, recursion, and longjmps() in the context of
+	 * emulating the branch delay instruction.
+	 */
+
+#ifdef DSEMUL_TRACE
+	printk("dsemulret\n");
+#endif
+	if (__get_user(epc, &fr->epc)) {		/* Saved EPC */
+		/* This is not a good situation to be in */
+		force_sig(SIGBUS, current);
+
+		return 0;
+	}
+
+	/* Set EPC to return to post-branch instruction */
+	xcp->cp0_epc = epc;
+
+	return 1;
+}
diff --git a/arch/mips/math-emu/dsemul.h b/arch/mips/math-emu/dsemul.h
new file mode 100644
index 0000000..dbd85f9
--- /dev/null
+++ b/arch/mips/math-emu/dsemul.h
@@ -0,0 +1,23 @@
+typedef long gpreg_t;
+typedef void *vaddr_t;
+
+#define REG_TO_VA (vaddr_t)
+#define VA_TO_REG (gpreg_t)
+
+int mips_dsemul(struct pt_regs *regs, mips_instruction ir, gpreg_t cpc);
+int do_dsemulret(struct pt_regs *xcp);
+
+/* Instruction which will always cause an address error */
+#define AdELOAD 0x8c000001	/* lw $0,1($0) */
+/* Instruction which will plainly cause a CP1 exception when FPU is disabled */
+#define CP1UNDEF 0x44400001    /* cfc1 $0,$0 undef  */
+
+/* Instruction inserted following the badinst to further tag the sequence */
+#define BD_COOKIE 0x0000bd36 /* tne $0,$0 with baggage */
+
+/* Setup which instruction to use for trampoline */
+#ifdef STANDALONE_EMULATOR
+#define BADINST CP1UNDEF
+#else
+#define BADINST AdELOAD
+#endif
diff --git a/arch/mips/math-emu/ieee754.c b/arch/mips/math-emu/ieee754.c
new file mode 100644
index 0000000..f0a364a
--- /dev/null
+++ b/arch/mips/math-emu/ieee754.c
@@ -0,0 +1,138 @@
+/* ieee754 floating point arithmetic
+ * single and double precision
+ *
+ * BUGS
+ * not much dp done
+ * doesn't generate IEEE754_INEXACT
+ *
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754int.h"
+
+#define DP_EBIAS	1023
+#define DP_EMIN		(-1022)
+#define DP_EMAX		1023
+
+#define SP_EBIAS	127
+#define SP_EMIN		(-126)
+#define SP_EMAX		127
+
+/* indexed by class */
+const char *const ieee754_cname[] = {
+	"Normal",
+	"Zero",
+	"Denormal",
+	"Infinity",
+	"QNaN",
+	"SNaN",
+};
+
+/* the control status register
+*/
+struct ieee754_csr ieee754_csr;
+
+/* special constants
+*/
+
+
+#if (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) || defined(__MIPSEL__)
+#define SPSTR(s,b,m) {m,b,s}
+#define DPSTR(s,b,mh,ml) {ml,mh,b,s}
+#endif
+
+#ifdef __MIPSEB__
+#define SPSTR(s,b,m) {s,b,m}
+#define DPSTR(s,b,mh,ml) {s,b,mh,ml}
+#endif
+
+const struct ieee754dp_konst __ieee754dp_spcvals[] = {
+	DPSTR(0, DP_EMIN - 1 + DP_EBIAS, 0, 0),	/* + zero   */
+	DPSTR(1, DP_EMIN - 1 + DP_EBIAS, 0, 0),	/* - zero   */
+	DPSTR(0, DP_EBIAS, 0, 0),	/* + 1.0   */
+	DPSTR(1, DP_EBIAS, 0, 0),	/* - 1.0   */
+	DPSTR(0, 3 + DP_EBIAS, 0x40000, 0),	/* + 10.0   */
+	DPSTR(1, 3 + DP_EBIAS, 0x40000, 0),	/* - 10.0   */
+	DPSTR(0, DP_EMAX + 1 + DP_EBIAS, 0, 0),	/* + infinity */
+	DPSTR(1, DP_EMAX + 1 + DP_EBIAS, 0, 0),	/* - infinity */
+	DPSTR(0,DP_EMAX+1+DP_EBIAS,0x7FFFF,0xFFFFFFFF), /* + indef quiet Nan */
+	DPSTR(0, DP_EMAX + DP_EBIAS, 0xFFFFF, 0xFFFFFFFF),	/* + max */
+	DPSTR(1, DP_EMAX + DP_EBIAS, 0xFFFFF, 0xFFFFFFFF),	/* - max */
+	DPSTR(0, DP_EMIN + DP_EBIAS, 0, 0),	/* + min normal */
+	DPSTR(1, DP_EMIN + DP_EBIAS, 0, 0),	/* - min normal */
+	DPSTR(0, DP_EMIN - 1 + DP_EBIAS, 0, 1),	/* + min denormal */
+	DPSTR(1, DP_EMIN - 1 + DP_EBIAS, 0, 1),	/* - min denormal */
+	DPSTR(0, 31 + DP_EBIAS, 0, 0),	/* + 1.0e31 */
+	DPSTR(0, 63 + DP_EBIAS, 0, 0),	/* + 1.0e63 */
+};
+
+const struct ieee754sp_konst __ieee754sp_spcvals[] = {
+	SPSTR(0, SP_EMIN - 1 + SP_EBIAS, 0),	/* + zero   */
+	SPSTR(1, SP_EMIN - 1 + SP_EBIAS, 0),	/* - zero   */
+	SPSTR(0, SP_EBIAS, 0),	/* + 1.0   */
+	SPSTR(1, SP_EBIAS, 0),	/* - 1.0   */
+	SPSTR(0, 3 + SP_EBIAS, 0x200000),	/* + 10.0   */
+	SPSTR(1, 3 + SP_EBIAS, 0x200000),	/* - 10.0   */
+	SPSTR(0, SP_EMAX + 1 + SP_EBIAS, 0),	/* + infinity */
+	SPSTR(1, SP_EMAX + 1 + SP_EBIAS, 0),	/* - infinity */
+	SPSTR(0,SP_EMAX+1+SP_EBIAS,0x3FFFFF),     /* + indef quiet Nan  */
+	SPSTR(0, SP_EMAX + SP_EBIAS, 0x7FFFFF),	/* + max normal */
+	SPSTR(1, SP_EMAX + SP_EBIAS, 0x7FFFFF),	/* - max normal */
+	SPSTR(0, SP_EMIN + SP_EBIAS, 0),	/* + min normal */
+	SPSTR(1, SP_EMIN + SP_EBIAS, 0),	/* - min normal */
+	SPSTR(0, SP_EMIN - 1 + SP_EBIAS, 1),	/* + min denormal */
+	SPSTR(1, SP_EMIN - 1 + SP_EBIAS, 1),	/* - min denormal */
+	SPSTR(0, 31 + SP_EBIAS, 0),	/* + 1.0e31 */
+	SPSTR(0, 63 + SP_EBIAS, 0),	/* + 1.0e63 */
+};
+
+
+int ieee754si_xcpt(int r, const char *op, ...)
+{
+	struct ieee754xctx ax;
+
+	if (!TSTX())
+		return r;
+	ax.op = op;
+	ax.rt = IEEE754_RT_SI;
+	ax.rv.si = r;
+	va_start(ax.ap, op);
+	ieee754_xcpt(&ax);
+	return ax.rv.si;
+}
+
+s64 ieee754di_xcpt(s64 r, const char *op, ...)
+{
+	struct ieee754xctx ax;
+
+	if (!TSTX())
+		return r;
+	ax.op = op;
+	ax.rt = IEEE754_RT_DI;
+	ax.rv.di = r;
+	va_start(ax.ap, op);
+	ieee754_xcpt(&ax);
+	return ax.rv.di;
+}
diff --git a/arch/mips/math-emu/ieee754.h b/arch/mips/math-emu/ieee754.h
new file mode 100644
index 0000000..b8772f4
--- /dev/null
+++ b/arch/mips/math-emu/ieee754.h
@@ -0,0 +1,489 @@
+/* single and double precision fp ops
+ * missing extended precision.
+*/
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+/**************************************************************************
+ *  Nov 7, 2000
+ *  Modification to allow integration with Linux kernel
+ *
+ *  Kevin D. Kissell, kevink@mips.com and Carsten Langgard, carstenl@mips.com
+ *  Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ *************************************************************************/
+
+#ifdef __KERNEL__
+/* Going from Algorithmics to Linux native environment, add this */
+#include <linux/types.h>
+
+/*
+ * Not very pretty, but the Linux kernel's normal va_list definition
+ * does not allow it to be used as a structure element, as it is here.
+ */
+#ifndef _STDARG_H
+#include <stdarg.h>
+#endif
+
+#else
+
+/* Note that __KERNEL__ is taken to mean Linux kernel */
+
+#if #system(OpenBSD)
+#include <machine/types.h>
+#endif
+#include <machine/endian.h>
+
+#endif				/* __KERNEL__ */
+
+#if (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) || defined(__MIPSEL__)
+struct ieee754dp_konst {
+	unsigned mantlo:32;
+	unsigned manthi:20;
+	unsigned bexp:11;
+	unsigned sign:1;
+};
+struct ieee754sp_konst {
+	unsigned mant:23;
+	unsigned bexp:8;
+	unsigned sign:1;
+};
+
+typedef union _ieee754dp {
+	struct ieee754dp_konst oparts;
+	struct {
+		u64 mant:52;
+		unsigned int bexp:11;
+		unsigned int sign:1;
+	} parts;
+	u64 bits;
+	double d;
+} ieee754dp;
+
+typedef union _ieee754sp {
+	struct ieee754sp_konst parts;
+	float f;
+	u32 bits;
+} ieee754sp;
+#endif
+
+#if (defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) || defined(__MIPSEB__)
+struct ieee754dp_konst {
+	unsigned sign:1;
+	unsigned bexp:11;
+	unsigned manthi:20;
+	unsigned mantlo:32;
+};
+typedef union _ieee754dp {
+	struct ieee754dp_konst oparts;
+	struct {
+		unsigned int sign:1;
+		unsigned int bexp:11;
+		u64 mant:52;
+	} parts;
+	double d;
+	u64 bits;
+} ieee754dp;
+
+struct ieee754sp_konst {
+	unsigned sign:1;
+	unsigned bexp:8;
+	unsigned mant:23;
+};
+
+typedef union _ieee754sp {
+	struct ieee754sp_konst parts;
+	float f;
+	u32 bits;
+} ieee754sp;
+#endif
+
+/*
+ * single precision (often aka float)
+*/
+int ieee754sp_finite(ieee754sp x);
+int ieee754sp_class(ieee754sp x);
+
+ieee754sp ieee754sp_abs(ieee754sp x);
+ieee754sp ieee754sp_neg(ieee754sp x);
+ieee754sp ieee754sp_scalb(ieee754sp x, int);
+ieee754sp ieee754sp_logb(ieee754sp x);
+
+/* x with sign of y */
+ieee754sp ieee754sp_copysign(ieee754sp x, ieee754sp y);
+
+ieee754sp ieee754sp_add(ieee754sp x, ieee754sp y);
+ieee754sp ieee754sp_sub(ieee754sp x, ieee754sp y);
+ieee754sp ieee754sp_mul(ieee754sp x, ieee754sp y);
+ieee754sp ieee754sp_div(ieee754sp x, ieee754sp y);
+
+ieee754sp ieee754sp_fint(int x);
+ieee754sp ieee754sp_funs(unsigned x);
+ieee754sp ieee754sp_flong(s64 x);
+ieee754sp ieee754sp_fulong(u64 x);
+ieee754sp ieee754sp_fdp(ieee754dp x);
+
+int ieee754sp_tint(ieee754sp x);
+unsigned int ieee754sp_tuns(ieee754sp x);
+s64 ieee754sp_tlong(ieee754sp x);
+u64 ieee754sp_tulong(ieee754sp x);
+
+int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cop, int sig);
+/*
+ * basic sp math
+ */
+ieee754sp ieee754sp_modf(ieee754sp x, ieee754sp * ip);
+ieee754sp ieee754sp_frexp(ieee754sp x, int *exp);
+ieee754sp ieee754sp_ldexp(ieee754sp x, int exp);
+
+ieee754sp ieee754sp_ceil(ieee754sp x);
+ieee754sp ieee754sp_floor(ieee754sp x);
+ieee754sp ieee754sp_trunc(ieee754sp x);
+
+ieee754sp ieee754sp_sqrt(ieee754sp x);
+
+/*
+ * double precision (often aka double)
+*/
+int ieee754dp_finite(ieee754dp x);
+int ieee754dp_class(ieee754dp x);
+
+/* x with sign of y */
+ieee754dp ieee754dp_copysign(ieee754dp x, ieee754dp y);
+
+ieee754dp ieee754dp_add(ieee754dp x, ieee754dp y);
+ieee754dp ieee754dp_sub(ieee754dp x, ieee754dp y);
+ieee754dp ieee754dp_mul(ieee754dp x, ieee754dp y);
+ieee754dp ieee754dp_div(ieee754dp x, ieee754dp y);
+
+ieee754dp ieee754dp_abs(ieee754dp x);
+ieee754dp ieee754dp_neg(ieee754dp x);
+ieee754dp ieee754dp_scalb(ieee754dp x, int);
+
+/* return exponent as integer in floating point format
+ */
+ieee754dp ieee754dp_logb(ieee754dp x);
+
+ieee754dp ieee754dp_fint(int x);
+ieee754dp ieee754dp_funs(unsigned x);
+ieee754dp ieee754dp_flong(s64 x);
+ieee754dp ieee754dp_fulong(u64 x);
+ieee754dp ieee754dp_fsp(ieee754sp x);
+
+ieee754dp ieee754dp_ceil(ieee754dp x);
+ieee754dp ieee754dp_floor(ieee754dp x);
+ieee754dp ieee754dp_trunc(ieee754dp x);
+
+int ieee754dp_tint(ieee754dp x);
+unsigned int ieee754dp_tuns(ieee754dp x);
+s64 ieee754dp_tlong(ieee754dp x);
+u64 ieee754dp_tulong(ieee754dp x);
+
+int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cop, int sig);
+/*
+ * basic sp math
+ */
+ieee754dp ieee754dp_modf(ieee754dp x, ieee754dp * ip);
+ieee754dp ieee754dp_frexp(ieee754dp x, int *exp);
+ieee754dp ieee754dp_ldexp(ieee754dp x, int exp);
+
+ieee754dp ieee754dp_ceil(ieee754dp x);
+ieee754dp ieee754dp_floor(ieee754dp x);
+ieee754dp ieee754dp_trunc(ieee754dp x);
+
+ieee754dp ieee754dp_sqrt(ieee754dp x);
+
+
+
+/* 5 types of floating point number
+*/
+#define IEEE754_CLASS_NORM	0x00
+#define IEEE754_CLASS_ZERO	0x01
+#define IEEE754_CLASS_DNORM	0x02
+#define IEEE754_CLASS_INF	0x03
+#define IEEE754_CLASS_SNAN	0x04
+#define IEEE754_CLASS_QNAN	0x05
+extern const char *const ieee754_cname[];
+
+/* exception numbers */
+#define IEEE754_INEXACT			0x01
+#define IEEE754_UNDERFLOW		0x02
+#define IEEE754_OVERFLOW		0x04
+#define IEEE754_ZERO_DIVIDE		0x08
+#define IEEE754_INVALID_OPERATION	0x10
+
+/* cmp operators
+*/
+#define IEEE754_CLT	0x01
+#define IEEE754_CEQ	0x02
+#define IEEE754_CGT	0x04
+#define IEEE754_CUN	0x08
+
+/* rounding mode
+*/
+#define IEEE754_RN	0	/* round to nearest */
+#define IEEE754_RZ	1	/* round toward zero  */
+#define IEEE754_RD	2	/* round toward -Infinity */
+#define IEEE754_RU	3	/* round toward +Infinity */
+
+/* other naming */
+#define IEEE754_RM	IEEE754_RD
+#define IEEE754_RP	IEEE754_RU
+
+/* "normal" comparisons
+*/
+static __inline int ieee754sp_eq(ieee754sp x, ieee754sp y)
+{
+	return ieee754sp_cmp(x, y, IEEE754_CEQ, 0);
+}
+
+static __inline int ieee754sp_ne(ieee754sp x, ieee754sp y)
+{
+	return ieee754sp_cmp(x, y,
+			     IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0);
+}
+
+static __inline int ieee754sp_lt(ieee754sp x, ieee754sp y)
+{
+	return ieee754sp_cmp(x, y, IEEE754_CLT, 0);
+}
+
+static __inline int ieee754sp_le(ieee754sp x, ieee754sp y)
+{
+	return ieee754sp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0);
+}
+
+static __inline int ieee754sp_gt(ieee754sp x, ieee754sp y)
+{
+	return ieee754sp_cmp(x, y, IEEE754_CGT, 0);
+}
+
+
+static __inline int ieee754sp_ge(ieee754sp x, ieee754sp y)
+{
+	return ieee754sp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0);
+}
+
+static __inline int ieee754dp_eq(ieee754dp x, ieee754dp y)
+{
+	return ieee754dp_cmp(x, y, IEEE754_CEQ, 0);
+}
+
+static __inline int ieee754dp_ne(ieee754dp x, ieee754dp y)
+{
+	return ieee754dp_cmp(x, y,
+			     IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0);
+}
+
+static __inline int ieee754dp_lt(ieee754dp x, ieee754dp y)
+{
+	return ieee754dp_cmp(x, y, IEEE754_CLT, 0);
+}
+
+static __inline int ieee754dp_le(ieee754dp x, ieee754dp y)
+{
+	return ieee754dp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0);
+}
+
+static __inline int ieee754dp_gt(ieee754dp x, ieee754dp y)
+{
+	return ieee754dp_cmp(x, y, IEEE754_CGT, 0);
+}
+
+static __inline int ieee754dp_ge(ieee754dp x, ieee754dp y)
+{
+	return ieee754dp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0);
+}
+
+
+/* like strtod
+*/
+ieee754dp ieee754dp_fstr(const char *s, char **endp);
+char *ieee754dp_tstr(ieee754dp x, int prec, int fmt, int af);
+
+
+/* the control status register
+*/
+struct ieee754_csr {
+	unsigned pad:13;
+	unsigned nod:1;		/* set 1 for no denormalised numbers */
+	unsigned cx:5;		/* exceptions this operation */
+	unsigned mx:5;		/* exception enable  mask */
+	unsigned sx:5;		/* exceptions total */
+	unsigned rm:2;		/* current rounding mode */
+};
+extern struct ieee754_csr ieee754_csr;
+
+static __inline unsigned ieee754_getrm(void)
+{
+	return (ieee754_csr.rm);
+}
+static __inline unsigned ieee754_setrm(unsigned rm)
+{
+	return (ieee754_csr.rm = rm);
+}
+
+/*
+ * get current exceptions
+ */
+static __inline unsigned ieee754_getcx(void)
+{
+	return (ieee754_csr.cx);
+}
+
+/* test for current exception condition
+ */
+static __inline int ieee754_cxtest(unsigned n)
+{
+	return (ieee754_csr.cx & n);
+}
+
+/*
+ * get sticky exceptions
+ */
+static __inline unsigned ieee754_getsx(void)
+{
+	return (ieee754_csr.sx);
+}
+
+/* clear sticky conditions
+*/
+static __inline unsigned ieee754_clrsx(void)
+{
+	return (ieee754_csr.sx = 0);
+}
+
+/* test for sticky exception condition
+ */
+static __inline int ieee754_sxtest(unsigned n)
+{
+	return (ieee754_csr.sx & n);
+}
+
+/* debugging */
+ieee754sp ieee754sp_dump(char *s, ieee754sp x);
+ieee754dp ieee754dp_dump(char *s, ieee754dp x);
+
+#define IEEE754_SPCVAL_PZERO	0
+#define IEEE754_SPCVAL_NZERO	1
+#define IEEE754_SPCVAL_PONE	2
+#define IEEE754_SPCVAL_NONE	3
+#define IEEE754_SPCVAL_PTEN	4
+#define IEEE754_SPCVAL_NTEN	5
+#define IEEE754_SPCVAL_PINFINITY	6
+#define IEEE754_SPCVAL_NINFINITY	7
+#define IEEE754_SPCVAL_INDEF	8
+#define IEEE754_SPCVAL_PMAX	9	/* +max norm */
+#define IEEE754_SPCVAL_NMAX	10	/* -max norm */
+#define IEEE754_SPCVAL_PMIN	11	/* +min norm */
+#define IEEE754_SPCVAL_NMIN	12	/* +min norm */
+#define IEEE754_SPCVAL_PMIND	13	/* +min denorm */
+#define IEEE754_SPCVAL_NMIND	14	/* +min denorm */
+#define IEEE754_SPCVAL_P1E31	15	/* + 1.0e31 */
+#define IEEE754_SPCVAL_P1E63	16	/* + 1.0e63 */
+
+extern const struct ieee754dp_konst __ieee754dp_spcvals[];
+extern const struct ieee754sp_konst __ieee754sp_spcvals[];
+#define ieee754dp_spcvals ((const ieee754dp *)__ieee754dp_spcvals)
+#define ieee754sp_spcvals ((const ieee754sp *)__ieee754sp_spcvals)
+
+/* return infinity with given sign
+*/
+#define ieee754dp_inf(sn)	\
+  (ieee754dp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
+#define ieee754dp_zero(sn) \
+  (ieee754dp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
+#define ieee754dp_one(sn) \
+  (ieee754dp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
+#define ieee754dp_ten(sn) \
+  (ieee754dp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
+#define ieee754dp_indef() \
+  (ieee754dp_spcvals[IEEE754_SPCVAL_INDEF])
+#define ieee754dp_max(sn) \
+  (ieee754dp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
+#define ieee754dp_min(sn) \
+  (ieee754dp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
+#define ieee754dp_mind(sn) \
+  (ieee754dp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
+#define ieee754dp_1e31() \
+  (ieee754dp_spcvals[IEEE754_SPCVAL_P1E31])
+#define ieee754dp_1e63() \
+  (ieee754dp_spcvals[IEEE754_SPCVAL_P1E63])
+
+#define ieee754sp_inf(sn) \
+  (ieee754sp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
+#define ieee754sp_zero(sn) \
+  (ieee754sp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
+#define ieee754sp_one(sn) \
+  (ieee754sp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
+#define ieee754sp_ten(sn) \
+  (ieee754sp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
+#define ieee754sp_indef() \
+  (ieee754sp_spcvals[IEEE754_SPCVAL_INDEF])
+#define ieee754sp_max(sn) \
+  (ieee754sp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
+#define ieee754sp_min(sn) \
+  (ieee754sp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
+#define ieee754sp_mind(sn) \
+  (ieee754sp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
+#define ieee754sp_1e31() \
+  (ieee754sp_spcvals[IEEE754_SPCVAL_P1E31])
+#define ieee754sp_1e63() \
+  (ieee754sp_spcvals[IEEE754_SPCVAL_P1E63])
+
+/* indefinite integer value
+*/
+#define ieee754si_indef()	INT_MAX
+#ifdef LONG_LONG_MAX
+#define ieee754di_indef()	LONG_LONG_MAX
+#else
+#define ieee754di_indef()	((s64)(~0ULL>>1))
+#endif
+
+/* IEEE exception context, passed to handler */
+struct ieee754xctx {
+	const char *op;		/* operation name */
+	int rt;			/* result type */
+	union {
+		ieee754sp sp;	/* single precision */
+		ieee754dp dp;	/* double precision */
+#ifdef IEEE854_XP
+		ieee754xp xp;	/* extended precision */
+#endif
+		int si;		/* standard signed integer (32bits) */
+		s64 di;		/* extended signed integer (64bits) */
+	} rv;			/* default result format implied by op */
+	va_list ap;
+};
+
+/* result types for xctx.rt */
+#define IEEE754_RT_SP	0
+#define IEEE754_RT_DP	1
+#define IEEE754_RT_XP	2
+#define IEEE754_RT_SI	3
+#define IEEE754_RT_DI	4
+
+extern void ieee754_xcpt(struct ieee754xctx *xcp);
+
+/* compat */
+#define ieee754dp_fix(x)	ieee754dp_tint(x)
+#define ieee754sp_fix(x)	ieee754sp_tint(x)
diff --git a/arch/mips/math-emu/ieee754d.c b/arch/mips/math-emu/ieee754d.c
new file mode 100644
index 0000000..7e900f3
--- /dev/null
+++ b/arch/mips/math-emu/ieee754d.c
@@ -0,0 +1,138 @@
+/*
+ * Some debug functions
+ *
+ * MIPS floating point support
+ *
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ *  Nov 7, 2000
+ *  Modified to build and operate in Linux kernel environment.
+ *
+ *  Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ *  Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ */
+
+#include <linux/kernel.h>
+#include "ieee754.h"
+
+#define DP_EBIAS	1023
+#define DP_EMIN		(-1022)
+#define DP_EMAX		1023
+#define DP_FBITS	52
+
+#define SP_EBIAS	127
+#define SP_EMIN		(-126)
+#define SP_EMAX		127
+#define SP_FBITS	23
+
+#define DP_MBIT(x)	((u64)1 << (x))
+#define DP_HIDDEN_BIT	DP_MBIT(DP_FBITS)
+#define DP_SIGN_BIT	DP_MBIT(63)
+
+
+#define SP_MBIT(x)	((u32)1 << (x))
+#define SP_HIDDEN_BIT	SP_MBIT(SP_FBITS)
+#define SP_SIGN_BIT	SP_MBIT(31)
+
+
+#define SPSIGN(sp)	(sp.parts.sign)
+#define SPBEXP(sp)	(sp.parts.bexp)
+#define SPMANT(sp)	(sp.parts.mant)
+
+#define DPSIGN(dp)	(dp.parts.sign)
+#define DPBEXP(dp)	(dp.parts.bexp)
+#define DPMANT(dp)	(dp.parts.mant)
+
+ieee754dp ieee754dp_dump(char *m, ieee754dp x)
+{
+	int i;
+
+	printk("%s", m);
+	printk("<%08x,%08x>\n", (unsigned) (x.bits >> 32),
+	       (unsigned) x.bits);
+	printk("\t=");
+	switch (ieee754dp_class(x)) {
+	case IEEE754_CLASS_QNAN:
+	case IEEE754_CLASS_SNAN:
+		printk("Nan %c", DPSIGN(x) ? '-' : '+');
+		for (i = DP_FBITS - 1; i >= 0; i--)
+			printk("%c", DPMANT(x) & DP_MBIT(i) ? '1' : '0');
+		break;
+	case IEEE754_CLASS_INF:
+		printk("%cInfinity", DPSIGN(x) ? '-' : '+');
+		break;
+	case IEEE754_CLASS_ZERO:
+		printk("%cZero", DPSIGN(x) ? '-' : '+');
+		break;
+	case IEEE754_CLASS_DNORM:
+		printk("%c0.", DPSIGN(x) ? '-' : '+');
+		for (i = DP_FBITS - 1; i >= 0; i--)
+			printk("%c", DPMANT(x) & DP_MBIT(i) ? '1' : '0');
+		printk("e%d", DPBEXP(x) - DP_EBIAS);
+		break;
+	case IEEE754_CLASS_NORM:
+		printk("%c1.", DPSIGN(x) ? '-' : '+');
+		for (i = DP_FBITS - 1; i >= 0; i--)
+			printk("%c", DPMANT(x) & DP_MBIT(i) ? '1' : '0');
+		printk("e%d", DPBEXP(x) - DP_EBIAS);
+		break;
+	default:
+		printk("Illegal/Unknown IEEE754 value class");
+	}
+	printk("\n");
+	return x;
+}
+
+ieee754sp ieee754sp_dump(char *m, ieee754sp x)
+{
+	int i;
+
+	printk("%s=", m);
+	printk("<%08x>\n", (unsigned) x.bits);
+	printk("\t=");
+	switch (ieee754sp_class(x)) {
+	case IEEE754_CLASS_QNAN:
+	case IEEE754_CLASS_SNAN:
+		printk("Nan %c", SPSIGN(x) ? '-' : '+');
+		for (i = SP_FBITS - 1; i >= 0; i--)
+			printk("%c", SPMANT(x) & SP_MBIT(i) ? '1' : '0');
+		break;
+	case IEEE754_CLASS_INF:
+		printk("%cInfinity", SPSIGN(x) ? '-' : '+');
+		break;
+	case IEEE754_CLASS_ZERO:
+		printk("%cZero", SPSIGN(x) ? '-' : '+');
+		break;
+	case IEEE754_CLASS_DNORM:
+		printk("%c0.", SPSIGN(x) ? '-' : '+');
+		for (i = SP_FBITS - 1; i >= 0; i--)
+			printk("%c", SPMANT(x) & SP_MBIT(i) ? '1' : '0');
+		printk("e%d", SPBEXP(x) - SP_EBIAS);
+		break;
+	case IEEE754_CLASS_NORM:
+		printk("%c1.", SPSIGN(x) ? '-' : '+');
+		for (i = SP_FBITS - 1; i >= 0; i--)
+			printk("%c", SPMANT(x) & SP_MBIT(i) ? '1' : '0');
+		printk("e%d", SPBEXP(x) - SP_EBIAS);
+		break;
+	default:
+		printk("Illegal/Unknown IEEE754 value class");
+	}
+	printk("\n");
+	return x;
+}
+
diff --git a/arch/mips/math-emu/ieee754dp.c b/arch/mips/math-emu/ieee754dp.c
new file mode 100644
index 0000000..3e214aa
--- /dev/null
+++ b/arch/mips/math-emu/ieee754dp.c
@@ -0,0 +1,243 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+int ieee754dp_class(ieee754dp x)
+{
+	COMPXDP;
+	EXPLODEXDP;
+	return xc;
+}
+
+int ieee754dp_isnan(ieee754dp x)
+{
+	return ieee754dp_class(x) >= IEEE754_CLASS_SNAN;
+}
+
+int ieee754dp_issnan(ieee754dp x)
+{
+	assert(ieee754dp_isnan(x));
+	return ((DPMANT(x) & DP_MBIT(DP_MBITS-1)) == DP_MBIT(DP_MBITS-1));
+}
+
+
+ieee754dp ieee754dp_xcpt(ieee754dp r, const char *op, ...)
+{
+	struct ieee754xctx ax;
+	if (!TSTX())
+		return r;
+
+	ax.op = op;
+	ax.rt = IEEE754_RT_DP;
+	ax.rv.dp = r;
+	va_start(ax.ap, op);
+	ieee754_xcpt(&ax);
+	return ax.rv.dp;
+}
+
+ieee754dp ieee754dp_nanxcpt(ieee754dp r, const char *op, ...)
+{
+	struct ieee754xctx ax;
+
+	assert(ieee754dp_isnan(r));
+
+	if (!ieee754dp_issnan(r))	/* QNAN does not cause invalid op !! */
+		return r;
+
+	if (!SETANDTESTCX(IEEE754_INVALID_OPERATION)) {
+		/* not enabled convert to a quiet NaN */
+		DPMANT(r) &= (~DP_MBIT(DP_MBITS-1));
+		if (ieee754dp_isnan(r))
+			return r;
+		else
+			return ieee754dp_indef();
+	}
+
+	ax.op = op;
+	ax.rt = 0;
+	ax.rv.dp = r;
+	va_start(ax.ap, op);
+	ieee754_xcpt(&ax);
+	return ax.rv.dp;
+}
+
+ieee754dp ieee754dp_bestnan(ieee754dp x, ieee754dp y)
+{
+	assert(ieee754dp_isnan(x));
+	assert(ieee754dp_isnan(y));
+
+	if (DPMANT(x) > DPMANT(y))
+		return x;
+	else
+		return y;
+}
+
+
+static u64 get_rounding(int sn, u64 xm)
+{
+	/* inexact must round of 3 bits
+	 */
+	if (xm & (DP_MBIT(3) - 1)) {
+		switch (ieee754_csr.rm) {
+		case IEEE754_RZ:
+			break;
+		case IEEE754_RN:
+			xm += 0x3 + ((xm >> 3) & 1);
+			/* xm += (xm&0x8)?0x4:0x3 */
+			break;
+		case IEEE754_RU:	/* toward +Infinity */
+			if (!sn)	/* ?? */
+				xm += 0x8;
+			break;
+		case IEEE754_RD:	/* toward -Infinity */
+			if (sn)	/* ?? */
+				xm += 0x8;
+			break;
+		}
+	}
+	return xm;
+}
+
+
+/* generate a normal/denormal number with over,under handling
+ * sn is sign
+ * xe is an unbiased exponent
+ * xm is 3bit extended precision value.
+ */
+ieee754dp ieee754dp_format(int sn, int xe, u64 xm)
+{
+	assert(xm);		/* we don't gen exact zeros (probably should) */
+
+	assert((xm >> (DP_MBITS + 1 + 3)) == 0);	/* no execess */
+	assert(xm & (DP_HIDDEN_BIT << 3));
+
+	if (xe < DP_EMIN) {
+		/* strip lower bits */
+		int es = DP_EMIN - xe;
+
+		if (ieee754_csr.nod) {
+			SETCX(IEEE754_UNDERFLOW);
+			SETCX(IEEE754_INEXACT);
+
+			switch(ieee754_csr.rm) {
+			case IEEE754_RN:
+				return ieee754dp_zero(sn);
+			case IEEE754_RZ:
+				return ieee754dp_zero(sn);
+			case IEEE754_RU:    /* toward +Infinity */
+				if(sn == 0)
+					return ieee754dp_min(0);
+				else
+					return ieee754dp_zero(1);
+			case IEEE754_RD:    /* toward -Infinity */
+				if(sn == 0)
+					return ieee754dp_zero(0);
+				else
+					return ieee754dp_min(1);
+			}
+		}
+
+		if (xe == DP_EMIN - 1
+				&& get_rounding(sn, xm) >> (DP_MBITS + 1 + 3))
+		{
+			/* Not tiny after rounding */
+			SETCX(IEEE754_INEXACT);
+			xm = get_rounding(sn, xm);
+			xm >>= 1;
+			/* Clear grs bits */
+			xm &= ~(DP_MBIT(3) - 1);
+			xe++;
+		}
+		else {
+			/* sticky right shift es bits
+			 */
+			xm = XDPSRS(xm, es);
+			xe += es;
+			assert((xm & (DP_HIDDEN_BIT << 3)) == 0);
+			assert(xe == DP_EMIN);
+		}
+	}
+	if (xm & (DP_MBIT(3) - 1)) {
+		SETCX(IEEE754_INEXACT);
+		if ((xm & (DP_HIDDEN_BIT << 3)) == 0) {
+			SETCX(IEEE754_UNDERFLOW);
+		}
+
+		/* inexact must round of 3 bits
+		 */
+		xm = get_rounding(sn, xm);
+		/* adjust exponent for rounding add overflowing
+		 */
+		if (xm >> (DP_MBITS + 3 + 1)) {
+			/* add causes mantissa overflow */
+			xm >>= 1;
+			xe++;
+		}
+	}
+	/* strip grs bits */
+	xm >>= 3;
+
+	assert((xm >> (DP_MBITS + 1)) == 0);	/* no execess */
+	assert(xe >= DP_EMIN);
+
+	if (xe > DP_EMAX) {
+		SETCX(IEEE754_OVERFLOW);
+		SETCX(IEEE754_INEXACT);
+		/* -O can be table indexed by (rm,sn) */
+		switch (ieee754_csr.rm) {
+		case IEEE754_RN:
+			return ieee754dp_inf(sn);
+		case IEEE754_RZ:
+			return ieee754dp_max(sn);
+		case IEEE754_RU:	/* toward +Infinity */
+			if (sn == 0)
+				return ieee754dp_inf(0);
+			else
+				return ieee754dp_max(1);
+		case IEEE754_RD:	/* toward -Infinity */
+			if (sn == 0)
+				return ieee754dp_max(0);
+			else
+				return ieee754dp_inf(1);
+		}
+	}
+	/* gen norm/denorm/zero */
+
+	if ((xm & DP_HIDDEN_BIT) == 0) {
+		/* we underflow (tiny/zero) */
+		assert(xe == DP_EMIN);
+		if (ieee754_csr.mx & IEEE754_UNDERFLOW)
+			SETCX(IEEE754_UNDERFLOW);
+		return builddp(sn, DP_EMIN - 1 + DP_EBIAS, xm);
+	} else {
+		assert((xm >> (DP_MBITS + 1)) == 0);	/* no execess */
+		assert(xm & DP_HIDDEN_BIT);
+
+		return builddp(sn, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
+	}
+}
diff --git a/arch/mips/math-emu/ieee754dp.h b/arch/mips/math-emu/ieee754dp.h
new file mode 100644
index 0000000..a37370d
--- /dev/null
+++ b/arch/mips/math-emu/ieee754dp.h
@@ -0,0 +1,83 @@
+/*
+ * IEEE754 floating point
+ * double precision internal header file
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754int.h"
+
+#define assert(expr) ((void)0)
+
+/* 3bit extended double precision sticky right shift */
+#define XDPSRS(v,rs)	\
+  ((rs > (DP_MBITS+3))?1:((v) >> (rs)) | ((v) << (64-(rs)) != 0))
+
+#define XDPSRSX1() \
+  (xe++, (xm = (xm >> 1) | (xm & 1)))
+
+#define XDPSRS1(v)	\
+  (((v) >> 1) | ((v) & 1))
+
+/* convert denormal to normalized with extended exponent */
+#define DPDNORMx(m,e) \
+  while( (m >> DP_MBITS) == 0) { m <<= 1; e--; }
+#define DPDNORMX	DPDNORMx(xm,xe)
+#define DPDNORMY	DPDNORMx(ym,ye)
+
+static __inline ieee754dp builddp(int s, int bx, u64 m)
+{
+	ieee754dp r;
+
+	assert((s) == 0 || (s) == 1);
+	assert((bx) >= DP_EMIN - 1 + DP_EBIAS
+	       && (bx) <= DP_EMAX + 1 + DP_EBIAS);
+	assert(((m) >> DP_MBITS) == 0);
+
+	r.parts.sign = s;
+	r.parts.bexp = bx;
+	r.parts.mant = m;
+	return r;
+}
+
+extern int ieee754dp_isnan(ieee754dp);
+extern int ieee754dp_issnan(ieee754dp);
+extern int ieee754si_xcpt(int, const char *, ...);
+extern s64 ieee754di_xcpt(s64, const char *, ...);
+extern ieee754dp ieee754dp_xcpt(ieee754dp, const char *, ...);
+extern ieee754dp ieee754dp_nanxcpt(ieee754dp, const char *, ...);
+extern ieee754dp ieee754dp_bestnan(ieee754dp, ieee754dp);
+extern ieee754dp ieee754dp_format(int, int, u64);
+
+
+#define DPNORMRET2(s,e,m,name,a0,a1) \
+{ \
+    ieee754dp V = ieee754dp_format(s,e,m); \
+    if(TSTX()) \
+      return ieee754dp_xcpt(V,name,a0,a1); \
+    else \
+      return V; \
+}
+
+#define DPNORMRET1(s,e,m,name,a0)  DPNORMRET2(s,e,m,name,a0,a0)
diff --git a/arch/mips/math-emu/ieee754int.h b/arch/mips/math-emu/ieee754int.h
new file mode 100644
index 0000000..4a5a81d
--- /dev/null
+++ b/arch/mips/math-emu/ieee754int.h
@@ -0,0 +1,165 @@
+/*
+ * IEEE754 floating point
+ * common internal header file
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754.h"
+
+#define DP_EBIAS	1023
+#define DP_EMIN		(-1022)
+#define DP_EMAX		1023
+#define DP_MBITS	52
+
+#define SP_EBIAS	127
+#define SP_EMIN		(-126)
+#define SP_EMAX		127
+#define SP_MBITS	23
+
+#define DP_MBIT(x)	((u64)1 << (x))
+#define DP_HIDDEN_BIT	DP_MBIT(DP_MBITS)
+#define DP_SIGN_BIT	DP_MBIT(63)
+
+#define SP_MBIT(x)	((u32)1 << (x))
+#define SP_HIDDEN_BIT	SP_MBIT(SP_MBITS)
+#define SP_SIGN_BIT	SP_MBIT(31)
+
+
+#define SPSIGN(sp)	(sp.parts.sign)
+#define SPBEXP(sp)	(sp.parts.bexp)
+#define SPMANT(sp)	(sp.parts.mant)
+
+#define DPSIGN(dp)	(dp.parts.sign)
+#define DPBEXP(dp)	(dp.parts.bexp)
+#define DPMANT(dp)	(dp.parts.mant)
+
+#define CLPAIR(x,y)	((x)*6+(y))
+
+#define CLEARCX	\
+  (ieee754_csr.cx = 0)
+
+#define SETCX(x) \
+  (ieee754_csr.cx |= (x),ieee754_csr.sx |= (x))
+
+#define SETANDTESTCX(x) \
+  (SETCX(x),ieee754_csr.mx & (x))
+
+#define TSTX()	\
+	(ieee754_csr.cx & ieee754_csr.mx)
+
+
+#define COMPXSP \
+  unsigned xm; int xe; int xs; int xc
+
+#define COMPYSP \
+  unsigned ym; int ye; int ys; int yc
+
+#define EXPLODESP(v,vc,vs,ve,vm) \
+{\
+    vs = SPSIGN(v);\
+    ve = SPBEXP(v);\
+    vm = SPMANT(v);\
+    if(ve == SP_EMAX+1+SP_EBIAS){\
+	if(vm == 0)\
+	  vc = IEEE754_CLASS_INF;\
+	else if(vm & SP_MBIT(SP_MBITS-1)) \
+	  vc = IEEE754_CLASS_SNAN;\
+	else \
+	  vc = IEEE754_CLASS_QNAN;\
+    } else if(ve == SP_EMIN-1+SP_EBIAS) {\
+	if(vm) {\
+	    ve = SP_EMIN;\
+	    vc = IEEE754_CLASS_DNORM;\
+	} else\
+	  vc = IEEE754_CLASS_ZERO;\
+    } else {\
+	ve -= SP_EBIAS;\
+	vm |= SP_HIDDEN_BIT;\
+	vc = IEEE754_CLASS_NORM;\
+    }\
+}
+#define EXPLODEXSP EXPLODESP(x,xc,xs,xe,xm)
+#define EXPLODEYSP EXPLODESP(y,yc,ys,ye,ym)
+
+
+#define COMPXDP \
+u64 xm; int xe; int xs; int xc
+
+#define COMPYDP \
+u64 ym; int ye; int ys; int yc
+
+#define EXPLODEDP(v,vc,vs,ve,vm) \
+{\
+    vm = DPMANT(v);\
+    vs = DPSIGN(v);\
+    ve = DPBEXP(v);\
+    if(ve == DP_EMAX+1+DP_EBIAS){\
+	if(vm == 0)\
+	  vc = IEEE754_CLASS_INF;\
+	else if(vm & DP_MBIT(DP_MBITS-1)) \
+	  vc = IEEE754_CLASS_SNAN;\
+	else \
+	  vc = IEEE754_CLASS_QNAN;\
+    } else if(ve == DP_EMIN-1+DP_EBIAS) {\
+	if(vm) {\
+	    ve = DP_EMIN;\
+	    vc = IEEE754_CLASS_DNORM;\
+	} else\
+	  vc = IEEE754_CLASS_ZERO;\
+    } else {\
+	ve -= DP_EBIAS;\
+	vm |= DP_HIDDEN_BIT;\
+	vc = IEEE754_CLASS_NORM;\
+    }\
+}
+#define EXPLODEXDP EXPLODEDP(x,xc,xs,xe,xm)
+#define EXPLODEYDP EXPLODEDP(y,yc,ys,ye,ym)
+
+#define FLUSHDP(v,vc,vs,ve,vm) \
+	if(vc==IEEE754_CLASS_DNORM) {\
+	    if(ieee754_csr.nod) {\
+		SETCX(IEEE754_INEXACT);\
+		vc = IEEE754_CLASS_ZERO;\
+		ve = DP_EMIN-1+DP_EBIAS;\
+		vm = 0;\
+		v = ieee754dp_zero(vs);\
+	    }\
+	}
+
+#define FLUSHSP(v,vc,vs,ve,vm) \
+	if(vc==IEEE754_CLASS_DNORM) {\
+	    if(ieee754_csr.nod) {\
+		SETCX(IEEE754_INEXACT);\
+		vc = IEEE754_CLASS_ZERO;\
+		ve = SP_EMIN-1+SP_EBIAS;\
+		vm = 0;\
+		v = ieee754sp_zero(vs);\
+	    }\
+	}
+
+#define FLUSHXDP FLUSHDP(x,xc,xs,xe,xm)
+#define FLUSHYDP FLUSHDP(y,yc,ys,ye,ym)
+#define FLUSHXSP FLUSHSP(x,xc,xs,xe,xm)
+#define FLUSHYSP FLUSHSP(y,yc,ys,ye,ym)
diff --git a/arch/mips/math-emu/ieee754m.c b/arch/mips/math-emu/ieee754m.c
new file mode 100644
index 0000000..d66896c
--- /dev/null
+++ b/arch/mips/math-emu/ieee754m.c
@@ -0,0 +1,56 @@
+/*
+ * floor, trunc, ceil
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754.h"
+
+ieee754dp ieee754dp_floor(ieee754dp x)
+{
+	ieee754dp i;
+
+	if (ieee754dp_lt(ieee754dp_modf(x, &i), ieee754dp_zero(0)))
+		return ieee754dp_sub(i, ieee754dp_one(0));
+	else
+		return i;
+}
+
+ieee754dp ieee754dp_ceil(ieee754dp x)
+{
+	ieee754dp i;
+
+	if (ieee754dp_gt(ieee754dp_modf(x, &i), ieee754dp_zero(0)))
+		return ieee754dp_add(i, ieee754dp_one(0));
+	else
+		return i;
+}
+
+ieee754dp ieee754dp_trunc(ieee754dp x)
+{
+	ieee754dp i;
+
+	(void) ieee754dp_modf(x, &i);
+	return i;
+}
diff --git a/arch/mips/math-emu/ieee754sp.c b/arch/mips/math-emu/ieee754sp.c
new file mode 100644
index 0000000..adda851
--- /dev/null
+++ b/arch/mips/math-emu/ieee754sp.c
@@ -0,0 +1,243 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+int ieee754sp_class(ieee754sp x)
+{
+	COMPXSP;
+	EXPLODEXSP;
+	return xc;
+}
+
+int ieee754sp_isnan(ieee754sp x)
+{
+	return ieee754sp_class(x) >= IEEE754_CLASS_SNAN;
+}
+
+int ieee754sp_issnan(ieee754sp x)
+{
+	assert(ieee754sp_isnan(x));
+	return (SPMANT(x) & SP_MBIT(SP_MBITS-1));
+}
+
+
+ieee754sp ieee754sp_xcpt(ieee754sp r, const char *op, ...)
+{
+	struct ieee754xctx ax;
+
+	if (!TSTX())
+		return r;
+
+	ax.op = op;
+	ax.rt = IEEE754_RT_SP;
+	ax.rv.sp = r;
+	va_start(ax.ap, op);
+	ieee754_xcpt(&ax);
+	return ax.rv.sp;
+}
+
+ieee754sp ieee754sp_nanxcpt(ieee754sp r, const char *op, ...)
+{
+	struct ieee754xctx ax;
+
+	assert(ieee754sp_isnan(r));
+
+	if (!ieee754sp_issnan(r))	/* QNAN does not cause invalid op !! */
+		return r;
+
+	if (!SETANDTESTCX(IEEE754_INVALID_OPERATION)) {
+		/* not enabled convert to a quiet NaN */
+		SPMANT(r) &= (~SP_MBIT(SP_MBITS-1));
+		if (ieee754sp_isnan(r))
+			return r;
+		else
+			return ieee754sp_indef();
+	}
+
+	ax.op = op;
+	ax.rt = 0;
+	ax.rv.sp = r;
+	va_start(ax.ap, op);
+	ieee754_xcpt(&ax);
+	return ax.rv.sp;
+}
+
+ieee754sp ieee754sp_bestnan(ieee754sp x, ieee754sp y)
+{
+	assert(ieee754sp_isnan(x));
+	assert(ieee754sp_isnan(y));
+
+	if (SPMANT(x) > SPMANT(y))
+		return x;
+	else
+		return y;
+}
+
+
+static unsigned get_rounding(int sn, unsigned xm)
+{
+	/* inexact must round of 3 bits
+	 */
+	if (xm & (SP_MBIT(3) - 1)) {
+		switch (ieee754_csr.rm) {
+		case IEEE754_RZ:
+			break;
+		case IEEE754_RN:
+			xm += 0x3 + ((xm >> 3) & 1);
+			/* xm += (xm&0x8)?0x4:0x3 */
+			break;
+		case IEEE754_RU:	/* toward +Infinity */
+			if (!sn)	/* ?? */
+				xm += 0x8;
+			break;
+		case IEEE754_RD:	/* toward -Infinity */
+			if (sn)	/* ?? */
+				xm += 0x8;
+			break;
+		}
+	}
+	return xm;
+}
+
+
+/* generate a normal/denormal number with over,under handling
+ * sn is sign
+ * xe is an unbiased exponent
+ * xm is 3bit extended precision value.
+ */
+ieee754sp ieee754sp_format(int sn, int xe, unsigned xm)
+{
+	assert(xm);		/* we don't gen exact zeros (probably should) */
+
+	assert((xm >> (SP_MBITS + 1 + 3)) == 0);	/* no execess */
+	assert(xm & (SP_HIDDEN_BIT << 3));
+
+	if (xe < SP_EMIN) {
+		/* strip lower bits */
+		int es = SP_EMIN - xe;
+
+		if (ieee754_csr.nod) {
+			SETCX(IEEE754_UNDERFLOW);
+			SETCX(IEEE754_INEXACT);
+
+			switch(ieee754_csr.rm) {
+			case IEEE754_RN:
+				return ieee754sp_zero(sn);
+			case IEEE754_RZ:
+				return ieee754sp_zero(sn);
+			case IEEE754_RU:      /* toward +Infinity */
+				if(sn == 0)
+					return ieee754sp_min(0);
+				else
+					return ieee754sp_zero(1);
+			case IEEE754_RD:      /* toward -Infinity */
+				if(sn == 0)
+					return ieee754sp_zero(0);
+				else
+					return ieee754sp_min(1);
+			}
+		}
+
+		if (xe == SP_EMIN - 1
+				&& get_rounding(sn, xm) >> (SP_MBITS + 1 + 3))
+		{
+			/* Not tiny after rounding */
+			SETCX(IEEE754_INEXACT);
+			xm = get_rounding(sn, xm);
+			xm >>= 1;
+			/* Clear grs bits */
+			xm &= ~(SP_MBIT(3) - 1);
+			xe++;
+		}
+		else {
+			/* sticky right shift es bits
+			 */
+			SPXSRSXn(es);
+			assert((xm & (SP_HIDDEN_BIT << 3)) == 0);
+			assert(xe == SP_EMIN);
+		}
+	}
+	if (xm & (SP_MBIT(3) - 1)) {
+		SETCX(IEEE754_INEXACT);
+		if ((xm & (SP_HIDDEN_BIT << 3)) == 0) {
+			SETCX(IEEE754_UNDERFLOW);
+		}
+
+		/* inexact must round of 3 bits
+		 */
+		xm = get_rounding(sn, xm);
+		/* adjust exponent for rounding add overflowing
+		 */
+		if (xm >> (SP_MBITS + 1 + 3)) {
+			/* add causes mantissa overflow */
+			xm >>= 1;
+			xe++;
+		}
+	}
+	/* strip grs bits */
+	xm >>= 3;
+
+	assert((xm >> (SP_MBITS + 1)) == 0);	/* no execess */
+	assert(xe >= SP_EMIN);
+
+	if (xe > SP_EMAX) {
+		SETCX(IEEE754_OVERFLOW);
+		SETCX(IEEE754_INEXACT);
+		/* -O can be table indexed by (rm,sn) */
+		switch (ieee754_csr.rm) {
+		case IEEE754_RN:
+			return ieee754sp_inf(sn);
+		case IEEE754_RZ:
+			return ieee754sp_max(sn);
+		case IEEE754_RU:	/* toward +Infinity */
+			if (sn == 0)
+				return ieee754sp_inf(0);
+			else
+				return ieee754sp_max(1);
+		case IEEE754_RD:	/* toward -Infinity */
+			if (sn == 0)
+				return ieee754sp_max(0);
+			else
+				return ieee754sp_inf(1);
+		}
+	}
+	/* gen norm/denorm/zero */
+
+	if ((xm & SP_HIDDEN_BIT) == 0) {
+		/* we underflow (tiny/zero) */
+		assert(xe == SP_EMIN);
+		if (ieee754_csr.mx & IEEE754_UNDERFLOW)
+			SETCX(IEEE754_UNDERFLOW);
+		return buildsp(sn, SP_EMIN - 1 + SP_EBIAS, xm);
+	} else {
+		assert((xm >> (SP_MBITS + 1)) == 0);	/* no execess */
+		assert(xm & SP_HIDDEN_BIT);
+
+		return buildsp(sn, xe + SP_EBIAS, xm & ~SP_HIDDEN_BIT);
+	}
+}
diff --git a/arch/mips/math-emu/ieee754sp.h b/arch/mips/math-emu/ieee754sp.h
new file mode 100644
index 0000000..ae82f51
--- /dev/null
+++ b/arch/mips/math-emu/ieee754sp.h
@@ -0,0 +1,89 @@
+/*
+ * IEEE754 floating point
+ * double precision internal header file
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754int.h"
+
+#define assert(expr) ((void)0)
+
+/* 3bit extended single precision sticky right shift */
+#define SPXSRSXn(rs) \
+  (xe += rs, \
+   xm = (rs > (SP_MBITS+3))?1:((xm) >> (rs)) | ((xm) << (32-(rs)) != 0))
+
+#define SPXSRSX1() \
+  (xe++, (xm = (xm >> 1) | (xm & 1)))
+
+#define SPXSRSYn(rs) \
+   (ye+=rs, \
+    ym = (rs > (SP_MBITS+3))?1:((ym) >> (rs)) | ((ym) << (32-(rs)) != 0))
+
+#define SPXSRSY1() \
+   (ye++, (ym = (ym >> 1) | (ym & 1)))
+
+/* convert denormal to normalized with extended exponent */
+#define SPDNORMx(m,e) \
+  while( (m >> SP_MBITS) == 0) { m <<= 1; e--; }
+#define SPDNORMX	SPDNORMx(xm,xe)
+#define SPDNORMY	SPDNORMx(ym,ye)
+
+static __inline ieee754sp buildsp(int s, int bx, unsigned m)
+{
+	ieee754sp r;
+
+	assert((s) == 0 || (s) == 1);
+	assert((bx) >= SP_EMIN - 1 + SP_EBIAS
+	       && (bx) <= SP_EMAX + 1 + SP_EBIAS);
+	assert(((m) >> SP_MBITS) == 0);
+
+	r.parts.sign = s;
+	r.parts.bexp = bx;
+	r.parts.mant = m;
+
+	return r;
+}
+
+extern int ieee754sp_isnan(ieee754sp);
+extern int ieee754sp_issnan(ieee754sp);
+extern int ieee754si_xcpt(int, const char *, ...);
+extern s64 ieee754di_xcpt(s64, const char *, ...);
+extern ieee754sp ieee754sp_xcpt(ieee754sp, const char *, ...);
+extern ieee754sp ieee754sp_nanxcpt(ieee754sp, const char *, ...);
+extern ieee754sp ieee754sp_bestnan(ieee754sp, ieee754sp);
+extern ieee754sp ieee754sp_format(int, int, unsigned);
+
+
+#define SPNORMRET2(s,e,m,name,a0,a1) \
+{ \
+    ieee754sp V = ieee754sp_format(s,e,m); \
+    if(TSTX()) \
+      return ieee754sp_xcpt(V,name,a0,a1); \
+    else \
+      return V; \
+}
+
+#define SPNORMRET1(s,e,m,name,a0)  SPNORMRET2(s,e,m,name,a0,a0)
diff --git a/arch/mips/math-emu/ieee754xcpt.c b/arch/mips/math-emu/ieee754xcpt.c
new file mode 100644
index 0000000..7d8ef89
--- /dev/null
+++ b/arch/mips/math-emu/ieee754xcpt.c
@@ -0,0 +1,49 @@
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+/**************************************************************************
+ *  Nov 7, 2000
+ *  Added preprocessor hacks to map to Linux kernel diagnostics.
+ *
+ *  Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ *  Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *************************************************************************/
+
+#include <linux/kernel.h>
+#include "ieee754.h"
+
+/*
+ * Very naff exception handler (you can plug in your own and
+ * override this).
+ */
+
+static const char *const rtnames[] = {
+	"sp", "dp", "xp", "si", "di"
+};
+
+void ieee754_xcpt(struct ieee754xctx *xcp)
+{
+	printk(KERN_DEBUG "floating point exception in \"%s\", type=%s\n",
+		xcp->op, rtnames[xcp->rt]);
+}
+
diff --git a/arch/mips/math-emu/kernel_linkage.c b/arch/mips/math-emu/kernel_linkage.c
new file mode 100644
index 0000000..04397fec
--- /dev/null
+++ b/arch/mips/math-emu/kernel_linkage.c
@@ -0,0 +1,125 @@
+/*
+ *  Kevin D. Kissell, kevink@mips and Carsten Langgaard, carstenl@mips.com
+ *  Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Routines corresponding to Linux kernel FP context
+ * manipulation primitives for the Algorithmics MIPS
+ * FPU Emulator
+ */
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <asm/processor.h>
+#include <asm/signal.h>
+#include <asm/uaccess.h>
+
+#include <asm/fpu_emulator.h>
+
+extern struct mips_fpu_emulator_private fpuemuprivate;
+
+#define SIGNALLING_NAN 0x7ff800007ff80000LL
+
+void fpu_emulator_init_fpu(void)
+{
+	static int first = 1;
+	int i;
+
+	if (first) {
+		first = 0;
+		printk("Algorithmics/MIPS FPU Emulator v1.5\n");
+	}
+
+	current->thread.fpu.soft.fcr31 = 0;
+	for (i = 0; i < 32; i++) {
+		current->thread.fpu.soft.fpr[i] = SIGNALLING_NAN;
+	}
+}
+
+
+/*
+ * Emulator context save/restore to/from a signal context
+ * presumed to be on the user stack, and therefore accessed
+ * with appropriate macros from uaccess.h
+ */
+
+int fpu_emulator_save_context(struct sigcontext *sc)
+{
+	int i;
+	int err = 0;
+
+	for (i = 0; i < 32; i++) {
+		err |=
+		    __put_user(current->thread.fpu.soft.fpr[i],
+			       &sc->sc_fpregs[i]);
+	}
+	err |= __put_user(current->thread.fpu.soft.fcr31, &sc->sc_fpc_csr);
+	err |= __put_user(fpuemuprivate.eir, &sc->sc_fpc_eir);
+
+	return err;
+}
+
+int fpu_emulator_restore_context(struct sigcontext *sc)
+{
+	int i;
+	int err = 0;
+
+	for (i = 0; i < 32; i++) {
+		err |=
+		    __get_user(current->thread.fpu.soft.fpr[i],
+			       &sc->sc_fpregs[i]);
+	}
+	err |= __get_user(current->thread.fpu.soft.fcr31, &sc->sc_fpc_csr);
+	err |= __get_user(fpuemuprivate.eir, &sc->sc_fpc_eir);
+
+	return err;
+}
+
+#ifdef CONFIG_MIPS64
+/*
+ * This is the o32 version
+ */
+
+int fpu_emulator_save_context32(struct sigcontext32 *sc)
+{
+	int i;
+	int err = 0;
+
+	for (i = 0; i < 32; i+=2) {
+		err |=
+		    __put_user(current->thread.fpu.soft.fpr[i],
+			       &sc->sc_fpregs[i]);
+	}
+	err |= __put_user(current->thread.fpu.soft.fcr31, &sc->sc_fpc_csr);
+	err |= __put_user(fpuemuprivate.eir, &sc->sc_fpc_eir);
+
+	return err;
+}
+
+int fpu_emulator_restore_context32(struct sigcontext32 *sc)
+{
+	int i;
+	int err = 0;
+
+	for (i = 0; i < 32; i+=2) {
+		err |=
+		    __get_user(current->thread.fpu.soft.fpr[i],
+			       &sc->sc_fpregs[i]);
+	}
+	err |= __get_user(current->thread.fpu.soft.fcr31, &sc->sc_fpc_csr);
+	err |= __get_user(fpuemuprivate.eir, &sc->sc_fpc_eir);
+
+	return err;
+}
+#endif
diff --git a/arch/mips/math-emu/sp_add.c b/arch/mips/math-emu/sp_add.c
new file mode 100644
index 0000000..d8c4211
--- /dev/null
+++ b/arch/mips/math-emu/sp_add.c
@@ -0,0 +1,177 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+ieee754sp ieee754sp_add(ieee754sp x, ieee754sp y)
+{
+	COMPXSP;
+	COMPYSP;
+
+	EXPLODEXSP;
+	EXPLODEYSP;
+
+	CLEARCX;
+
+	FLUSHXSP;
+	FLUSHYSP;
+
+	switch (CLPAIR(xc, yc)) {
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754sp_nanxcpt(ieee754sp_indef(), "add", x, y);
+
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
+		return y;
+
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
+		return x;
+
+
+		/* Infinity handling
+		 */
+
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+		if (xs == ys)
+			return x;
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754sp_xcpt(ieee754sp_indef(), "add", x, y);
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
+		return y;
+
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
+		return x;
+
+		/* Zero handling
+		 */
+
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+		if (xs == ys)
+			return x;
+		else
+			return ieee754sp_zero(ieee754_csr.rm ==
+					      IEEE754_RD);
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
+		return x;
+
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
+		return y;
+
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
+		SPDNORMX;
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
+		SPDNORMY;
+		break;
+
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
+		SPDNORMX;
+		break;
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
+		break;
+	}
+	assert(xm & SP_HIDDEN_BIT);
+	assert(ym & SP_HIDDEN_BIT);
+
+	/* provide guard,round and stick bit space */
+	xm <<= 3;
+	ym <<= 3;
+
+	if (xe > ye) {
+		/* have to shift y fraction right to align
+		 */
+		int s = xe - ye;
+		SPXSRSYn(s);
+	} else if (ye > xe) {
+		/* have to shift x fraction right to align
+		 */
+		int s = ye - xe;
+		SPXSRSXn(s);
+	}
+	assert(xe == ye);
+	assert(xe <= SP_EMAX);
+
+	if (xs == ys) {
+		/* generate 28 bit result of adding two 27 bit numbers
+		 * leaving result in xm,xs,xe
+		 */
+		xm = xm + ym;
+		xe = xe;
+		xs = xs;
+
+		if (xm >> (SP_MBITS + 1 + 3)) {	/* carry out */
+			SPXSRSX1();
+		}
+	} else {
+		if (xm >= ym) {
+			xm = xm - ym;
+			xe = xe;
+			xs = xs;
+		} else {
+			xm = ym - xm;
+			xe = xe;
+			xs = ys;
+		}
+		if (xm == 0)
+			return ieee754sp_zero(ieee754_csr.rm ==
+					      IEEE754_RD);
+
+		/* normalize in extended single precision */
+		while ((xm >> (SP_MBITS + 3)) == 0) {
+			xm <<= 1;
+			xe--;
+		}
+
+	}
+	SPNORMRET2(xs, xe, xm, "add", x, y);
+}
diff --git a/arch/mips/math-emu/sp_cmp.c b/arch/mips/math-emu/sp_cmp.c
new file mode 100644
index 0000000..d3eff6b
--- /dev/null
+++ b/arch/mips/math-emu/sp_cmp.c
@@ -0,0 +1,67 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cmp, int sig)
+{
+	COMPXSP;
+	COMPYSP;
+
+	EXPLODEXSP;
+	EXPLODEYSP;
+	FLUSHXSP;
+	FLUSHYSP;
+	CLEARCX;	/* Even clear inexact flag here */
+
+	if (ieee754sp_isnan(x) || ieee754sp_isnan(y)) {
+		if (sig || xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
+			SETCX(IEEE754_INVALID_OPERATION);
+		if (cmp & IEEE754_CUN)
+			return 1;
+		if (cmp & (IEEE754_CLT | IEEE754_CGT)) {
+			if (sig && SETANDTESTCX(IEEE754_INVALID_OPERATION))
+				return ieee754si_xcpt(0, "fcmpf", x);
+		}
+		return 0;
+	} else {
+		int vx = x.bits;
+		int vy = y.bits;
+
+		if (vx < 0)
+			vx = -vx ^ SP_SIGN_BIT;
+		if (vy < 0)
+			vy = -vy ^ SP_SIGN_BIT;
+
+		if (vx < vy)
+			return (cmp & IEEE754_CLT) != 0;
+		else if (vx == vy)
+			return (cmp & IEEE754_CEQ) != 0;
+		else
+			return (cmp & IEEE754_CGT) != 0;
+	}
+}
diff --git a/arch/mips/math-emu/sp_div.c b/arch/mips/math-emu/sp_div.c
new file mode 100644
index 0000000..2b437fc
--- /dev/null
+++ b/arch/mips/math-emu/sp_div.c
@@ -0,0 +1,157 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+ieee754sp ieee754sp_div(ieee754sp x, ieee754sp y)
+{
+	COMPXSP;
+	COMPYSP;
+
+	EXPLODEXSP;
+	EXPLODEYSP;
+
+	CLEARCX;
+
+	FLUSHXSP;
+	FLUSHYSP;
+
+	switch (CLPAIR(xc, yc)) {
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754sp_nanxcpt(ieee754sp_indef(), "div", x, y);
+
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
+		return y;
+
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
+		return x;
+
+
+		/* Infinity handling
+		 */
+
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754sp_xcpt(ieee754sp_indef(), "div", x, y);
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
+		return ieee754sp_zero(xs ^ ys);
+
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
+		return ieee754sp_inf(xs ^ ys);
+
+		/* Zero handling
+		 */
+
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754sp_xcpt(ieee754sp_indef(), "div", x, y);
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
+		SETCX(IEEE754_ZERO_DIVIDE);
+		return ieee754sp_xcpt(ieee754sp_inf(xs ^ ys), "div", x, y);
+
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
+		return ieee754sp_zero(xs == ys ? 0 : 1);
+
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
+		SPDNORMX;
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
+		SPDNORMY;
+		break;
+
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
+		SPDNORMX;
+		break;
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
+		break;
+	}
+	assert(xm & SP_HIDDEN_BIT);
+	assert(ym & SP_HIDDEN_BIT);
+
+	/* provide rounding space */
+	xm <<= 3;
+	ym <<= 3;
+
+	{
+		/* now the dirty work */
+
+		unsigned rm = 0;
+		int re = xe - ye;
+		unsigned bm;
+
+		for (bm = SP_MBIT(SP_MBITS + 2); bm; bm >>= 1) {
+			if (xm >= ym) {
+				xm -= ym;
+				rm |= bm;
+				if (xm == 0)
+					break;
+			}
+			xm <<= 1;
+		}
+		rm <<= 1;
+		if (xm)
+			rm |= 1;	/* have remainder, set sticky */
+
+		assert(rm);
+
+		/* normalise rm to rounding precision ?
+		 */
+		while ((rm >> (SP_MBITS + 3)) == 0) {
+			rm <<= 1;
+			re--;
+		}
+
+		SPNORMRET2(xs == ys ? 0 : 1, re, rm, "div", x, y);
+	}
+}
diff --git a/arch/mips/math-emu/sp_fdp.c b/arch/mips/math-emu/sp_fdp.c
new file mode 100644
index 0000000..4093723
--- /dev/null
+++ b/arch/mips/math-emu/sp_fdp.c
@@ -0,0 +1,77 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+ieee754sp ieee754sp_fdp(ieee754dp x)
+{
+	COMPXDP;
+	ieee754sp nan;
+
+	EXPLODEXDP;
+
+	CLEARCX;
+
+	FLUSHXDP;
+
+	switch (xc) {
+	case IEEE754_CLASS_SNAN:
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754sp_nanxcpt(ieee754sp_indef(), "fdp");
+	case IEEE754_CLASS_QNAN:
+		nan = buildsp(xs, SP_EMAX + 1 + SP_EBIAS, (u32)
+				(xm >> (DP_MBITS - SP_MBITS)));
+		if (!ieee754sp_isnan(nan))
+			nan = ieee754sp_indef();
+		return ieee754sp_nanxcpt(nan, "fdp", x);
+	case IEEE754_CLASS_INF:
+		return ieee754sp_inf(xs);
+	case IEEE754_CLASS_ZERO:
+		return ieee754sp_zero(xs);
+	case IEEE754_CLASS_DNORM:
+		/* can't possibly be sp representable */
+		SETCX(IEEE754_UNDERFLOW);
+		SETCX(IEEE754_INEXACT);
+		if ((ieee754_csr.rm == IEEE754_RU && !xs) ||
+				(ieee754_csr.rm == IEEE754_RD && xs))
+			return ieee754sp_xcpt(ieee754sp_mind(xs), "fdp", x);
+		return ieee754sp_xcpt(ieee754sp_zero(xs), "fdp", x);
+	case IEEE754_CLASS_NORM:
+		break;
+	}
+
+	{
+		u32 rm;
+
+		/* convert from DP_MBITS to SP_MBITS+3 with sticky right shift
+		 */
+		rm = (xm >> (DP_MBITS - (SP_MBITS + 3))) |
+		    ((xm << (64 - (DP_MBITS - (SP_MBITS + 3)))) != 0);
+
+		SPNORMRET1(xs, xe, rm, "fdp", x);
+	}
+}
diff --git a/arch/mips/math-emu/sp_fint.c b/arch/mips/math-emu/sp_fint.c
new file mode 100644
index 0000000..42d9ed4
--- /dev/null
+++ b/arch/mips/math-emu/sp_fint.c
@@ -0,0 +1,80 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+ieee754sp ieee754sp_fint(int x)
+{
+	COMPXSP;
+
+	CLEARCX;
+
+	xc = ( 0 ? xc : xc );
+
+	if (x == 0)
+		return ieee754sp_zero(0);
+	if (x == 1 || x == -1)
+		return ieee754sp_one(x < 0);
+	if (x == 10 || x == -10)
+		return ieee754sp_ten(x < 0);
+
+	xs = (x < 0);
+	if (xs) {
+		if (x == (1 << 31))
+			xm = ((unsigned) 1 << 31);	/* max neg can't be safely negated */
+		else
+			xm = -x;
+	} else {
+		xm = x;
+	}
+	xe = SP_MBITS + 3;
+
+	if (xm >> (SP_MBITS + 1 + 3)) {
+		/* shunt out overflow bits
+		 */
+		while (xm >> (SP_MBITS + 1 + 3)) {
+			SPXSRSX1();
+		}
+	} else {
+		/* normalize in grs extended single precision
+		 */
+		while ((xm >> (SP_MBITS + 3)) == 0) {
+			xm <<= 1;
+			xe--;
+		}
+	}
+	SPNORMRET1(xs, xe, xm, "fint", x);
+}
+
+
+ieee754sp ieee754sp_funs(unsigned int u)
+{
+	if ((int) u < 0)
+		return ieee754sp_add(ieee754sp_1e31(),
+				     ieee754sp_fint(u & ~(1 << 31)));
+	return ieee754sp_fint(u);
+}
diff --git a/arch/mips/math-emu/sp_flong.c b/arch/mips/math-emu/sp_flong.c
new file mode 100644
index 0000000..1e26795
--- /dev/null
+++ b/arch/mips/math-emu/sp_flong.c
@@ -0,0 +1,79 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+ieee754sp ieee754sp_flong(s64 x)
+{
+	COMPXDP;		/* <--- need 64-bit mantissa temp */
+
+	CLEARCX;
+
+	xc = ( 0 ? xc : xc );
+
+	if (x == 0)
+		return ieee754sp_zero(0);
+	if (x == 1 || x == -1)
+		return ieee754sp_one(x < 0);
+	if (x == 10 || x == -10)
+		return ieee754sp_ten(x < 0);
+
+	xs = (x < 0);
+	if (xs) {
+		if (x == (1ULL << 63))
+			xm = (1ULL << 63);	/* max neg can't be safely negated */
+		else
+			xm = -x;
+	} else {
+		xm = x;
+	}
+	xe = SP_MBITS + 3;
+
+	if (xm >> (SP_MBITS + 1 + 3)) {
+		/* shunt out overflow bits
+		 */
+		while (xm >> (SP_MBITS + 1 + 3)) {
+			SPXSRSX1();
+		}
+	} else {
+		/* normalize in grs extended single precision */
+		while ((xm >> (SP_MBITS + 3)) == 0) {
+			xm <<= 1;
+			xe--;
+		}
+	}
+	SPNORMRET1(xs, xe, xm, "sp_flong", x);
+}
+
+
+ieee754sp ieee754sp_fulong(u64 u)
+{
+	if ((s64) u < 0)
+		return ieee754sp_add(ieee754sp_1e63(),
+				     ieee754sp_flong(u & ~(1ULL << 63)));
+	return ieee754sp_flong(u);
+}
diff --git a/arch/mips/math-emu/sp_frexp.c b/arch/mips/math-emu/sp_frexp.c
new file mode 100644
index 0000000..359c648
--- /dev/null
+++ b/arch/mips/math-emu/sp_frexp.c
@@ -0,0 +1,53 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+/* close to ieeep754sp_logb
+*/
+ieee754sp ieee754sp_frexp(ieee754sp x, int *eptr)
+{
+	COMPXSP;
+	CLEARCX;
+	EXPLODEXSP;
+
+	switch (xc) {
+	case IEEE754_CLASS_SNAN:
+	case IEEE754_CLASS_QNAN:
+	case IEEE754_CLASS_INF:
+	case IEEE754_CLASS_ZERO:
+		*eptr = 0;
+		return x;
+	case IEEE754_CLASS_DNORM:
+		SPDNORMX;
+		break;
+	case IEEE754_CLASS_NORM:
+		break;
+	}
+	*eptr = xe + 1;
+	return buildsp(xs, -1 + SP_EBIAS, xm & ~SP_HIDDEN_BIT);
+}
diff --git a/arch/mips/math-emu/sp_logb.c b/arch/mips/math-emu/sp_logb.c
new file mode 100644
index 0000000..3c33721
--- /dev/null
+++ b/arch/mips/math-emu/sp_logb.c
@@ -0,0 +1,54 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+ieee754sp ieee754sp_logb(ieee754sp x)
+{
+	COMPXSP;
+
+	CLEARCX;
+
+	EXPLODEXSP;
+
+	switch (xc) {
+	case IEEE754_CLASS_SNAN:
+		return ieee754sp_nanxcpt(x, "logb", x);
+	case IEEE754_CLASS_QNAN:
+		return x;
+	case IEEE754_CLASS_INF:
+		return ieee754sp_inf(0);
+	case IEEE754_CLASS_ZERO:
+		return ieee754sp_inf(1);
+	case IEEE754_CLASS_DNORM:
+		SPDNORMX;
+		break;
+	case IEEE754_CLASS_NORM:
+		break;
+	}
+	return ieee754sp_fint(xe);
+}
diff --git a/arch/mips/math-emu/sp_modf.c b/arch/mips/math-emu/sp_modf.c
new file mode 100644
index 0000000..4b1dbac
--- /dev/null
+++ b/arch/mips/math-emu/sp_modf.c
@@ -0,0 +1,80 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+/* modf function is always exact for a finite number
+*/
+ieee754sp ieee754sp_modf(ieee754sp x, ieee754sp * ip)
+{
+	COMPXSP;
+
+	CLEARCX;
+
+	EXPLODEXSP;
+
+	switch (xc) {
+	case IEEE754_CLASS_SNAN:
+	case IEEE754_CLASS_QNAN:
+	case IEEE754_CLASS_INF:
+	case IEEE754_CLASS_ZERO:
+		*ip = x;
+		return x;
+	case IEEE754_CLASS_DNORM:
+		/* far to small */
+		*ip = ieee754sp_zero(xs);
+		return x;
+	case IEEE754_CLASS_NORM:
+		break;
+	}
+	if (xe < 0) {
+		*ip = ieee754sp_zero(xs);
+		return x;
+	}
+	if (xe >= SP_MBITS) {
+		*ip = x;
+		return ieee754sp_zero(xs);
+	}
+	/* generate ipart mantissa by clearing bottom bits
+	 */
+	*ip = buildsp(xs, xe + SP_EBIAS,
+		      ((xm >> (SP_MBITS - xe)) << (SP_MBITS - xe)) &
+		      ~SP_HIDDEN_BIT);
+
+	/* generate fpart mantissa by clearing top bits
+	 * and normalizing (must be able to normalize)
+	 */
+	xm = (xm << (32 - (SP_MBITS - xe))) >> (32 - (SP_MBITS - xe));
+	if (xm == 0)
+		return ieee754sp_zero(xs);
+
+	while ((xm >> SP_MBITS) == 0) {
+		xm <<= 1;
+		xe--;
+	}
+	return buildsp(xs, xe + SP_EBIAS, xm & ~SP_HIDDEN_BIT);
+}
diff --git a/arch/mips/math-emu/sp_mul.c b/arch/mips/math-emu/sp_mul.c
new file mode 100644
index 0000000..3f070f8
--- /dev/null
+++ b/arch/mips/math-emu/sp_mul.c
@@ -0,0 +1,171 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+ieee754sp ieee754sp_mul(ieee754sp x, ieee754sp y)
+{
+	COMPXSP;
+	COMPYSP;
+
+	EXPLODEXSP;
+	EXPLODEYSP;
+
+	CLEARCX;
+
+	FLUSHXSP;
+	FLUSHYSP;
+
+	switch (CLPAIR(xc, yc)) {
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754sp_nanxcpt(ieee754sp_indef(), "mul", x, y);
+
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
+		return y;
+
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
+		return x;
+
+
+		/* Infinity handling */
+
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754sp_xcpt(ieee754sp_indef(), "mul", x, y);
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+		return ieee754sp_inf(xs ^ ys);
+
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
+		return ieee754sp_zero(xs ^ ys);
+
+
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
+		SPDNORMX;
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
+		SPDNORMY;
+		break;
+
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
+		SPDNORMX;
+		break;
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
+		break;
+	}
+	/* rm = xm * ym, re = xe+ye basicly */
+	assert(xm & SP_HIDDEN_BIT);
+	assert(ym & SP_HIDDEN_BIT);
+
+	{
+		int re = xe + ye;
+		int rs = xs ^ ys;
+		unsigned rm;
+
+		/* shunt to top of word */
+		xm <<= 32 - (SP_MBITS + 1);
+		ym <<= 32 - (SP_MBITS + 1);
+
+		/* multiply 32bits xm,ym to give high 32bits rm with stickness
+		 */
+		{
+			unsigned short lxm = xm & 0xffff;
+			unsigned short hxm = xm >> 16;
+			unsigned short lym = ym & 0xffff;
+			unsigned short hym = ym >> 16;
+			unsigned lrm;
+			unsigned hrm;
+
+			lrm = lxm * lym;	/* 16 * 16 => 32 */
+			hrm = hxm * hym;	/* 16 * 16 => 32 */
+
+			{
+				unsigned t = lxm * hym;	/* 16 * 16 => 32 */
+				{
+					unsigned at = lrm + (t << 16);
+					hrm += at < lrm;
+					lrm = at;
+				}
+				hrm = hrm + (t >> 16);
+			}
+
+			{
+				unsigned t = hxm * lym;	/* 16 * 16 => 32 */
+				{
+					unsigned at = lrm + (t << 16);
+					hrm += at < lrm;
+					lrm = at;
+				}
+				hrm = hrm + (t >> 16);
+			}
+			rm = hrm | (lrm != 0);
+		}
+
+		/*
+		 * sticky shift down to normal rounding precision
+		 */
+		if ((int) rm < 0) {
+			rm = (rm >> (32 - (SP_MBITS + 1 + 3))) |
+			    ((rm << (SP_MBITS + 1 + 3)) != 0);
+			re++;
+		} else {
+			rm = (rm >> (32 - (SP_MBITS + 1 + 3 + 1))) |
+			    ((rm << (SP_MBITS + 1 + 3 + 1)) != 0);
+		}
+		assert(rm & (SP_HIDDEN_BIT << 3));
+
+		SPNORMRET2(rs, re, rm, "mul", x, y);
+	}
+}
diff --git a/arch/mips/math-emu/sp_scalb.c b/arch/mips/math-emu/sp_scalb.c
new file mode 100644
index 0000000..44ceb87
--- /dev/null
+++ b/arch/mips/math-emu/sp_scalb.c
@@ -0,0 +1,58 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+ieee754sp ieee754sp_scalb(ieee754sp x, int n)
+{
+	COMPXSP;
+
+	CLEARCX;
+
+	EXPLODEXSP;
+
+	switch (xc) {
+	case IEEE754_CLASS_SNAN:
+		return ieee754sp_nanxcpt(x, "scalb", x, n);
+	case IEEE754_CLASS_QNAN:
+	case IEEE754_CLASS_INF:
+	case IEEE754_CLASS_ZERO:
+		return x;
+	case IEEE754_CLASS_DNORM:
+		SPDNORMX;
+		break;
+	case IEEE754_CLASS_NORM:
+		break;
+	}
+	SPNORMRET2(xs, xe + n, xm << 3, "scalb", x, n);
+}
+
+
+ieee754sp ieee754sp_ldexp(ieee754sp x, int n)
+{
+	return ieee754sp_scalb(x, n);
+}
diff --git a/arch/mips/math-emu/sp_simple.c b/arch/mips/math-emu/sp_simple.c
new file mode 100644
index 0000000..c809830
--- /dev/null
+++ b/arch/mips/math-emu/sp_simple.c
@@ -0,0 +1,84 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+int ieee754sp_finite(ieee754sp x)
+{
+	return SPBEXP(x) != SP_EMAX + 1 + SP_EBIAS;
+}
+
+ieee754sp ieee754sp_copysign(ieee754sp x, ieee754sp y)
+{
+	CLEARCX;
+	SPSIGN(x) = SPSIGN(y);
+	return x;
+}
+
+
+ieee754sp ieee754sp_neg(ieee754sp x)
+{
+	COMPXSP;
+
+	EXPLODEXSP;
+	CLEARCX;
+	FLUSHXSP;
+
+	if (xc == IEEE754_CLASS_SNAN) {
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754sp_nanxcpt(ieee754sp_indef(), "neg");
+	}
+
+	if (ieee754sp_isnan(x))	/* but not infinity */
+		return ieee754sp_nanxcpt(x, "neg", x);
+
+	/* quick fix up */
+	SPSIGN(x) ^= 1;
+	return x;
+}
+
+
+ieee754sp ieee754sp_abs(ieee754sp x)
+{
+	COMPXSP;
+
+	EXPLODEXSP;
+	CLEARCX;
+	FLUSHXSP;
+
+	if (xc == IEEE754_CLASS_SNAN) {
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754sp_nanxcpt(ieee754sp_indef(), "abs");
+	}
+
+	if (ieee754sp_isnan(x))	/* but not infinity */
+		return ieee754sp_nanxcpt(x, "abs", x);
+
+	/* quick fix up */
+	SPSIGN(x) = 0;
+	return x;
+}
diff --git a/arch/mips/math-emu/sp_sqrt.c b/arch/mips/math-emu/sp_sqrt.c
new file mode 100644
index 0000000..8a934b9
--- /dev/null
+++ b/arch/mips/math-emu/sp_sqrt.c
@@ -0,0 +1,117 @@
+/* IEEE754 floating point arithmetic
+ * single precision square root
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+ieee754sp ieee754sp_sqrt(ieee754sp x)
+{
+	int ix, s, q, m, t, i;
+	unsigned int r;
+	COMPXSP;
+
+	/* take care of Inf and NaN */
+
+	EXPLODEXSP;
+	CLEARCX;
+	FLUSHXSP;
+
+	/* x == INF or NAN? */
+	switch (xc) {
+	case IEEE754_CLASS_QNAN:
+		/* sqrt(Nan) = Nan */
+		return ieee754sp_nanxcpt(x, "sqrt");
+	case IEEE754_CLASS_SNAN:
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt");
+	case IEEE754_CLASS_ZERO:
+		/* sqrt(0) = 0 */
+		return x;
+	case IEEE754_CLASS_INF:
+		if (xs) {
+			/* sqrt(-Inf) = Nan */
+			SETCX(IEEE754_INVALID_OPERATION);
+			return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt");
+		}
+		/* sqrt(+Inf) = Inf */
+		return x;
+	case IEEE754_CLASS_DNORM:
+	case IEEE754_CLASS_NORM:
+		if (xs) {
+			/* sqrt(-x) = Nan */
+			SETCX(IEEE754_INVALID_OPERATION);
+			return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt");
+		}
+		break;
+	}
+
+	ix = x.bits;
+
+	/* normalize x */
+	m = (ix >> 23);
+	if (m == 0) {		/* subnormal x */
+		for (i = 0; (ix & 0x00800000) == 0; i++)
+			ix <<= 1;
+		m -= i - 1;
+	}
+	m -= 127;		/* unbias exponent */
+	ix = (ix & 0x007fffff) | 0x00800000;
+	if (m & 1)		/* odd m, double x to make it even */
+		ix += ix;
+	m >>= 1;		/* m = [m/2] */
+
+	/* generate sqrt(x) bit by bit */
+	ix += ix;
+	q = s = 0;		/* q = sqrt(x) */
+	r = 0x01000000;		/* r = moving bit from right to left */
+
+	while (r != 0) {
+		t = s + r;
+		if (t <= ix) {
+			s = t + r;
+			ix -= t;
+			q += r;
+		}
+		ix += ix;
+		r >>= 1;
+	}
+
+	if (ix != 0) {
+		SETCX(IEEE754_INEXACT);
+		switch (ieee754_csr.rm) {
+		case IEEE754_RP:
+			q += 2;
+			break;
+		case IEEE754_RN:
+			q += (q & 1);
+			break;
+		}
+	}
+	ix = (q >> 1) + 0x3f000000;
+	ix += (m << 23);
+	x.bits = ix;
+	return x;
+}
diff --git a/arch/mips/math-emu/sp_sub.c b/arch/mips/math-emu/sp_sub.c
new file mode 100644
index 0000000..dbb802c
--- /dev/null
+++ b/arch/mips/math-emu/sp_sub.c
@@ -0,0 +1,184 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+ieee754sp ieee754sp_sub(ieee754sp x, ieee754sp y)
+{
+	COMPXSP;
+	COMPYSP;
+
+	EXPLODEXSP;
+	EXPLODEYSP;
+
+	CLEARCX;
+
+	FLUSHXSP;
+	FLUSHYSP;
+
+	switch (CLPAIR(xc, yc)) {
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
+	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754sp_nanxcpt(ieee754sp_indef(), "sub", x, y);
+
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
+		return y;
+
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
+	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
+		return x;
+
+
+		/* Infinity handling
+		 */
+
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+		if (xs != ys)
+			return x;
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754sp_xcpt(ieee754sp_indef(), "sub", x, y);
+
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
+		return ieee754sp_inf(ys ^ 1);
+
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
+		return x;
+
+		/* Zero handling
+		 */
+
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+		if (xs != ys)
+			return x;
+		else
+			return ieee754sp_zero(ieee754_csr.rm ==
+					      IEEE754_RD);
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
+		return x;
+
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
+	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
+		/* quick fix up */
+		DPSIGN(y) ^= 1;
+		return y;
+
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
+		SPDNORMX;
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
+		SPDNORMY;
+		break;
+
+	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
+		SPDNORMX;
+		break;
+
+	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
+		break;
+	}
+	/* flip sign of y and handle as add */
+	ys ^= 1;
+
+	assert(xm & SP_HIDDEN_BIT);
+	assert(ym & SP_HIDDEN_BIT);
+
+
+	/* provide guard,round and stick bit space */
+	xm <<= 3;
+	ym <<= 3;
+
+	if (xe > ye) {
+		/* have to shift y fraction right to align
+		 */
+		int s = xe - ye;
+		SPXSRSYn(s);
+	} else if (ye > xe) {
+		/* have to shift x fraction right to align
+		 */
+		int s = ye - xe;
+		SPXSRSXn(s);
+	}
+	assert(xe == ye);
+	assert(xe <= SP_EMAX);
+
+	if (xs == ys) {
+		/* generate 28 bit result of adding two 27 bit numbers
+		 */
+		xm = xm + ym;
+		xe = xe;
+		xs = xs;
+
+		if (xm >> (SP_MBITS + 1 + 3)) {	/* carry out */
+			SPXSRSX1();	/* shift preserving sticky */
+		}
+	} else {
+		if (xm >= ym) {
+			xm = xm - ym;
+			xe = xe;
+			xs = xs;
+		} else {
+			xm = ym - xm;
+			xe = xe;
+			xs = ys;
+		}
+		if (xm == 0) {
+			if (ieee754_csr.rm == IEEE754_RD)
+				return ieee754sp_zero(1);	/* round negative inf. => sign = -1 */
+			else
+				return ieee754sp_zero(0);	/* other round modes   => sign = 1 */
+		}
+		/* normalize to rounding precision
+		 */
+		while ((xm >> (SP_MBITS + 3)) == 0) {
+			xm <<= 1;
+			xe--;
+		}
+	}
+	SPNORMRET2(xs, xe, xm, "sub", x, y);
+}
diff --git a/arch/mips/math-emu/sp_tint.c b/arch/mips/math-emu/sp_tint.c
new file mode 100644
index 0000000..1d73d2a
--- /dev/null
+++ b/arch/mips/math-emu/sp_tint.c
@@ -0,0 +1,128 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include <linux/kernel.h>
+#include "ieee754sp.h"
+
+int ieee754sp_tint(ieee754sp x)
+{
+	COMPXSP;
+
+	CLEARCX;
+
+	EXPLODEXSP;
+	FLUSHXSP;
+
+	switch (xc) {
+	case IEEE754_CLASS_SNAN:
+	case IEEE754_CLASS_QNAN:
+	case IEEE754_CLASS_INF:
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x);
+	case IEEE754_CLASS_ZERO:
+		return 0;
+	case IEEE754_CLASS_DNORM:
+	case IEEE754_CLASS_NORM:
+		break;
+	}
+	if (xe >= 31) {
+		/* look for valid corner case */
+		if (xe == 31 && xs && xm == SP_HIDDEN_BIT)
+			return -0x80000000;
+		/* Set invalid. We will only use overflow for floating
+		   point overflow */
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x);
+	}
+	/* oh gawd */
+	if (xe > SP_MBITS) {
+		xm <<= xe - SP_MBITS;
+	} else {
+		u32 residue;
+		int round;
+		int sticky;
+		int odd;
+
+		if (xe < -1) {
+			residue = xm;
+			round = 0;
+			sticky = residue != 0;
+			xm = 0;
+		}
+		else {
+			/* Shifting a u32 32 times does not work,
+			* so we do it in two steps. Be aware that xe
+			* may be -1 */
+			residue = xm << (xe + 1);
+			residue <<= 31 - SP_MBITS;
+			round = (residue >> 31) != 0;
+			sticky = (residue << 1) != 0;
+			xm >>= SP_MBITS - xe;
+		}
+		odd = (xm & 0x1) != 0x0;
+		switch (ieee754_csr.rm) {
+		case IEEE754_RN:
+			if (round && (sticky || odd))
+				xm++;
+			break;
+		case IEEE754_RZ:
+			break;
+		case IEEE754_RU:	/* toward +Infinity */
+			if ((round || sticky) && !xs)
+				xm++;
+			break;
+		case IEEE754_RD:	/* toward -Infinity */
+			if ((round || sticky) && xs)
+				xm++;
+			break;
+		}
+		if ((xm >> 31) != 0) {
+			/* This can happen after rounding */
+			SETCX(IEEE754_INVALID_OPERATION);
+			return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x);
+		}
+		if (round || sticky)
+			SETCX(IEEE754_INEXACT);
+	}
+	if (xs)
+		return -xm;
+	else
+		return xm;
+}
+
+
+unsigned int ieee754sp_tuns(ieee754sp x)
+{
+	ieee754sp hb = ieee754sp_1e31();
+
+	/* what if x < 0 ?? */
+	if (ieee754sp_lt(x, hb))
+		return (unsigned) ieee754sp_tint(x);
+
+	return (unsigned) ieee754sp_tint(ieee754sp_sub(x, hb)) |
+	    ((unsigned) 1 << 31);
+}
diff --git a/arch/mips/math-emu/sp_tlong.c b/arch/mips/math-emu/sp_tlong.c
new file mode 100644
index 0000000..4be21aa
--- /dev/null
+++ b/arch/mips/math-emu/sp_tlong.c
@@ -0,0 +1,123 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * http://www.algor.co.uk
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+s64 ieee754sp_tlong(ieee754sp x)
+{
+	COMPXDP;		/* <-- need 64-bit mantissa tmp */
+
+	CLEARCX;
+
+	EXPLODEXSP;
+	FLUSHXSP;
+
+	switch (xc) {
+	case IEEE754_CLASS_SNAN:
+	case IEEE754_CLASS_QNAN:
+	case IEEE754_CLASS_INF:
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x);
+	case IEEE754_CLASS_ZERO:
+		return 0;
+	case IEEE754_CLASS_DNORM:
+	case IEEE754_CLASS_NORM:
+		break;
+	}
+	if (xe >= 63) {
+		/* look for valid corner case */
+		if (xe == 63 && xs && xm == SP_HIDDEN_BIT)
+			return -0x8000000000000000LL;
+		/* Set invalid. We will only use overflow for floating
+		   point overflow */
+		SETCX(IEEE754_INVALID_OPERATION);
+		return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x);
+	}
+	/* oh gawd */
+	if (xe > SP_MBITS) {
+		xm <<= xe - SP_MBITS;
+	} else if (xe < SP_MBITS) {
+		u32 residue;
+		int round;
+		int sticky;
+		int odd;
+
+		if (xe < -1) {
+			residue = xm;
+			round = 0;
+			sticky = residue != 0;
+			xm = 0;
+		}
+		else {
+			residue = xm << (32 - SP_MBITS + xe);
+			round = (residue >> 31) != 0;
+			sticky = (residue << 1) != 0;
+			xm >>= SP_MBITS - xe;
+		}
+		odd = (xm & 0x1) != 0x0;
+		switch (ieee754_csr.rm) {
+		case IEEE754_RN:
+			if (round && (sticky || odd))
+				xm++;
+			break;
+		case IEEE754_RZ:
+			break;
+		case IEEE754_RU:	/* toward +Infinity */
+			if ((round || sticky) && !xs)
+				xm++;
+			break;
+		case IEEE754_RD:	/* toward -Infinity */
+			if ((round || sticky) && xs)
+				xm++;
+			break;
+		}
+		if ((xm >> 63) != 0) {
+			/* This can happen after rounding */
+			SETCX(IEEE754_INVALID_OPERATION);
+			return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x);
+		}
+		if (round || sticky)
+			SETCX(IEEE754_INEXACT);
+	}
+	if (xs)
+		return -xm;
+	else
+		return xm;
+}
+
+
+u64 ieee754sp_tulong(ieee754sp x)
+{
+	ieee754sp hb = ieee754sp_1e63();
+
+	/* what if x < 0 ?? */
+	if (ieee754sp_lt(x, hb))
+		return (u64) ieee754sp_tlong(x);
+
+	return (u64) ieee754sp_tlong(ieee754sp_sub(x, hb)) |
+	    (1ULL << 63);
+}
diff --git a/arch/mips/mips-boards/atlas/Makefile b/arch/mips/mips-boards/atlas/Makefile
new file mode 100644
index 0000000..d8dab75
--- /dev/null
+++ b/arch/mips/mips-boards/atlas/Makefile
@@ -0,0 +1,20 @@
+#
+# Carsten Langgaard, carstenl@mips.com
+# Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+#
+# This program is free software; you can distribute it and/or modify it
+# under the terms of the GNU General Public License (Version 2) as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+
+obj-y			:= atlas_int.o atlas_setup.o
+obj-$(CONFIG_KGDB)	+= atlas_gdb.o
diff --git a/arch/mips/mips-boards/atlas/atlas_gdb.c b/arch/mips/mips-boards/atlas/atlas_gdb.c
new file mode 100644
index 0000000..fb65280
--- /dev/null
+++ b/arch/mips/mips-boards/atlas/atlas_gdb.c
@@ -0,0 +1,97 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * This is the interface to the remote debugger stub.
+ */
+#include <asm/io.h>
+#include <asm/mips-boards/atlas.h>
+#include <asm/mips-boards/saa9730_uart.h>
+
+#define INB(a)     inb((unsigned long)a)
+#define OUTB(x,a)  outb(x,(unsigned long)a)
+
+/*
+ * This is the interface to the remote debugger stub
+ * if the Philips part is used for the debug port,
+ * called from the platform setup code.
+ */
+void *saa9730_base = (void *)ATLAS_SAA9730_REG;
+
+static int saa9730_kgdb_active = 0;
+
+#define SAA9730_BAUDCLOCK(baud) (((ATLAS_SAA9730_BAUDCLOCK/(baud))/16)-1)
+
+int saa9730_kgdb_hook(int speed)
+{
+	int baudclock;
+	t_uart_saa9730_regmap *kgdb_uart = (t_uart_saa9730_regmap *)(saa9730_base + SAA9730_UART_REGS_ADDR);
+
+        /*
+         * Clear all interrupts
+         */
+	(void) INB(&kgdb_uart->Lsr);
+	(void) INB(&kgdb_uart->Msr);
+	(void) INB(&kgdb_uart->Thr_Rbr);
+	(void) INB(&kgdb_uart->Iir_Fcr);
+
+        /*
+         * Now, initialize the UART
+         */
+	/* 8 data bits, one stop bit, no parity */
+	OUTB(SAA9730_LCR_DATA8, &kgdb_uart->Lcr);
+
+	baudclock = SAA9730_BAUDCLOCK(speed);
+
+	OUTB((baudclock >> 16) & 0xff, &kgdb_uart->BaudDivMsb);
+	OUTB( baudclock        & 0xff, &kgdb_uart->BaudDivLsb);
+
+	/* Set RTS/DTR active */
+	OUTB(SAA9730_MCR_DTR | SAA9730_MCR_RTS, &kgdb_uart->Mcr);
+	saa9730_kgdb_active = 1;
+
+	return speed;
+}
+
+int saa9730_putDebugChar(char c)
+{
+	t_uart_saa9730_regmap *kgdb_uart = (t_uart_saa9730_regmap *)(saa9730_base + SAA9730_UART_REGS_ADDR);
+
+        if (!saa9730_kgdb_active) {     /* need to init device first */
+                return 0;
+        }
+
+        while (!(INB(&kgdb_uart->Lsr) & SAA9730_LSR_THRE))
+                ;
+	OUTB(c, &kgdb_uart->Thr_Rbr);
+
+        return 1;
+}
+
+char saa9730_getDebugChar(void)
+{
+	t_uart_saa9730_regmap *kgdb_uart = (t_uart_saa9730_regmap *)(saa9730_base + SAA9730_UART_REGS_ADDR);
+	char c;
+
+        if (!saa9730_kgdb_active) {     /* need to init device first */
+                return 0;
+        }
+        while (!(INB(&kgdb_uart->Lsr) & SAA9730_LSR_DR))
+                ;
+
+	c = INB(&kgdb_uart->Thr_Rbr);
+	return(c);
+}
diff --git a/arch/mips/mips-boards/atlas/atlas_int.c b/arch/mips/mips-boards/atlas/atlas_int.c
new file mode 100644
index 0000000..8f1d875
--- /dev/null
+++ b/arch/mips/mips-boards/atlas/atlas_int.c
@@ -0,0 +1,142 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * Routines for generic manipulation of the interrupts found on the MIPS
+ * Atlas board.
+ *
+ */
+#include <linux/compiler.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/mips-boards/atlas.h>
+#include <asm/mips-boards/atlasint.h>
+#include <asm/gdb-stub.h>
+
+
+static struct atlas_ictrl_regs *atlas_hw0_icregs;
+
+extern asmlinkage void mipsIRQ(void);
+
+#if 0
+#define DEBUG_INT(x...) printk(x)
+#else
+#define DEBUG_INT(x...)
+#endif
+
+void disable_atlas_irq(unsigned int irq_nr)
+{
+	atlas_hw0_icregs->intrsten = (1 << (irq_nr-ATLASINT_BASE));
+	iob();
+}
+
+void enable_atlas_irq(unsigned int irq_nr)
+{
+	atlas_hw0_icregs->intseten = (1 << (irq_nr-ATLASINT_BASE));
+	iob();
+}
+
+static unsigned int startup_atlas_irq(unsigned int irq)
+{
+	enable_atlas_irq(irq);
+	return 0; /* never anything pending */
+}
+
+#define shutdown_atlas_irq	disable_atlas_irq
+
+#define mask_and_ack_atlas_irq disable_atlas_irq
+
+static void end_atlas_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_atlas_irq(irq);
+}
+
+static struct hw_interrupt_type atlas_irq_type = {
+	"Atlas",
+	startup_atlas_irq,
+	shutdown_atlas_irq,
+	enable_atlas_irq,
+	disable_atlas_irq,
+	mask_and_ack_atlas_irq,
+	end_atlas_irq,
+	NULL
+};
+
+static inline int ls1bit32(unsigned int x)
+{
+	int b = 31, s;
+
+	s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s;
+	s =  8; if (x <<  8 == 0) s = 0; b -= s; x <<= s;
+	s =  4; if (x <<  4 == 0) s = 0; b -= s; x <<= s;
+	s =  2; if (x <<  2 == 0) s = 0; b -= s; x <<= s;
+	s =  1; if (x <<  1 == 0) s = 0; b -= s;
+
+	return b;
+}
+
+void atlas_hw0_irqdispatch(struct pt_regs *regs)
+{
+	unsigned long int_status;
+	int irq;
+
+	int_status = atlas_hw0_icregs->intstatus;
+
+	/* if int_status == 0, then the interrupt has already been cleared */
+	if (unlikely(int_status == 0))
+		return;
+
+	irq = ATLASINT_BASE + ls1bit32(int_status);
+
+	DEBUG_INT("atlas_hw0_irqdispatch: irq=%d\n", irq);
+
+	do_IRQ(irq, regs);
+}
+
+void __init arch_init_irq(void)
+{
+	int i;
+
+	atlas_hw0_icregs = (struct atlas_ictrl_regs *)ioremap (ATLAS_ICTRL_REGS_BASE, sizeof(struct atlas_ictrl_regs *));
+	
+	/*
+	 * Mask out all interrupt by writing "1" to all bit position in
+	 * the interrupt reset reg.
+	 */
+	atlas_hw0_icregs->intrsten = 0xffffffff;
+
+	/* Now safe to set the exception vector. */
+	set_except_vector(0, mipsIRQ);
+
+	for (i = ATLASINT_BASE; i <= ATLASINT_END; i++) {
+		irq_desc[i].status	= IRQ_DISABLED;
+		irq_desc[i].action	= 0;
+		irq_desc[i].depth	= 1;
+		irq_desc[i].handler	= &atlas_irq_type;
+		spin_lock_init(&irq_desc[i].lock);
+	}
+}
diff --git a/arch/mips/mips-boards/atlas/atlas_setup.c b/arch/mips/mips-boards/atlas/atlas_setup.c
new file mode 100644
index 0000000..0a1dd9b
--- /dev/null
+++ b/arch/mips/mips-boards/atlas/atlas_setup.c
@@ -0,0 +1,95 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+#include <asm/mips-boards/atlas.h>
+#include <asm/mips-boards/atlasint.h>
+#include <asm/time.h>
+#include <asm/traps.h>
+
+extern void mips_reboot_setup(void);
+extern void mips_time_init(void);
+extern void mips_timer_setup(struct irqaction *irq);
+extern unsigned long mips_rtc_get_time(void);
+
+#ifdef CONFIG_KGDB
+extern void kgdb_config(void);
+#endif
+
+static void __init serial_init(void);
+
+const char *get_system_type(void)
+{
+	return "MIPS Atlas";
+}
+
+static int __init atlas_setup(void)
+{
+	ioport_resource.end = 0x7fffffff;
+
+	serial_init ();
+
+#ifdef CONFIG_KGDB
+	kgdb_config();
+#endif
+	mips_reboot_setup();
+
+	board_time_init = mips_time_init;
+	board_timer_setup = mips_timer_setup;
+	rtc_get_time = mips_rtc_get_time;
+
+	return 0;
+}
+
+early_initcall(atlas_setup);
+
+static void __init serial_init(void)
+{
+#ifdef CONFIG_SERIAL_8250
+	struct uart_port s;
+
+	memset(&s, 0, sizeof(s));
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+	s.iobase = ATLAS_UART_REGS_BASE;
+#else
+	s.iobase = ATLAS_UART_REGS_BASE+3;
+#endif
+	s.irq = ATLASINT_UART;
+	s.uartclk = ATLAS_BASE_BAUD * 16;
+	s.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
+	s.iotype = SERIAL_IO_PORT;
+	s.regshift = 3;
+
+	if (early_serial_setup(&s) != 0) {
+		printk(KERN_ERR "Serial setup failed!\n");
+	}
+#endif
+}
diff --git a/arch/mips/mips-boards/generic/Makefile b/arch/mips/mips-boards/generic/Makefile
new file mode 100644
index 0000000..b21bc68
--- /dev/null
+++ b/arch/mips/mips-boards/generic/Makefile
@@ -0,0 +1,26 @@
+#
+# Carsten Langgaard, carstenl@mips.com
+# Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+#
+# This program is free software; you can distribute it and/or modify it
+# under the terms of the GNU General Public License (Version 2) as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Makefile for the MIPS boards generic routines under Linux.
+#
+
+obj-y				:= mipsIRQ.o reset.o display.o init.o memory.o \
+				   printf.o cmdline.o time.o
+obj-$(CONFIG_PCI)		+= pci.o
+obj-$(CONFIG_KGDB)		+= gdb_hook.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/mips-boards/generic/cmdline.c b/arch/mips/mips-boards/generic/cmdline.c
new file mode 100644
index 0000000..1871c30
--- /dev/null
+++ b/arch/mips/mips-boards/generic/cmdline.c
@@ -0,0 +1,59 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Kernel command line creation using the prom monitor (YAMON) argc/argv.
+ */
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+
+extern int prom_argc;
+extern int *_prom_argv;
+
+/*
+ * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer.
+ * This macro take care of sign extension.
+ */
+#define prom_argv(index) ((char *)(long)_prom_argv[(index)])
+
+char * __init prom_getcmdline(void)
+{
+	return &(arcs_cmdline[0]);
+}
+
+
+void  __init prom_init_cmdline(void)
+{
+	char *cp;
+	int actr;
+
+	actr = 1; /* Always ignore argv[0] */
+
+	cp = &(arcs_cmdline[0]);
+	while(actr < prom_argc) {
+	        strcpy(cp, prom_argv(actr));
+		cp += strlen(prom_argv(actr));
+		*cp++ = ' ';
+		actr++;
+	}
+	if (cp != &(arcs_cmdline[0])) {
+		/* get rid of trailing space */
+		--cp;
+		*cp = '\0';
+	}
+}
diff --git a/arch/mips/mips-boards/generic/display.c b/arch/mips/mips-boards/generic/display.c
new file mode 100644
index 0000000..f653946
--- /dev/null
+++ b/arch/mips/mips-boards/generic/display.c
@@ -0,0 +1,39 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Display routines for display messages in MIPS boards ascii display.
+ */
+
+#include <linux/compiler.h>
+#include <asm/io.h>
+#include <asm/mips-boards/generic.h>
+
+void mips_display_message(const char *str)
+{
+	static volatile unsigned int *display = NULL;
+	int i;
+
+	if (unlikely(display == NULL))
+		display = (volatile unsigned int *)ioremap(ASCII_DISPLAY_POS_BASE, 16*sizeof(int));
+
+	for (i = 0; i <= 14; i=i+2) {
+	         if (*str)
+		         display[i] = *str++;
+		 else
+		         display[i] = ' ';
+	}
+}
diff --git a/arch/mips/mips-boards/generic/gdb_hook.c b/arch/mips/mips-boards/generic/gdb_hook.c
new file mode 100644
index 0000000..91a2ccb
--- /dev/null
+++ b/arch/mips/mips-boards/generic/gdb_hook.c
@@ -0,0 +1,133 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * This is the interface to the remote debugger stub.
+ */
+#include <linux/types.h>
+#include <linux/serial.h>
+#include <linux/serialP.h>
+#include <linux/serial_reg.h>
+
+#include <asm/serial.h>
+#include <asm/io.h>
+
+static struct serial_state rs_table[RS_TABLE_SIZE] = {
+	SERIAL_PORT_DFNS	/* Defined in serial.h */
+};
+
+static struct async_struct kdb_port_info = {0};
+
+int (*generic_putDebugChar)(char);
+char (*generic_getDebugChar)(void);
+
+static __inline__ unsigned int serial_in(struct async_struct *info, int offset)
+{
+	return inb(info->port + offset);
+}
+
+static __inline__ void serial_out(struct async_struct *info, int offset,
+				int value)
+{
+	outb(value, info->port+offset);
+}
+
+int rs_kgdb_hook(int tty_no, int speed) {
+	int t;
+	struct serial_state *ser = &rs_table[tty_no];
+
+	kdb_port_info.state = ser;
+	kdb_port_info.magic = SERIAL_MAGIC;
+	kdb_port_info.port = ser->port;
+	kdb_port_info.flags = ser->flags;
+
+	/*
+	 * Clear all interrupts
+	 */
+	serial_in(&kdb_port_info, UART_LSR);
+	serial_in(&kdb_port_info, UART_RX);
+	serial_in(&kdb_port_info, UART_IIR);
+	serial_in(&kdb_port_info, UART_MSR);
+
+	/*
+	 * Now, initialize the UART
+	 */
+	serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8);	/* reset DLAB */
+	if (kdb_port_info.flags & ASYNC_FOURPORT) {
+		kdb_port_info.MCR = UART_MCR_DTR | UART_MCR_RTS;
+		t = UART_MCR_DTR | UART_MCR_OUT1;
+	} else {
+		kdb_port_info.MCR
+			= UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
+		t = UART_MCR_DTR | UART_MCR_RTS;
+	}
+
+	kdb_port_info.MCR = t;		/* no interrupts, please */
+	serial_out(&kdb_port_info, UART_MCR, kdb_port_info.MCR);
+
+	/*
+	 * and set the speed of the serial port
+	 */
+	if (speed == 0)
+		speed = 9600;
+
+	t = kdb_port_info.state->baud_base / speed;
+	/* set DLAB */
+	serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8 | UART_LCR_DLAB);
+	serial_out(&kdb_port_info, UART_DLL, t & 0xff);/* LS of divisor */
+	serial_out(&kdb_port_info, UART_DLM, t >> 8);  /* MS of divisor */
+	/* reset DLAB */
+	serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8);
+
+	return speed;
+}
+
+int putDebugChar(char c)
+{
+	return generic_putDebugChar(c);
+}
+
+char getDebugChar(void)
+{
+	return generic_getDebugChar();
+}
+
+int rs_putDebugChar(char c)
+{
+
+	if (!kdb_port_info.state) { 	/* need to init device first */
+		return 0;
+	}
+
+	while ((serial_in(&kdb_port_info, UART_LSR) & UART_LSR_THRE) == 0)
+		;
+
+	serial_out(&kdb_port_info, UART_TX, c);
+
+	return 1;
+}
+
+char rs_getDebugChar(void)
+{
+	if (!kdb_port_info.state) { 	/* need to init device first */
+		return 0;
+	}
+
+	while (!(serial_in(&kdb_port_info, UART_LSR) & 1))
+		;
+
+	return serial_in(&kdb_port_info, UART_RX);
+}
diff --git a/arch/mips/mips-boards/generic/init.c b/arch/mips/mips-boards/generic/init.c
new file mode 100644
index 0000000..31caf06
--- /dev/null
+++ b/arch/mips/mips-boards/generic/init.c
@@ -0,0 +1,343 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * PROM library initialisation code.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+#include <asm/io.h>
+#include <asm/bootinfo.h>
+#include <asm/mips-boards/prom.h>
+#include <asm/mips-boards/generic.h>
+#ifdef CONFIG_MIPS_GT64120
+#include <asm/gt64120.h>
+#endif
+#include <asm/mips-boards/msc01_pci.h>
+#include <asm/mips-boards/bonito64.h>
+#ifdef CONFIG_MIPS_MALTA
+#include <asm/mips-boards/malta.h>
+#endif
+
+#ifdef CONFIG_KGDB
+extern int rs_kgdb_hook(int, int);
+extern int rs_putDebugChar(char);
+extern char rs_getDebugChar(void);
+extern int saa9730_kgdb_hook(int);
+extern int saa9730_putDebugChar(char);
+extern char saa9730_getDebugChar(void);
+#endif
+
+int prom_argc;
+int *_prom_argv, *_prom_envp;
+
+/*
+ * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer.
+ * This macro take care of sign extension, if running in 64-bit mode.
+ */
+#define prom_envp(index) ((char *)(long)_prom_envp[(index)])
+
+int init_debug = 0;
+
+unsigned int mips_revision_corid;
+
+/* Bonito64 system controller register base. */
+unsigned long _pcictrl_bonito;
+unsigned long _pcictrl_bonito_pcicfg;
+
+/* GT64120 system controller register base */
+unsigned long _pcictrl_gt64120;
+
+/* MIPS System controller register base */
+unsigned long _pcictrl_msc;
+
+char *prom_getenv(char *envname)
+{
+	/*
+	 * Return a pointer to the given environment variable.
+	 * In 64-bit mode: we're using 64-bit pointers, but all pointers
+	 * in the PROM structures are only 32-bit, so we need some
+	 * workarounds, if we are running in 64-bit mode.
+	 */
+	int i, index=0;
+
+	i = strlen(envname);
+
+	while (prom_envp(index)) {
+		if(strncmp(envname, prom_envp(index), i) == 0) {
+			return(prom_envp(index+1));
+		}
+		index += 2;
+	}
+
+	return NULL;
+}
+
+static inline unsigned char str2hexnum(unsigned char c)
+{
+	if (c >= '0' && c <= '9')
+		return c - '0';
+	if (c >= 'a' && c <= 'f')
+		return c - 'a' + 10;
+	return 0; /* foo */
+}
+
+static inline void str2eaddr(unsigned char *ea, unsigned char *str)
+{
+	int i;
+
+	for (i = 0; i < 6; i++) {
+		unsigned char num;
+
+		if((*str == '.') || (*str == ':'))
+			str++;
+		num = str2hexnum(*str++) << 4;
+		num |= (str2hexnum(*str++));
+		ea[i] = num;
+	}
+}
+
+int get_ethernet_addr(char *ethernet_addr)
+{
+        char *ethaddr_str;
+
+        ethaddr_str = prom_getenv("ethaddr");
+	if (!ethaddr_str) {
+	        printk("ethaddr not set in boot prom\n");
+		return -1;
+	}
+	str2eaddr(ethernet_addr, ethaddr_str);
+
+	if (init_debug > 1) {
+	        int i;
+		printk("get_ethernet_addr: ");
+	        for (i=0; i<5; i++)
+		        printk("%02x:", (unsigned char)*(ethernet_addr+i));
+		printk("%02x\n", *(ethernet_addr+i));
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+static void __init console_config(void)
+{
+	char console_string[40];
+	int baud = 0;
+	char parity = '\0', bits = '\0', flow = '\0';
+	char *s;
+
+	if ((strstr(prom_getcmdline(), "console=ttyS")) == NULL) {
+		s = prom_getenv("modetty0");
+		if (s) {
+			while (*s >= '0' && *s <= '9')
+				baud = baud*10 + *s++ - '0';
+			if (*s == ',') s++;
+			if (*s) parity = *s++;
+			if (*s == ',') s++;
+			if (*s) bits = *s++;
+			if (*s == ',') s++;
+			if (*s == 'h') flow = 'r';
+		}
+		if (baud == 0)
+			baud = 38400;
+		if (parity != 'n' && parity != 'o' && parity != 'e')
+			parity = 'n';
+		if (bits != '7' && bits != '8')
+			bits = '8';
+		if (flow == '\0')
+			flow = 'r';
+		sprintf (console_string, " console=ttyS0,%d%c%c%c", baud, parity, bits, flow);
+		strcat (prom_getcmdline(), console_string);
+		prom_printf("Config serial console:%s\n", console_string);
+	}
+}
+#endif
+
+#ifdef CONFIG_KGDB
+void __init kgdb_config (void)
+{
+	extern int (*generic_putDebugChar)(char);
+	extern char (*generic_getDebugChar)(void);
+	char *argptr;
+	int line, speed;
+
+	argptr = prom_getcmdline();
+	if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) {
+		argptr += strlen("kgdb=ttyS");
+		if (*argptr != '0' && *argptr != '1')
+			printk("KGDB: Unknown serial line /dev/ttyS%c, "
+			       "falling back to /dev/ttyS1\n", *argptr);
+		line = *argptr == '0' ? 0 : 1;
+		printk("KGDB: Using serial line /dev/ttyS%d for session\n", line);
+
+		speed = 0;
+		if (*++argptr == ',')
+		{
+			int c;
+			while ((c = *++argptr) && ('0' <= c && c <= '9'))
+				speed = speed * 10 + c - '0';
+		}
+#ifdef CONFIG_MIPS_ATLAS
+		if (line == 1) {
+			speed = saa9730_kgdb_hook(speed);
+			generic_putDebugChar = saa9730_putDebugChar;
+			generic_getDebugChar = saa9730_getDebugChar;
+		}
+		else 
+#endif
+		{
+			speed = rs_kgdb_hook(line, speed);
+			generic_putDebugChar = rs_putDebugChar;
+			generic_getDebugChar = rs_getDebugChar;
+		}
+
+		prom_printf("KGDB: Using serial line /dev/ttyS%d at %d for session, "
+			    "please connect your debugger\n", line ? 1 : 0, speed);
+
+		{
+			char *s;
+			for (s = "Please connect GDB to this port\r\n"; *s; )
+				generic_putDebugChar (*s++);
+		}
+
+		kgdb_enabled = 1;
+		/* Breakpoint is invoked after interrupts are initialised */
+	}
+}
+#endif
+
+void __init prom_init(void)
+{
+	prom_argc = fw_arg0;
+	_prom_argv = (int *) fw_arg1;
+	_prom_envp = (int *) fw_arg2;
+
+	mips_display_message("LINUX");
+
+#ifdef CONFIG_MIPS_SEAD
+	set_io_port_base(KSEG1);
+#else
+	/*
+	 * early setup of _pcictrl_bonito so that we can determine
+	 * the system controller on a CORE_EMUL board
+	 */
+	_pcictrl_bonito = (unsigned long)ioremap(BONITO_REG_BASE, BONITO_REG_SIZE);
+
+	mips_revision_corid = MIPS_REVISION_CORID;
+
+	if (mips_revision_corid == MIPS_REVISION_CORID_CORE_EMUL) {
+		if (BONITO_PCIDID == 0x0001df53 || 
+		    BONITO_PCIDID == 0x0003df53)
+			mips_revision_corid = MIPS_REVISION_CORID_CORE_EMUL_BON;
+		else
+			mips_revision_corid = MIPS_REVISION_CORID_CORE_EMUL_MSC;
+	}
+	switch(mips_revision_corid) {
+	case MIPS_REVISION_CORID_QED_RM5261:
+	case MIPS_REVISION_CORID_CORE_LV:
+	case MIPS_REVISION_CORID_CORE_FPGA:
+	case MIPS_REVISION_CORID_CORE_FPGAR2:
+		/*
+		 * Setup the North bridge to do Master byte-lane swapping
+		 * when running in bigendian.
+		 */
+		_pcictrl_gt64120 = (unsigned long)ioremap(MIPS_GT_BASE, 0x2000);
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+		GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT |
+			 GT_PCI0_CMD_SBYTESWAP_BIT);
+#else
+		GT_WRITE(GT_PCI0_CMD_OFS, 0);
+#endif
+
+#ifdef CONFIG_MIPS_MALTA
+		set_io_port_base(MALTA_GT_PORT_BASE);
+#else
+		set_io_port_base((unsigned long)ioremap(0, 0x20000000));
+#endif
+		break;
+
+	case MIPS_REVISION_CORID_CORE_EMUL_BON:
+	case MIPS_REVISION_CORID_BONITO64:
+	case MIPS_REVISION_CORID_CORE_20K:
+		_pcictrl_bonito_pcicfg = (unsigned long)ioremap(BONITO_PCICFG_BASE, BONITO_PCICFG_SIZE);
+
+		/*
+		 * Disable Bonito IOBC.
+		 */
+		BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG &
+			~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |
+			  BONITO_PCIMEMBASECFG_MEMBASE1_CACHED);
+
+		/*
+		 * Setup the North bridge to do Master byte-lane swapping
+		 * when running in bigendian.
+		 */
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+		BONITO_BONGENCFG = BONITO_BONGENCFG &
+			~(BONITO_BONGENCFG_MSTRBYTESWAP |
+			  BONITO_BONGENCFG_BYTESWAP);
+#else
+		BONITO_BONGENCFG = BONITO_BONGENCFG |
+			BONITO_BONGENCFG_MSTRBYTESWAP |
+			BONITO_BONGENCFG_BYTESWAP;
+#endif
+
+#ifdef CONFIG_MIPS_MALTA
+		set_io_port_base(MALTA_BONITO_PORT_BASE);
+#else
+		set_io_port_base((unsigned long)ioremap(0, 0x20000000));
+#endif
+		break;
+
+	case MIPS_REVISION_CORID_CORE_MSC:
+	case MIPS_REVISION_CORID_CORE_FPGA2:
+	case MIPS_REVISION_CORID_CORE_EMUL_MSC:
+		_pcictrl_msc = (unsigned long)ioremap(MIPS_MSC01_PCI_REG_BASE, 0x2000); 
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+		MSC_WRITE(MSC01_PCI_SWAP, MSC01_PCI_SWAP_NOSWAP);
+#else
+		MSC_WRITE(MSC01_PCI_SWAP,
+			  MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_IO_SHF |
+			  MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_MEM_SHF |
+			  MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_BAR0_SHF);
+#endif
+
+#ifdef CONFIG_MIPS_MALTA
+		set_io_port_base(MALTA_MSC_PORT_BASE);
+#else
+		set_io_port_base((unsigned long)ioremap(0, 0x20000000));
+#endif
+		break;
+
+	default:
+		/* Unknown Core card */
+		mips_display_message("CC Error");
+		while(1);   /* We die here... */
+	}
+#endif
+	prom_printf("\nLINUX started...\n");
+	prom_init_cmdline();
+	prom_meminit();
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+	console_config();
+#endif
+}
diff --git a/arch/mips/mips-boards/generic/memory.c b/arch/mips/mips-boards/generic/memory.c
new file mode 100644
index 0000000..5ae2b43
--- /dev/null
+++ b/arch/mips/mips-boards/generic/memory.c
@@ -0,0 +1,173 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * PROM library functions for acquiring/using memory descriptors given to
+ * us from the YAMON.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+
+#include <asm/mips-boards/prom.h>
+
+/*#define DEBUG*/
+
+enum yamon_memtypes {
+	yamon_dontuse,
+	yamon_prom,
+	yamon_free,
+};
+struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
+
+#ifdef DEBUG
+static char *mtypes[3] = {
+	"Dont use memory",
+	"YAMON PROM memory",
+	"Free memmory",
+};
+#endif
+
+/* References to section boundaries */
+extern char _end;
+
+#define PFN_ALIGN(x)    (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
+
+
+struct prom_pmemblock * __init prom_getmdesc(void)
+{
+	char *memsize_str;
+	unsigned int memsize;
+
+	memsize_str = prom_getenv("memsize");
+	if (!memsize_str) {
+		prom_printf("memsize not set in boot prom, set to default (32Mb)\n");
+		memsize = 0x02000000;
+	} else {
+#ifdef DEBUG
+		prom_printf("prom_memsize = %s\n", memsize_str);
+#endif
+		memsize = simple_strtol(memsize_str, NULL, 0);
+	}
+
+	memset(mdesc, 0, sizeof(mdesc));
+
+	mdesc[0].type = yamon_dontuse;
+	mdesc[0].base = 0x00000000;
+	mdesc[0].size = 0x00001000;
+
+	mdesc[1].type = yamon_prom;
+	mdesc[1].base = 0x00001000;
+	mdesc[1].size = 0x000ef000;
+
+#ifdef CONFIG_MIPS_MALTA
+	/*
+	 * The area 0x000f0000-0x000fffff is allocated for BIOS memory by the
+	 * south bridge and PCI access always forwarded to the ISA Bus and
+	 * BIOSCS# is always generated.
+	 * This mean that this area can't be used as DMA memory for PCI
+	 * devices.
+	 */
+	mdesc[2].type = yamon_dontuse;
+	mdesc[2].base = 0x000f0000;
+	mdesc[2].size = 0x00010000;
+#else
+	mdesc[2].type = yamon_prom;
+	mdesc[2].base = 0x000f0000;
+	mdesc[2].size = 0x00010000;
+#endif
+
+	mdesc[3].type = yamon_dontuse;
+	mdesc[3].base = 0x00100000;
+	mdesc[3].size = CPHYSADDR(PFN_ALIGN(&_end)) - mdesc[3].base;
+
+	mdesc[4].type = yamon_free;
+	mdesc[4].base = CPHYSADDR(PFN_ALIGN(&_end));
+	mdesc[4].size = memsize - mdesc[4].base;
+
+	return &mdesc[0];
+}
+
+static int __init prom_memtype_classify (unsigned int type)
+{
+	switch (type) {
+	case yamon_free:
+		return BOOT_MEM_RAM;
+	case yamon_prom:
+		return BOOT_MEM_ROM_DATA;
+	default:
+		return BOOT_MEM_RESERVED;
+	}
+}
+
+void __init prom_meminit(void)
+{
+	struct prom_pmemblock *p;
+
+#ifdef DEBUG
+	prom_printf("YAMON MEMORY DESCRIPTOR dump:\n");
+	p = prom_getmdesc();
+	while (p->size) {
+		int i = 0;
+		prom_printf("[%d,%p]: base<%08lx> size<%08lx> type<%s>\n",
+			    i, p, p->base, p->size, mtypes[p->type]);
+		p++;
+		i++;
+	}
+#endif
+	p = prom_getmdesc();
+
+	while (p->size) {
+		long type;
+		unsigned long base, size;
+
+		type = prom_memtype_classify (p->type);
+		base = p->base;
+		size = p->size;
+
+		add_memory_region(base, size, type);
+                p++;
+	}
+}
+
+unsigned long __init prom_free_prom_memory(void)
+{
+	unsigned long freed = 0;
+	unsigned long addr;
+	int i;
+
+	for (i = 0; i < boot_mem_map.nr_map; i++) {
+		if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
+			continue;
+
+		addr = boot_mem_map.map[i].addr;
+		while (addr < boot_mem_map.map[i].addr
+			      + boot_mem_map.map[i].size) {
+			ClearPageReserved(virt_to_page(__va(addr)));
+			set_page_count(virt_to_page(__va(addr)), 1);
+			free_page((unsigned long)__va(addr));
+			addr += PAGE_SIZE;
+			freed += PAGE_SIZE;
+		}
+	}
+	printk("Freeing prom memory: %ldkb freed\n", freed >> 10);
+
+	return freed;
+}
diff --git a/arch/mips/mips-boards/generic/mipsIRQ.S b/arch/mips/mips-boards/generic/mipsIRQ.S
new file mode 100644
index 0000000..131f49b
--- /dev/null
+++ b/arch/mips/mips-boards/generic/mipsIRQ.S
@@ -0,0 +1,153 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999, 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * Interrupt exception dispatch code.
+ *
+ */
+#include <linux/config.h>
+
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/* A lot of complication here is taken away because:
+ *
+ * 1) We handle one interrupt and return, sitting in a loop and moving across
+ *    all the pending IRQ bits in the cause register is _NOT_ the answer, the
+ *    common case is one pending IRQ so optimize in that direction.
+ *
+ * 2) We need not check against bits in the status register IRQ mask, that
+ *    would make this routine slow as hell.
+ *
+ * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
+ *    between like BSD spl() brain-damage.
+ *
+ * Furthermore, the IRQs on the MIPS board look basically (barring software
+ * IRQs which we don't use at all and all external interrupt sources are
+ * combined together on hardware interrupt 0 (MIPS IRQ 2)) like:
+ *
+ *	MIPS IRQ	Source
+ *      --------        ------
+ *             0	Software (ignored)
+ *             1        Software (ignored)
+ *             2        Combined hardware interrupt (hw0)
+ *             3        Hardware (ignored)
+ *             4        Hardware (ignored)
+ *             5        Hardware (ignored)
+ *             6        Hardware (ignored)
+ *             7        R4k timer (what we use)
+ *
+ * Note: On the SEAD board thing are a little bit different.
+ *       Here IRQ 2 (hw0) is wired to the UART0 and IRQ 3 (hw1) is wired
+ *       wired to UART1.
+ *
+ * We handle the IRQ according to _our_ priority which is:
+ *
+ * Highest ----     R4k Timer
+ * Lowest  ----     Combined hardware interrupt
+ *
+ * then we just return, if multiple IRQs are pending then we will just take
+ * another exception, big deal.
+ */
+
+	.text
+	.set	noreorder
+	.set	noat
+	.align	5
+	NESTED(mipsIRQ, PT_SIZE, sp)
+	SAVE_ALL
+	CLI
+	.set	at
+
+	mfc0	s0, CP0_CAUSE		# get irq bits
+	mfc0	s1, CP0_STATUS		# get irq mask
+	and	s0, s1
+
+	/* First we check for r4k counter/timer IRQ. */
+	andi	a0, s0, CAUSEF_IP7
+	beq	a0, zero, 1f
+	 andi	a0, s0, CAUSEF_IP2	# delay slot, check hw0 interrupt
+
+	/* Wheee, a timer interrupt. */
+	move	a0, sp
+	jal	mips_timer_interrupt
+	 nop
+
+	j	ret_from_irq
+	 nop
+
+1:
+#if defined(CONFIG_MIPS_SEAD)
+	beq	a0, zero, 1f
+	 andi	a0, s0, CAUSEF_IP3	# delay slot, check hw1 interrupt
+#else
+	beq	a0, zero, 1f		# delay slot, check hw3 interrupt
+ 	 andi	a0, s0, CAUSEF_IP5
+#endif
+
+	/* Wheee, combined hardware level zero interrupt. */
+#if defined(CONFIG_MIPS_ATLAS)
+	jal	atlas_hw0_irqdispatch
+#elif defined(CONFIG_MIPS_MALTA)
+	jal	malta_hw0_irqdispatch
+#elif defined(CONFIG_MIPS_SEAD)
+	jal	sead_hw0_irqdispatch
+#else
+#error "MIPS board not supported\n"
+#endif
+	 move	a0, sp			# delay slot
+
+	j	ret_from_irq
+	 nop				# delay slot
+
+1:
+#if defined(CONFIG_MIPS_SEAD)
+	beq	a0, zero, 1f
+	 andi	a0, s0, CAUSEF_IP5	# delay slot, check hw3 interrupt
+	jal	sead_hw1_irqdispatch
+	 move	a0, sp			# delay slot
+	j	ret_from_irq
+	 nop				# delay slot
+1:
+#endif
+#if defined(CONFIG_MIPS_MALTA)
+	beq	a0, zero, 1f            # check hw3 (coreHI) interrupt
+	 nop
+	jal	corehi_irqdispatch
+	 move	a0, sp
+	j	ret_from_irq
+	 nop
+1:
+#endif
+	/*
+	 * Here by mistake?  This is possible, what can happen is that by the
+	 * time we take the exception the IRQ pin goes low, so just leave if
+	 * this is the case.
+	 */
+	move	a1,s0
+	PRINT("Got interrupt: c0_cause = %08x\n")
+	mfc0	a1, CP0_EPC
+	PRINT("c0_epc = %08x\n")
+
+	j	ret_from_irq
+	 nop
+	END(mipsIRQ)
diff --git a/arch/mips/mips-boards/generic/pci.c b/arch/mips/mips-boards/generic/pci.c
new file mode 100644
index 0000000..92c34bd
--- /dev/null
+++ b/arch/mips/mips-boards/generic/pci.c
@@ -0,0 +1,163 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999, 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * MIPS boards specific PCI support.
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/mips-boards/generic.h>
+#include <asm/gt64120.h>
+#include <asm/mips-boards/bonito64.h>
+#include <asm/mips-boards/msc01_pci.h>
+#ifdef CONFIG_MIPS_MALTA
+#include <asm/mips-boards/malta.h>
+#endif
+
+static struct resource bonito64_mem_resource = {
+	.name	= "Bonito PCI MEM",
+	.start	= 0x10000000UL,
+	.end	= 0x1bffffffUL,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct resource bonito64_io_resource = {
+	.name	= "Bonito IO MEM",
+	.start	= 0x00002000UL,	/* avoid conflicts with YAMON allocated I/O addresses */
+	.end	= 0x000fffffUL,
+	.flags	= IORESOURCE_IO,
+};
+
+static struct resource gt64120_mem_resource = {
+	.name	= "GT64120 PCI MEM",
+	.start	= 0x10000000UL,
+	.end	= 0x1bdfffffUL,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct resource gt64120_io_resource = {
+	.name	= "GT64120 IO MEM",
+#ifdef CONFIG_MIPS_ATLAS
+	.start	= 0x18000000UL,
+	.end	= 0x181fffffUL,
+#endif
+#ifdef CONFIG_MIPS_MALTA
+	.start	= 0x00002000UL,
+	.end	= 0x001fffffUL,
+#endif
+	.flags	= IORESOURCE_IO,
+};
+
+static struct resource msc_mem_resource = {
+	.name	= "MSC PCI MEM",
+	.start	= 0x10000000UL,
+	.end	= 0x1fffffffUL,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct resource msc_io_resource = {
+	.name	= "MSC IO MEM",
+	.start	= 0x00002000UL,
+	.end	= 0x007fffffUL,
+	.flags	= IORESOURCE_IO,
+};
+
+extern struct pci_ops bonito64_pci_ops;
+extern struct pci_ops gt64120_pci_ops;
+extern struct pci_ops msc_pci_ops;
+
+static struct pci_controller bonito64_controller = {
+	.pci_ops	= &bonito64_pci_ops,
+	.io_resource	= &bonito64_io_resource,
+	.mem_resource	= &bonito64_mem_resource,
+	.mem_offset	= 0x10000000UL,
+	.io_offset	= 0x00000000UL,
+};
+
+static struct pci_controller gt64120_controller = {
+	.pci_ops	= &gt64120_pci_ops,
+	.io_resource	= &gt64120_io_resource,
+	.mem_resource	= &gt64120_mem_resource,
+	.mem_offset	= 0x00000000UL,
+	.io_offset	= 0x00000000UL,
+};
+
+static struct pci_controller  msc_controller = {
+	.pci_ops	= &msc_pci_ops,
+	.io_resource	= &msc_io_resource,
+	.mem_resource	= &msc_mem_resource,
+	.mem_offset	= 0x10000000UL,
+	.io_offset	= 0x00000000UL,
+};
+
+static int __init pcibios_init(void)
+{
+	struct pci_controller *controller;
+
+	switch (mips_revision_corid) {
+	case MIPS_REVISION_CORID_QED_RM5261:
+	case MIPS_REVISION_CORID_CORE_LV:
+	case MIPS_REVISION_CORID_CORE_FPGA:
+	case MIPS_REVISION_CORID_CORE_FPGAR2:
+		/*
+		 * Due to a bug in the Galileo system controller, we need
+		 * to setup the PCI BAR for the Galileo internal registers.
+		 * This should be done in the bios/bootprom and will be
+		 * fixed in a later revision of YAMON (the MIPS boards
+		 * boot prom).
+		 */
+		GT_WRITE(GT_PCI0_CFGADDR_OFS,
+			 (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | /* Local bus */
+			 (0 << GT_PCI0_CFGADDR_DEVNUM_SHF) | /* GT64120 dev */
+			 (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | /* Function 0*/
+			 ((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) | /* BAR 4*/
+			 GT_PCI0_CFGADDR_CONFIGEN_BIT );
+
+		/* Perform the write */
+		GT_WRITE(GT_PCI0_CFGDATA_OFS, CPHYSADDR(MIPS_GT_BASE));
+
+		controller = &gt64120_controller;
+		break;
+
+	case MIPS_REVISION_CORID_BONITO64:
+	case MIPS_REVISION_CORID_CORE_20K:
+	case MIPS_REVISION_CORID_CORE_EMUL_BON:
+		controller = &bonito64_controller;
+		break;
+
+	case MIPS_REVISION_CORID_CORE_MSC:
+	case MIPS_REVISION_CORID_CORE_FPGA2:
+	case MIPS_REVISION_CORID_CORE_EMUL_MSC:
+		controller = &msc_controller;
+		break;
+	default:
+		return 1;
+	}
+
+	ioport_resource.end = controller->io_resource->end;
+
+	register_pci_controller (controller);
+
+	return 0;
+}
+
+early_initcall(pcibios_init);
diff --git a/arch/mips/mips-boards/generic/printf.c b/arch/mips/mips-boards/generic/printf.c
new file mode 100644
index 0000000..2c1ab1f
--- /dev/null
+++ b/arch/mips/mips-boards/generic/printf.c
@@ -0,0 +1,79 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Putting things on the screen/serial line using YAMONs facilities.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/serial_reg.h>
+#include <linux/spinlock.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_MIPS_ATLAS
+#include <asm/mips-boards/atlas.h>
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+#define PORT(offset) (ATLAS_UART_REGS_BASE     + ((offset)<<3))
+#else
+#define PORT(offset) (ATLAS_UART_REGS_BASE + 3 + ((offset)<<3))
+#endif
+
+#elif defined(CONFIG_MIPS_SEAD)
+
+#include <asm/mips-boards/sead.h>
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+#define PORT(offset) (SEAD_UART0_REGS_BASE     + ((offset)<<3))
+#else
+#define PORT(offset) (SEAD_UART0_REGS_BASE + 3 + ((offset)<<3))
+#endif
+
+#else
+
+#define PORT(offset) (0x3f8 + (offset))
+
+#endif
+
+static inline unsigned int serial_in(int offset)
+{
+	return inb(PORT(offset));
+}
+
+static inline void serial_out(int offset, int value)
+{
+	outb(value, PORT(offset));
+}
+
+int prom_putchar(char c)
+{
+	while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0)
+		;
+
+	serial_out(UART_TX, c);
+
+	return 1;
+}
+
+char prom_getchar(void)
+{
+	while (!(serial_in(UART_LSR) & UART_LSR_DR))
+		;
+
+	return serial_in(UART_RX);
+}
+
diff --git a/arch/mips/mips-boards/generic/reset.c b/arch/mips/mips-boards/generic/reset.c
new file mode 100644
index 0000000..9fdec74
--- /dev/null
+++ b/arch/mips/mips-boards/generic/reset.c
@@ -0,0 +1,73 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * Reset the MIPS boards.
+ *
+ */
+#include <linux/config.h>
+
+#include <asm/io.h>
+#include <asm/reboot.h>
+#include <asm/mips-boards/generic.h>
+#if defined(CONFIG_MIPS_ATLAS)
+#include <asm/mips-boards/atlas.h>
+#endif
+
+static void mips_machine_restart(char *command);
+static void mips_machine_halt(void);
+#if defined(CONFIG_MIPS_ATLAS)
+static void atlas_machine_power_off(void);
+#endif
+
+static void mips_machine_restart(char *command)
+{
+        volatile unsigned int *softres_reg = (unsigned int *)ioremap (SOFTRES_REG, sizeof(unsigned int));
+
+	*softres_reg = GORESET;
+}
+
+static void mips_machine_halt(void)
+{
+        volatile unsigned int *softres_reg = (unsigned int *)ioremap (SOFTRES_REG, sizeof(unsigned int));
+
+	*softres_reg = GORESET;
+}
+
+#if defined(CONFIG_MIPS_ATLAS)
+static void atlas_machine_power_off(void)
+{
+        volatile unsigned int *psustby_reg = (unsigned int *)ioremap(ATLAS_PSUSTBY_REG, sizeof(unsigned int));
+
+	*psustby_reg = ATLAS_GOSTBY;
+}
+#endif
+
+void mips_reboot_setup(void)
+{
+	_machine_restart = mips_machine_restart;
+	_machine_halt = mips_machine_halt;
+#if defined(CONFIG_MIPS_ATLAS)
+	_machine_power_off = atlas_machine_power_off;
+#endif
+#if defined(CONFIG_MIPS_MALTA) || defined(CONFIG_MIPS_SEAD)
+	_machine_power_off = mips_machine_halt;
+#endif
+}
diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c
new file mode 100644
index 0000000..fe7fc17
--- /dev/null
+++ b/arch/mips/mips-boards/generic/time.c
@@ -0,0 +1,167 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Setting up the clock on the MIPS boards.
+ */
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/mc146818rtc.h>
+
+#include <asm/mipsregs.h>
+#include <asm/ptrace.h>
+#include <asm/div64.h>
+#include <asm/cpu.h>
+#include <asm/time.h>
+#include <asm/mc146818-time.h>
+
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+
+unsigned long cpu_khz;
+
+#if defined(CONFIG_MIPS_SEAD)
+#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ5)
+#else
+#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
+#endif
+
+#if defined(CONFIG_MIPS_ATLAS)
+static char display_string[] = "        LINUX ON ATLAS       ";
+#endif
+#if defined(CONFIG_MIPS_MALTA)
+static char display_string[] = "        LINUX ON MALTA       ";
+#endif
+#if defined(CONFIG_MIPS_SEAD)
+static char display_string[] = "        LINUX ON SEAD       ";
+#endif
+static unsigned int display_count = 0;
+#define MAX_DISPLAY_COUNT (sizeof(display_string) - 8)
+
+#define MIPS_CPU_TIMER_IRQ (NR_IRQS-1)
+
+static unsigned int timer_tick_count=0;
+
+void mips_timer_interrupt(struct pt_regs *regs)
+{
+	if ((timer_tick_count++ % HZ) == 0) {
+		mips_display_message(&display_string[display_count++]);
+		if (display_count == MAX_DISPLAY_COUNT)
+		        display_count = 0;
+
+	}
+
+	ll_timer_interrupt(MIPS_CPU_TIMER_IRQ, regs);
+}
+
+/*
+ * Estimate CPU frequency.  Sets mips_counter_frequency as a side-effect
+ */
+static unsigned int __init estimate_cpu_frequency(void)
+{
+	unsigned int prid = read_c0_prid() & 0xffff00;
+	unsigned int count;
+
+#ifdef CONFIG_MIPS_SEAD
+	/*
+	 * The SEAD board doesn't have a real time clock, so we can't
+	 * really calculate the timer frequency
+	 * For now we hardwire the SEAD board frequency to 12MHz.
+	 */
+	
+	if ((prid == (PRID_COMP_MIPS | PRID_IMP_20KC)) ||
+	    (prid == (PRID_COMP_MIPS | PRID_IMP_25KF)))
+		count = 12000000;
+	else
+		count = 6000000;
+#endif
+#if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_MALTA)
+	unsigned int flags;
+
+	local_irq_save(flags);
+
+	/* Start counter exactly on falling edge of update flag */
+	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
+	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
+
+	/* Start r4k counter. */
+	write_c0_count(0);
+
+	/* Read counter exactly on falling edge of update flag */
+	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
+	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
+
+	count = read_c0_count();
+
+	/* restore interrupts */
+	local_irq_restore(flags);
+#endif
+
+	mips_hpt_frequency = count;
+	if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) &&
+	    (prid != (PRID_COMP_MIPS | PRID_IMP_25KF)))
+		count *= 2;
+
+	count += 5000;    /* round */
+	count -= count%10000;
+
+	return count;
+}
+
+unsigned long __init mips_rtc_get_time(void)
+{
+	return mc146818_get_cmos_time();
+}
+
+void __init mips_time_init(void)
+{
+	unsigned int est_freq, flags;
+
+	local_irq_save(flags);
+
+#if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_MALTA)
+        /* Set Data mode - binary. */
+        CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
+#endif
+
+	est_freq = estimate_cpu_frequency ();
+
+	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
+	       (est_freq%1000000)*100/1000000);
+
+        cpu_khz = est_freq / 1000;
+
+	local_irq_restore(flags);
+}
+
+void __init mips_timer_setup(struct irqaction *irq)
+{
+	/* we are using the cpu counter for timer interrupts */
+	irq->handler = no_action;     /* we use our own handler */
+	setup_irq(MIPS_CPU_TIMER_IRQ, irq);
+
+        /* to generate the first timer interrupt */
+	write_c0_compare (read_c0_count() + mips_hpt_frequency/HZ);
+	set_c0_status(ALLINTS);
+}
diff --git a/arch/mips/mips-boards/malta/Makefile b/arch/mips/mips-boards/malta/Makefile
new file mode 100644
index 0000000..fd4c143
--- /dev/null
+++ b/arch/mips/mips-boards/malta/Makefile
@@ -0,0 +1,22 @@
+#
+# Carsten Langgaard, carstenl@mips.com
+# Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+#
+# This program is free software; you can distribute it and/or modify it
+# under the terms of the GNU General Public License (Version 2) as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Makefile for the MIPS Malta specific kernel interface routines
+# under Linux.
+#
+
+obj-y := malta_int.o malta_setup.o
diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c
new file mode 100644
index 0000000..dd2db35
--- /dev/null
+++ b/arch/mips/mips-boards/malta/malta_int.c
@@ -0,0 +1,187 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc.
+ * Copyright (C) 2001 Ralf Baechle
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Routines for generic manipulation of the interrupts found on the MIPS
+ * Malta board.
+ * The interrupt controller is located in the South Bridge a PIIX4 device
+ * with two internal 82C95 interrupt controllers.
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/random.h>
+
+#include <asm/i8259.h>
+#include <asm/io.h>
+#include <asm/mips-boards/malta.h>
+#include <asm/mips-boards/maltaint.h>
+#include <asm/mips-boards/piix4.h>
+#include <asm/gt64120.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/msc01_pci.h>
+
+extern asmlinkage void mipsIRQ(void);
+
+static DEFINE_SPINLOCK(mips_irq_lock);
+
+static inline int mips_pcibios_iack(void)
+{
+	int irq;
+        u32 dummy;
+
+	/*
+	 * Determine highest priority pending interrupt by performing
+	 * a PCI Interrupt Acknowledge cycle.
+	 */
+	switch(mips_revision_corid) {
+	case MIPS_REVISION_CORID_CORE_MSC:
+	case MIPS_REVISION_CORID_CORE_FPGA2:
+	case MIPS_REVISION_CORID_CORE_EMUL_MSC:
+	        MSC_READ(MSC01_PCI_IACK, irq);
+		irq &= 0xff;
+		break;
+	case MIPS_REVISION_CORID_QED_RM5261:
+	case MIPS_REVISION_CORID_CORE_LV:
+	case MIPS_REVISION_CORID_CORE_FPGA:
+	case MIPS_REVISION_CORID_CORE_FPGAR2:
+		irq = GT_READ(GT_PCI0_IACK_OFS);
+		irq &= 0xff;
+		break;
+	case MIPS_REVISION_CORID_BONITO64:
+	case MIPS_REVISION_CORID_CORE_20K:
+	case MIPS_REVISION_CORID_CORE_EMUL_BON:
+		/* The following will generate a PCI IACK cycle on the
+		 * Bonito controller. It's a little bit kludgy, but it
+		 * was the easiest way to implement it in hardware at
+		 * the given time.
+		 */
+		BONITO_PCIMAP_CFG = 0x20000;
+
+		/* Flush Bonito register block */
+		dummy = BONITO_PCIMAP_CFG;
+		iob();    /* sync */
+
+		irq = *(volatile u32 *)(_pcictrl_bonito_pcicfg);
+		iob();    /* sync */
+		irq &= 0xff;
+		BONITO_PCIMAP_CFG = 0;
+		break;
+	default:
+	        printk("Unknown Core card, don't know the system controller.\n");
+		return -1;
+	}
+	return irq;
+}
+
+static inline int get_int(int *irq)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&mips_irq_lock, flags);
+
+	*irq = mips_pcibios_iack();
+
+	/*
+	 * IRQ7 is used to detect spurious interrupts.
+	 * The interrupt acknowledge cycle returns IRQ7, if no
+	 * interrupts is requested.
+	 * We can differentiate between this situation and a
+	 * "Normal" IRQ7 by reading the ISR.
+	 */
+	if (*irq == 7)
+	{
+		outb(PIIX4_OCW3_SEL | PIIX4_OCW3_ISR,
+		     PIIX4_ICTLR1_OCW3);
+		if (!(inb(PIIX4_ICTLR1_OCW3) & (1 << 7))) {
+			spin_unlock_irqrestore(&mips_irq_lock, flags);
+			printk("We got a spurious interrupt from PIIX4.\n");
+			atomic_inc(&irq_err_count);
+			return -1;    /* Spurious interrupt. */
+		}
+	}
+
+	spin_unlock_irqrestore(&mips_irq_lock, flags);
+
+	return 0;
+}
+
+void malta_hw0_irqdispatch(struct pt_regs *regs)
+{
+	int irq;
+
+	if (get_int(&irq))
+	        return;  /* interrupt has already been cleared */
+
+	do_IRQ(irq, regs);
+}
+
+void corehi_irqdispatch(struct pt_regs *regs)
+{
+        unsigned int data,datahi;
+
+	/* Mask out corehi interrupt. */
+	clear_c0_status(IE_IRQ3);
+
+        printk("CoreHI interrupt, shouldn't happen, so we die here!!!\n");
+        printk("epc   : %08lx\nStatus: %08lx\nCause : %08lx\nbadVaddr : %08lx\n"
+, regs->cp0_epc, regs->cp0_status, regs->cp0_cause, regs->cp0_badvaddr);
+        switch(mips_revision_corid) {
+        case MIPS_REVISION_CORID_CORE_MSC:
+        case MIPS_REVISION_CORID_CORE_FPGA2:
+	case MIPS_REVISION_CORID_CORE_EMUL_MSC:
+                break;
+        case MIPS_REVISION_CORID_QED_RM5261:
+        case MIPS_REVISION_CORID_CORE_LV:
+        case MIPS_REVISION_CORID_CORE_FPGA:
+        case MIPS_REVISION_CORID_CORE_FPGAR2:
+                data = GT_READ(GT_INTRCAUSE_OFS);
+                printk("GT_INTRCAUSE = %08x\n", data);
+                data = GT_READ(GT_CPUERR_ADDRLO_OFS);
+                datahi = GT_READ(GT_CPUERR_ADDRHI_OFS);
+                printk("GT_CPUERR_ADDR = %02x%08x\n", datahi, data);
+                break;
+        case MIPS_REVISION_CORID_BONITO64:
+        case MIPS_REVISION_CORID_CORE_20K:
+        case MIPS_REVISION_CORID_CORE_EMUL_BON:
+                data = BONITO_INTISR;
+                printk("BONITO_INTISR = %08x\n", data);
+                data = BONITO_INTEN;
+                printk("BONITO_INTEN = %08x\n", data);
+                data = BONITO_INTPOL;
+                printk("BONITO_INTPOL = %08x\n", data);
+                data = BONITO_INTEDGE;
+                printk("BONITO_INTEDGE = %08x\n", data);
+                data = BONITO_INTSTEER;
+                printk("BONITO_INTSTEER = %08x\n", data);
+                data = BONITO_PCICMD;
+                printk("BONITO_PCICMD = %08x\n", data);
+                break;
+        }
+
+        /* We die here*/
+        die("CoreHi interrupt", regs);
+}
+
+void __init arch_init_irq(void)
+{
+	set_except_vector(0, mipsIRQ);
+	init_i8259_irqs();
+}
diff --git a/arch/mips/mips-boards/malta/malta_setup.c b/arch/mips/mips-boards/malta/malta_setup.c
new file mode 100644
index 0000000..3377e66
--- /dev/null
+++ b/arch/mips/mips-boards/malta/malta_setup.c
@@ -0,0 +1,231 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/tty.h>
+
+#ifdef CONFIG_MTD
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#endif
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+#include <asm/mips-boards/malta.h>
+#include <asm/mips-boards/maltaint.h>
+#include <asm/dma.h>
+#include <asm/time.h>
+#include <asm/traps.h>
+#ifdef CONFIG_VT
+#include <linux/console.h>
+#endif
+
+extern void mips_reboot_setup(void);
+extern void mips_time_init(void);
+extern void mips_timer_setup(struct irqaction *irq);
+extern unsigned long mips_rtc_get_time(void);
+
+#ifdef CONFIG_KGDB
+extern void kgdb_config(void);
+#endif
+
+struct resource standard_io_resources[] = {
+	{ "dma1", 0x00, 0x1f, IORESOURCE_BUSY },
+	{ "timer", 0x40, 0x5f, IORESOURCE_BUSY },
+	{ "keyboard", 0x60, 0x6f, IORESOURCE_BUSY },
+	{ "dma page reg", 0x80, 0x8f, IORESOURCE_BUSY },
+	{ "dma2", 0xc0, 0xdf, IORESOURCE_BUSY },
+};
+
+#ifdef CONFIG_MTD
+static struct mtd_partition malta_mtd_partitions[] = {
+	{
+		.name =		"YAMON",
+		.offset =	0x0,
+		.size =		0x100000,
+		.mask_flags =	MTD_WRITEABLE
+	},
+	{
+		.name =		"User FS",
+		.offset = 	0x100000,
+		.size =		0x2e0000
+	},
+	{
+		.name =		"Board Config",
+		.offset =	0x3e0000,
+		.size =		0x020000,
+		.mask_flags =	MTD_WRITEABLE
+	}
+};
+
+#define number_partitions	(sizeof(malta_mtd_partitions)/sizeof(struct mtd_partition))
+#endif
+
+const char *get_system_type(void)
+{
+	return "MIPS Malta";
+}
+
+#ifdef CONFIG_BLK_DEV_FD
+void __init fd_activate(void)
+{
+	/*
+	 * Activate Floppy Controller in the SMSC FDC37M817 Super I/O
+	 * Controller.
+	 * Done by YAMON 2.00 onwards
+	 */
+	/* Entering config state. */
+	SMSC_WRITE(SMSC_CONFIG_ENTER, SMSC_CONFIG_REG);
+
+	/* Activate floppy controller. */
+	SMSC_WRITE(SMSC_CONFIG_DEVNUM, SMSC_CONFIG_REG);
+	SMSC_WRITE(SMSC_CONFIG_DEVNUM_FLOPPY, SMSC_DATA_REG);
+	SMSC_WRITE(SMSC_CONFIG_ACTIVATE, SMSC_CONFIG_REG);
+	SMSC_WRITE(SMSC_CONFIG_ACTIVATE_ENABLE, SMSC_DATA_REG);
+
+	/* Exit config state. */
+	SMSC_WRITE(SMSC_CONFIG_EXIT, SMSC_CONFIG_REG);
+}
+#endif
+
+static int __init malta_setup(void)
+{
+	unsigned int i;
+
+	/* Request I/O space for devices used on the Malta board. */
+	for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++)
+		request_resource(&ioport_resource, standard_io_resources+i);
+
+	/*
+	 * Enable DMA channel 4 (cascade channel) in the PIIX4 south bridge.
+	 */
+	enable_dma(4);
+
+#ifdef CONFIG_KGDB
+	kgdb_config ();
+#endif
+
+	if ((mips_revision_corid == MIPS_REVISION_CORID_BONITO64) ||
+	    (mips_revision_corid == MIPS_REVISION_CORID_CORE_20K) ||
+	    (mips_revision_corid == MIPS_REVISION_CORID_CORE_EMUL_BON)) {
+		char *argptr;
+
+		argptr = prom_getcmdline();
+		if (strstr(argptr, "debug")) {
+			BONITO_BONGENCFG |= BONITO_BONGENCFG_DEBUGMODE;
+			printk ("Enabled Bonito debug mode\n");
+		}
+		else
+			BONITO_BONGENCFG &= ~BONITO_BONGENCFG_DEBUGMODE;
+
+#ifdef CONFIG_DMA_COHERENT
+		if (BONITO_PCICACHECTRL & BONITO_PCICACHECTRL_CPUCOH_PRES) {
+			BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_CPUCOH_EN;
+			printk("Enabled Bonito CPU coherency\n");
+
+			argptr = prom_getcmdline();
+			if (strstr(argptr, "iobcuncached")) {
+				BONITO_PCICACHECTRL &= ~BONITO_PCICACHECTRL_IOBCCOH_EN;
+				BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG & 
+					~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |
+					  BONITO_PCIMEMBASECFG_MEMBASE1_CACHED);
+				printk("Disabled Bonito IOBC coherency\n");
+			}
+			else {
+				BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_IOBCCOH_EN;
+				BONITO_PCIMEMBASECFG |= 
+					(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED | 
+					 BONITO_PCIMEMBASECFG_MEMBASE1_CACHED);
+				printk("Disabled Bonito IOBC coherency\n");
+			}
+		}
+		else
+			panic("Hardware DMA cache coherency not supported");
+
+#endif
+	}
+#ifdef CONFIG_DMA_COHERENT
+	else {
+		panic("Hardware DMA cache coherency not supported");
+	}
+#endif
+
+#ifdef CONFIG_BLK_DEV_IDE
+	/* Check PCI clock */
+	{
+		int jmpr = (*((volatile unsigned int *)ioremap(MALTA_JMPRS_REG, sizeof(unsigned int))) >> 2) & 0x07;
+		static const int pciclocks[] __initdata = {
+			33, 20, 25, 30, 12, 16, 37, 10
+		};
+		int pciclock = pciclocks[jmpr];
+		char *argptr = prom_getcmdline();
+
+		if (pciclock != 33 && !strstr (argptr, "idebus=")) {
+			printk("WARNING: PCI clock is %dMHz, setting idebus\n", pciclock);
+			argptr += strlen(argptr);
+			sprintf (argptr, " idebus=%d", pciclock);
+			if (pciclock < 20 || pciclock > 66)
+				printk ("WARNING: IDE timing calculations will be incorrect\n");
+		}
+	}
+#endif
+#ifdef CONFIG_BLK_DEV_FD
+	fd_activate ();
+#endif
+#ifdef CONFIG_VT
+#if defined(CONFIG_VGA_CONSOLE)
+	screen_info = (struct screen_info) {
+		0, 25,			/* orig-x, orig-y */
+		0,			/* unused */
+		0,			/* orig-video-page */
+		0,			/* orig-video-mode */
+		80,			/* orig-video-cols */
+		0,0,0,			/* ega_ax, ega_bx, ega_cx */
+		25,			/* orig-video-lines */
+		VIDEO_TYPE_VGAC,	/* orig-video-isVGA */
+		16			/* orig-video-points */
+	};
+#endif
+#endif
+
+#ifdef CONFIG_MTD
+	/*
+	 * Support for MTD on Malta. Use the generic physmap driver
+	 */
+	physmap_configure(0x1e000000, 0x400000, 4, NULL);
+	physmap_set_partitions(malta_mtd_partitions, number_partitions);
+#endif
+
+	mips_reboot_setup();
+
+	board_time_init = mips_time_init;
+	board_timer_setup = mips_timer_setup;
+	rtc_get_time = mips_rtc_get_time;
+
+	return 0;
+}
+
+early_initcall(malta_setup);
diff --git a/arch/mips/mips-boards/sead/Makefile b/arch/mips/mips-boards/sead/Makefile
new file mode 100644
index 0000000..224bb84
--- /dev/null
+++ b/arch/mips/mips-boards/sead/Makefile
@@ -0,0 +1,26 @@
+#
+# Carsten Langgaard, carstenl@mips.com
+# Copyright (C) 2002 MIPS Technologies, Inc.  All rights reserved.
+#
+# ########################################################################
+#
+# This program is free software; you can distribute it and/or modify it
+# under the terms of the GNU General Public License (Version 2) as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# #######################################################################
+#
+# Makefile for the MIPS SEAD specific kernel interface routines
+# under Linux.
+#
+
+obj-y		:= sead_int.o sead_setup.o
diff --git a/arch/mips/mips-boards/sead/sead_int.c b/arch/mips/mips-boards/sead/sead_int.c
new file mode 100644
index 0000000..e510965
--- /dev/null
+++ b/arch/mips/mips-boards/sead/sead_int.c
@@ -0,0 +1,51 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2002 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2003 Ralf Baechle (ralf@linux-mips.org)
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Routines for generic manipulation of the interrupts found on the MIPS
+ * Sead board.
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+
+#include <asm/mips-boards/seadint.h>
+
+extern asmlinkage void mipsIRQ(void);
+
+asmlinkage void sead_hw0_irqdispatch(struct pt_regs *regs)
+{
+	do_IRQ(SEADINT_UART0, regs);
+}
+
+asmlinkage void sead_hw1_irqdispatch(struct pt_regs *regs)
+{
+	do_IRQ(SEADINT_UART1, regs);
+}
+
+void __init arch_init_irq(void)
+{
+        /*
+         * Mask out all interrupt
+	 */
+	clear_c0_status(0x0000ff00);
+
+	/* Now safe to set the exception vector. */
+	set_except_vector(0, mipsIRQ);
+
+	mips_cpu_irq_init(0);
+}
diff --git a/arch/mips/mips-boards/sead/sead_setup.c b/arch/mips/mips-boards/sead/sead_setup.c
new file mode 100644
index 0000000..29892b8
--- /dev/null
+++ b/arch/mips/mips-boards/sead/sead_setup.c
@@ -0,0 +1,84 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2002 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * SEAD specific setup.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+#include <asm/mips-boards/sead.h>
+#include <asm/mips-boards/seadint.h>
+#include <asm/time.h>
+
+extern void mips_reboot_setup(void);
+extern void mips_time_init(void);
+extern void mips_timer_setup(struct irqaction *irq);
+
+static void __init serial_init(void);
+
+const char *get_system_type(void)
+{
+	return "MIPS SEAD";
+}
+
+static void __init sead_setup(void)
+{
+	ioport_resource.end = 0x7fffffff;
+
+	serial_init ();
+
+	board_time_init = mips_time_init;
+	board_timer_setup = mips_timer_setup;
+
+	mips_reboot_setup();
+}
+
+early_initcall(sead_setup);
+
+static void __init serial_init(void)
+{
+#ifdef CONFIG_SERIAL_8250
+	struct uart_port s;
+
+	memset(&s, 0, sizeof(s));
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+	s.iobase = SEAD_UART0_REGS_BASE;
+#else
+	s.iobase = SEAD_UART0_REGS_BASE+3;
+#endif
+	s.irq = SEADINT_UART0;
+	s.uartclk = SEAD_BASE_BAUD * 16;
+	s.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
+	s.iotype = 0;
+	s.regshift = 3;
+
+	if (early_serial_setup(&s) != 0) {
+		printk(KERN_ERR "Serial setup failed!\n");
+	}
+#endif
+}
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
new file mode 100644
index 0000000..f61e038
--- /dev/null
+++ b/arch/mips/mm/Makefile
@@ -0,0 +1,44 @@
+#
+# Makefile for the Linux/MIPS-specific parts of the memory manager.
+#
+
+obj-y				+= cache.o extable.o fault.o init.o pgtable.o \
+				   tlbex.o tlbex-fault.o
+
+obj-$(CONFIG_MIPS32)		+= ioremap.o pgtable-32.o
+obj-$(CONFIG_MIPS64)		+= pgtable-64.o
+obj-$(CONFIG_HIGHMEM)		+= highmem.o
+
+obj-$(CONFIG_CPU_MIPS32)	+= c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
+obj-$(CONFIG_CPU_MIPS64)	+= c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
+obj-$(CONFIG_CPU_NEVADA)	+= c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
+obj-$(CONFIG_CPU_R10000)	+= c-r4k.o cex-gen.o pg-r4k.o tlb-andes.o
+obj-$(CONFIG_CPU_R3000)		+= c-r3k.o tlb-r3k.o pg-r4k.o
+obj-$(CONFIG_CPU_R4300)		+= c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
+obj-$(CONFIG_CPU_R4X00)		+= c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
+obj-$(CONFIG_CPU_R5000)		+= c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
+obj-$(CONFIG_CPU_R5432)		+= c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
+obj-$(CONFIG_CPU_R8000)		+= c-r4k.o cex-gen.o pg-r4k.o tlb-r8k.o
+obj-$(CONFIG_CPU_RM7000)	+= c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
+obj-$(CONFIG_CPU_RM9000)	+= c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
+obj-$(CONFIG_CPU_SB1)		+= c-sb1.o cerr-sb1.o cex-sb1.o pg-sb1.o \
+				   tlb-sb1.o
+obj-$(CONFIG_CPU_TX39XX)	+= c-tx39.o pg-r4k.o tlb-r3k.o
+obj-$(CONFIG_CPU_TX49XX)	+= c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
+obj-$(CONFIG_CPU_VR41XX)	+= c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
+
+obj-$(CONFIG_IP22_CPU_SCACHE)	+= sc-ip22.o
+obj-$(CONFIG_R5000_CPU_SCACHE)  += sc-r5k.o
+obj-$(CONFIG_RM7000_CPU_SCACHE)	+= sc-rm7k.o
+
+#
+# Choose one DMA coherency model
+#
+ifndef CONFIG_OWN_DMA
+obj-$(CONFIG_DMA_COHERENT)	+= dma-coherent.o
+obj-$(CONFIG_DMA_NONCOHERENT)	+= dma-noncoherent.o
+endif
+obj-$(CONFIG_DMA_IP27)		+= dma-ip27.o
+obj-$(CONFIG_DMA_IP32)		+= dma-ip32.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c
new file mode 100644
index 0000000..c659f99
--- /dev/null
+++ b/arch/mips/mm/c-r3k.c
@@ -0,0 +1,349 @@
+/*
+ * r2300.c: R2000 and R3000 specific mmu/cache code.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ *
+ * with a lot of changes to make this thing work for R3000s
+ * Tx39XX R4k style caches added. HK
+ * Copyright (C) 1998, 1999, 2000 Harald Koerfgen
+ * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
+ * Copyright (C) 2001, 2004  Maciej W. Rozycki
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/mmu_context.h>
+#include <asm/system.h>
+#include <asm/isadep.h>
+#include <asm/io.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+
+static unsigned long icache_size, dcache_size;		/* Size in bytes */
+static unsigned long icache_lsize, dcache_lsize;	/* Size in bytes */
+
+#undef DEBUG_CACHE
+
+unsigned long __init r3k_cache_size(unsigned long ca_flags)
+{
+	unsigned long flags, status, dummy, size;
+	volatile unsigned long *p;
+
+	p = (volatile unsigned long *) KSEG0;
+
+	flags = read_c0_status();
+
+	/* isolate cache space */
+	write_c0_status((ca_flags|flags)&~ST0_IEC);
+
+	*p = 0xa5a55a5a;
+	dummy = *p;
+	status = read_c0_status();
+
+	if (dummy != 0xa5a55a5a || (status & ST0_CM)) {
+		size = 0;
+	} else {
+		for (size = 128; size <= 0x40000; size <<= 1)
+			*(p + size) = 0;
+		*p = -1;
+		for (size = 128;
+		     (size <= 0x40000) && (*(p + size) == 0);
+		     size <<= 1)
+			;
+		if (size > 0x40000)
+			size = 0;
+	}
+
+	write_c0_status(flags);
+
+	return size * sizeof(*p);
+}
+
+unsigned long __init r3k_cache_lsize(unsigned long ca_flags)
+{
+	unsigned long flags, status, lsize, i;
+	volatile unsigned long *p;
+
+	p = (volatile unsigned long *) KSEG0;
+
+	flags = read_c0_status();
+
+	/* isolate cache space */
+	write_c0_status((ca_flags|flags)&~ST0_IEC);
+
+	for (i = 0; i < 128; i++)
+		*(p + i) = 0;
+	*(volatile unsigned char *)p = 0;
+	for (lsize = 1; lsize < 128; lsize <<= 1) {
+		*(p + lsize);
+		status = read_c0_status();
+		if (!(status & ST0_CM))
+			break;
+	}
+	for (i = 0; i < 128; i += lsize)
+		*(volatile unsigned char *)(p + i) = 0;
+
+	write_c0_status(flags);
+
+	return lsize * sizeof(*p);
+}
+
+static void __init r3k_probe_cache(void)
+{
+	dcache_size = r3k_cache_size(ST0_ISC);
+	if (dcache_size)
+		dcache_lsize = r3k_cache_lsize(ST0_ISC);
+
+	icache_size = r3k_cache_size(ST0_ISC|ST0_SWC);
+	if (icache_size)
+		icache_lsize = r3k_cache_lsize(ST0_ISC|ST0_SWC);
+}
+
+static void r3k_flush_icache_range(unsigned long start, unsigned long end)
+{
+	unsigned long size, i, flags;
+	volatile unsigned char *p;
+
+	size = end - start;
+	if (size > icache_size || KSEGX(start) != KSEG0) {
+		start = KSEG0;
+		size = icache_size;
+	}
+	p = (char *)start;
+
+	flags = read_c0_status();
+
+	/* isolate cache space */
+	write_c0_status((ST0_ISC|ST0_SWC|flags)&~ST0_IEC);
+
+	for (i = 0; i < size; i += 0x080) {
+		asm ( 	"sb\t$0, 0x000(%0)\n\t"
+			"sb\t$0, 0x004(%0)\n\t"
+			"sb\t$0, 0x008(%0)\n\t"
+			"sb\t$0, 0x00c(%0)\n\t"
+			"sb\t$0, 0x010(%0)\n\t"
+			"sb\t$0, 0x014(%0)\n\t"
+			"sb\t$0, 0x018(%0)\n\t"
+			"sb\t$0, 0x01c(%0)\n\t"
+		 	"sb\t$0, 0x020(%0)\n\t"
+			"sb\t$0, 0x024(%0)\n\t"
+			"sb\t$0, 0x028(%0)\n\t"
+			"sb\t$0, 0x02c(%0)\n\t"
+			"sb\t$0, 0x030(%0)\n\t"
+			"sb\t$0, 0x034(%0)\n\t"
+			"sb\t$0, 0x038(%0)\n\t"
+			"sb\t$0, 0x03c(%0)\n\t"
+			"sb\t$0, 0x040(%0)\n\t"
+			"sb\t$0, 0x044(%0)\n\t"
+			"sb\t$0, 0x048(%0)\n\t"
+			"sb\t$0, 0x04c(%0)\n\t"
+			"sb\t$0, 0x050(%0)\n\t"
+			"sb\t$0, 0x054(%0)\n\t"
+			"sb\t$0, 0x058(%0)\n\t"
+			"sb\t$0, 0x05c(%0)\n\t"
+		 	"sb\t$0, 0x060(%0)\n\t"
+			"sb\t$0, 0x064(%0)\n\t"
+			"sb\t$0, 0x068(%0)\n\t"
+			"sb\t$0, 0x06c(%0)\n\t"
+			"sb\t$0, 0x070(%0)\n\t"
+			"sb\t$0, 0x074(%0)\n\t"
+			"sb\t$0, 0x078(%0)\n\t"
+			"sb\t$0, 0x07c(%0)\n\t"
+			: : "r" (p) );
+		p += 0x080;
+	}
+
+	write_c0_status(flags);
+}
+
+static void r3k_flush_dcache_range(unsigned long start, unsigned long end)
+{
+	unsigned long size, i, flags;
+	volatile unsigned char *p;
+
+	size = end - start;
+	if (size > dcache_size || KSEGX(start) != KSEG0) {
+		start = KSEG0;
+		size = dcache_size;
+	}
+	p = (char *)start;
+
+	flags = read_c0_status();
+
+	/* isolate cache space */
+	write_c0_status((ST0_ISC|flags)&~ST0_IEC);
+
+	for (i = 0; i < size; i += 0x080) {
+		asm ( 	"sb\t$0, 0x000(%0)\n\t"
+			"sb\t$0, 0x004(%0)\n\t"
+			"sb\t$0, 0x008(%0)\n\t"
+			"sb\t$0, 0x00c(%0)\n\t"
+		 	"sb\t$0, 0x010(%0)\n\t"
+			"sb\t$0, 0x014(%0)\n\t"
+			"sb\t$0, 0x018(%0)\n\t"
+			"sb\t$0, 0x01c(%0)\n\t"
+		 	"sb\t$0, 0x020(%0)\n\t"
+			"sb\t$0, 0x024(%0)\n\t"
+			"sb\t$0, 0x028(%0)\n\t"
+			"sb\t$0, 0x02c(%0)\n\t"
+		 	"sb\t$0, 0x030(%0)\n\t"
+			"sb\t$0, 0x034(%0)\n\t"
+			"sb\t$0, 0x038(%0)\n\t"
+			"sb\t$0, 0x03c(%0)\n\t"
+		 	"sb\t$0, 0x040(%0)\n\t"
+			"sb\t$0, 0x044(%0)\n\t"
+			"sb\t$0, 0x048(%0)\n\t"
+			"sb\t$0, 0x04c(%0)\n\t"
+		 	"sb\t$0, 0x050(%0)\n\t"
+			"sb\t$0, 0x054(%0)\n\t"
+			"sb\t$0, 0x058(%0)\n\t"
+			"sb\t$0, 0x05c(%0)\n\t"
+		 	"sb\t$0, 0x060(%0)\n\t"
+			"sb\t$0, 0x064(%0)\n\t"
+			"sb\t$0, 0x068(%0)\n\t"
+			"sb\t$0, 0x06c(%0)\n\t"
+		 	"sb\t$0, 0x070(%0)\n\t"
+			"sb\t$0, 0x074(%0)\n\t"
+			"sb\t$0, 0x078(%0)\n\t"
+			"sb\t$0, 0x07c(%0)\n\t"
+			: : "r" (p) );
+		p += 0x080;
+	}
+
+	write_c0_status(flags);
+}
+
+static inline unsigned long get_phys_page (unsigned long addr,
+					   struct mm_struct *mm)
+{
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *pte;
+	unsigned long physpage;
+
+	pgd = pgd_offset(mm, addr);
+	pmd = pmd_offset(pgd, addr);
+	pte = pte_offset(pmd, addr);
+
+	if ((physpage = pte_val(*pte)) & _PAGE_VALID)
+		return KSEG0ADDR(physpage & PAGE_MASK);
+
+	return 0;
+}
+
+static inline void r3k_flush_cache_all(void)
+{
+}
+
+static inline void r3k___flush_cache_all(void)
+{
+	r3k_flush_dcache_range(KSEG0, KSEG0 + dcache_size);
+	r3k_flush_icache_range(KSEG0, KSEG0 + icache_size);
+}
+
+static void r3k_flush_cache_mm(struct mm_struct *mm)
+{
+}
+
+static void r3k_flush_cache_range(struct vm_area_struct *vma,
+	unsigned long start, unsigned long end)
+{
+}
+
+static void r3k_flush_cache_page(struct vm_area_struct *vma, unsigned long page, unsigned long pfn)
+{
+}
+
+static void r3k_flush_data_cache_page(unsigned long addr)
+{
+}
+
+static void r3k_flush_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long physpage;
+
+	if (cpu_context(smp_processor_id(), mm) == 0)
+		return;
+
+	if (!(vma->vm_flags & VM_EXEC))
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", cpu_context(smp_processor_id(), mm), page);
+#endif
+
+	physpage = (unsigned long) page_address(page);
+	if (physpage)
+		r3k_flush_icache_range(physpage, physpage + PAGE_SIZE);
+}
+
+static void r3k_flush_cache_sigtramp(unsigned long addr)
+{
+	unsigned long flags;
+
+#ifdef DEBUG_CACHE
+	printk("csigtramp[%08lx]", addr);
+#endif
+
+	flags = read_c0_status();
+
+	write_c0_status(flags&~ST0_IEC);
+
+	/* Fill the TLB to avoid an exception with caches isolated. */
+	asm ( 	"lw\t$0, 0x000(%0)\n\t"
+		"lw\t$0, 0x004(%0)\n\t"
+		: : "r" (addr) );
+
+	write_c0_status((ST0_ISC|ST0_SWC|flags)&~ST0_IEC);
+
+	asm ( 	"sb\t$0, 0x000(%0)\n\t"
+		"sb\t$0, 0x004(%0)\n\t"
+		: : "r" (addr) );
+
+	write_c0_status(flags);
+}
+
+static void r3k_dma_cache_wback_inv(unsigned long start, unsigned long size)
+{
+	/* Catch bad driver code */
+	BUG_ON(size == 0);
+
+	iob();
+	r3k_flush_dcache_range(start, start + size);
+}
+
+void __init ld_mmu_r23000(void)
+{
+	extern void build_clear_page(void);
+	extern void build_copy_page(void);
+
+	r3k_probe_cache();
+
+	flush_cache_all = r3k_flush_cache_all;
+	__flush_cache_all = r3k___flush_cache_all;
+	flush_cache_mm = r3k_flush_cache_mm;
+	flush_cache_range = r3k_flush_cache_range;
+	flush_cache_page = r3k_flush_cache_page;
+	flush_icache_page = r3k_flush_icache_page;
+	flush_icache_range = r3k_flush_icache_range;
+
+	flush_cache_sigtramp = r3k_flush_cache_sigtramp;
+	flush_data_cache_page = r3k_flush_data_cache_page;
+
+	_dma_cache_wback_inv = r3k_dma_cache_wback_inv;
+	_dma_cache_wback = r3k_dma_cache_wback_inv;
+	_dma_cache_inv = r3k_dma_cache_wback_inv;
+
+	printk("Primary instruction cache %ldkB, linesize %ld bytes.\n",
+		icache_size >> 10, icache_lsize);
+	printk("Primary data cache %ldkB, linesize %ld bytes.\n",
+		dcache_size >> 10, dcache_lsize);
+
+	build_clear_page();
+	build_copy_page();
+}
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
new file mode 100644
index 0000000..a03ebb2
--- /dev/null
+++ b/arch/mips/mm/c-r4k.c
@@ -0,0 +1,1260 @@
+/*
+ * 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) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/bitops.h>
+
+#include <asm/bcache.h>
+#include <asm/bootinfo.h>
+#include <asm/cacheops.h>
+#include <asm/cpu.h>
+#include <asm/cpu-features.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/r4kcache.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+#include <asm/war.h>
+
+static unsigned long icache_size, dcache_size, scache_size;
+
+/*
+ * Dummy cache handling routines for machines without boardcaches
+ */
+static void no_sc_noop(void) {}
+
+static struct bcache_ops no_sc_ops = {
+	.bc_enable = (void *)no_sc_noop,
+	.bc_disable = (void *)no_sc_noop,
+	.bc_wback_inv = (void *)no_sc_noop,
+	.bc_inv = (void *)no_sc_noop
+};
+
+struct bcache_ops *bcops = &no_sc_ops;
+
+#define cpu_is_r4600_v1_x()	((read_c0_prid() & 0xfffffff0) == 0x2010)
+#define cpu_is_r4600_v2_x()	((read_c0_prid() & 0xfffffff0) == 0x2020)
+
+#define R4600_HIT_CACHEOP_WAR_IMPL					\
+do {									\
+	if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())		\
+		*(volatile unsigned long *)CKSEG1;			\
+	if (R4600_V1_HIT_CACHEOP_WAR)					\
+		__asm__ __volatile__("nop;nop;nop;nop");		\
+} while (0)
+
+static void (*r4k_blast_dcache_page)(unsigned long addr);
+
+static inline void r4k_blast_dcache_page_dc32(unsigned long addr)
+{
+	R4600_HIT_CACHEOP_WAR_IMPL;
+	blast_dcache32_page(addr);
+}
+
+static inline void r4k_blast_dcache_page_setup(void)
+{
+	unsigned long  dc_lsize = cpu_dcache_line_size();
+
+	if (dc_lsize == 16)
+		r4k_blast_dcache_page = blast_dcache16_page;
+	else if (dc_lsize == 32)
+		r4k_blast_dcache_page = r4k_blast_dcache_page_dc32;
+}
+
+static void (* r4k_blast_dcache_page_indexed)(unsigned long addr);
+
+static inline void r4k_blast_dcache_page_indexed_setup(void)
+{
+	unsigned long dc_lsize = cpu_dcache_line_size();
+
+	if (dc_lsize == 16)
+		r4k_blast_dcache_page_indexed = blast_dcache16_page_indexed;
+	else if (dc_lsize == 32)
+		r4k_blast_dcache_page_indexed = blast_dcache32_page_indexed;
+}
+
+static void (* r4k_blast_dcache)(void);
+
+static inline void r4k_blast_dcache_setup(void)
+{
+	unsigned long dc_lsize = cpu_dcache_line_size();
+
+	if (dc_lsize == 16)
+		r4k_blast_dcache = blast_dcache16;
+	else if (dc_lsize == 32)
+		r4k_blast_dcache = blast_dcache32;
+}
+
+/* force code alignment (used for TX49XX_ICACHE_INDEX_INV_WAR) */
+#define JUMP_TO_ALIGN(order) \
+	__asm__ __volatile__( \
+		"b\t1f\n\t" \
+		".align\t" #order "\n\t" \
+		"1:\n\t" \
+		)
+#define CACHE32_UNROLL32_ALIGN	JUMP_TO_ALIGN(10) /* 32 * 32 = 1024 */
+#define CACHE32_UNROLL32_ALIGN2	JUMP_TO_ALIGN(11)
+
+static inline void blast_r4600_v1_icache32(void)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	blast_icache32();
+	local_irq_restore(flags);
+}
+
+static inline void tx49_blast_icache32(void)
+{
+	unsigned long start = INDEX_BASE;
+	unsigned long end = start + current_cpu_data.icache.waysize;
+	unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
+	unsigned long ws_end = current_cpu_data.icache.ways <<
+	                       current_cpu_data.icache.waybit;
+	unsigned long ws, addr;
+
+	CACHE32_UNROLL32_ALIGN2;
+	/* I'm in even chunk.  blast odd chunks */
+	for (ws = 0; ws < ws_end; ws += ws_inc) 
+		for (addr = start + 0x400; addr < end; addr += 0x400 * 2) 
+			cache32_unroll32(addr|ws,Index_Invalidate_I);
+	CACHE32_UNROLL32_ALIGN;
+	/* I'm in odd chunk.  blast even chunks */
+	for (ws = 0; ws < ws_end; ws += ws_inc) 
+		for (addr = start; addr < end; addr += 0x400 * 2) 
+			cache32_unroll32(addr|ws,Index_Invalidate_I);
+}
+
+static inline void blast_icache32_r4600_v1_page_indexed(unsigned long page)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	blast_icache32_page_indexed(page);
+	local_irq_restore(flags);
+}
+
+static inline void tx49_blast_icache32_page_indexed(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = start + PAGE_SIZE;
+	unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
+	unsigned long ws_end = current_cpu_data.icache.ways <<
+	                       current_cpu_data.icache.waybit;
+	unsigned long ws, addr;
+
+	CACHE32_UNROLL32_ALIGN2;
+	/* I'm in even chunk.  blast odd chunks */
+	for (ws = 0; ws < ws_end; ws += ws_inc) 
+		for (addr = start + 0x400; addr < end; addr += 0x400 * 2) 
+			cache32_unroll32(addr|ws,Index_Invalidate_I);
+	CACHE32_UNROLL32_ALIGN;
+	/* I'm in odd chunk.  blast even chunks */
+	for (ws = 0; ws < ws_end; ws += ws_inc) 
+		for (addr = start; addr < end; addr += 0x400 * 2) 
+			cache32_unroll32(addr|ws,Index_Invalidate_I);
+}
+
+static void (* r4k_blast_icache_page)(unsigned long addr);
+
+static inline void r4k_blast_icache_page_setup(void)
+{
+	unsigned long ic_lsize = cpu_icache_line_size();
+
+	if (ic_lsize == 16)
+		r4k_blast_icache_page = blast_icache16_page;
+	else if (ic_lsize == 32)
+		r4k_blast_icache_page = blast_icache32_page;
+	else if (ic_lsize == 64)
+		r4k_blast_icache_page = blast_icache64_page;
+}
+
+
+static void (* r4k_blast_icache_page_indexed)(unsigned long addr);
+
+static inline void r4k_blast_icache_page_indexed_setup(void)
+{
+	unsigned long ic_lsize = cpu_icache_line_size();
+
+	if (ic_lsize == 16)
+		r4k_blast_icache_page_indexed = blast_icache16_page_indexed;
+	else if (ic_lsize == 32) {
+		if (TX49XX_ICACHE_INDEX_INV_WAR)
+			r4k_blast_icache_page_indexed =
+				tx49_blast_icache32_page_indexed;
+		else if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x())
+			r4k_blast_icache_page_indexed =
+				blast_icache32_r4600_v1_page_indexed;
+		else
+			r4k_blast_icache_page_indexed =
+				blast_icache32_page_indexed;
+	} else if (ic_lsize == 64)
+		r4k_blast_icache_page_indexed = blast_icache64_page_indexed;
+}
+
+static void (* r4k_blast_icache)(void);
+
+static inline void r4k_blast_icache_setup(void)
+{
+	unsigned long ic_lsize = cpu_icache_line_size();
+
+	if (ic_lsize == 16)
+		r4k_blast_icache = blast_icache16;
+	else if (ic_lsize == 32) {
+		if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x())
+			r4k_blast_icache = blast_r4600_v1_icache32;
+		else if (TX49XX_ICACHE_INDEX_INV_WAR)
+			r4k_blast_icache = tx49_blast_icache32;
+		else
+			r4k_blast_icache = blast_icache32;
+	} else if (ic_lsize == 64)
+		r4k_blast_icache = blast_icache64;
+}
+
+static void (* r4k_blast_scache_page)(unsigned long addr);
+
+static inline void r4k_blast_scache_page_setup(void)
+{
+	unsigned long sc_lsize = cpu_scache_line_size();
+
+	if (sc_lsize == 16)
+		r4k_blast_scache_page = blast_scache16_page;
+	else if (sc_lsize == 32)
+		r4k_blast_scache_page = blast_scache32_page;
+	else if (sc_lsize == 64)
+		r4k_blast_scache_page = blast_scache64_page;
+	else if (sc_lsize == 128)
+		r4k_blast_scache_page = blast_scache128_page;
+}
+
+static void (* r4k_blast_scache_page_indexed)(unsigned long addr);
+
+static inline void r4k_blast_scache_page_indexed_setup(void)
+{
+	unsigned long sc_lsize = cpu_scache_line_size();
+
+	if (sc_lsize == 16)
+		r4k_blast_scache_page_indexed = blast_scache16_page_indexed;
+	else if (sc_lsize == 32)
+		r4k_blast_scache_page_indexed = blast_scache32_page_indexed;
+	else if (sc_lsize == 64)
+		r4k_blast_scache_page_indexed = blast_scache64_page_indexed;
+	else if (sc_lsize == 128)
+		r4k_blast_scache_page_indexed = blast_scache128_page_indexed;
+}
+
+static void (* r4k_blast_scache)(void);
+
+static inline void r4k_blast_scache_setup(void)
+{
+	unsigned long sc_lsize = cpu_scache_line_size();
+
+	if (sc_lsize == 16)
+		r4k_blast_scache = blast_scache16;
+	else if (sc_lsize == 32)
+		r4k_blast_scache = blast_scache32;
+	else if (sc_lsize == 64)
+		r4k_blast_scache = blast_scache64;
+	else if (sc_lsize == 128)
+		r4k_blast_scache = blast_scache128;
+}
+
+/*
+ * This is former mm's flush_cache_all() which really should be
+ * flush_cache_vunmap these days ...
+ */
+static inline void local_r4k_flush_cache_all(void * args)
+{
+	r4k_blast_dcache();
+	r4k_blast_icache();
+}
+
+static void r4k_flush_cache_all(void)
+{
+	if (!cpu_has_dc_aliases)
+		return;
+
+	on_each_cpu(local_r4k_flush_cache_all, NULL, 1, 1);
+}
+
+static inline void local_r4k___flush_cache_all(void * args)
+{
+	r4k_blast_dcache();
+	r4k_blast_icache();
+
+	switch (current_cpu_data.cputype) {
+	case CPU_R4000SC:
+	case CPU_R4000MC:
+	case CPU_R4400SC:
+	case CPU_R4400MC:
+	case CPU_R10000:
+	case CPU_R12000:
+		r4k_blast_scache();
+	}
+}
+
+static void r4k___flush_cache_all(void)
+{
+	on_each_cpu(local_r4k___flush_cache_all, NULL, 1, 1);
+}
+
+static inline void local_r4k_flush_cache_range(void * args)
+{
+	struct vm_area_struct *vma = args;
+	int exec;
+
+	if (!(cpu_context(smp_processor_id(), vma->vm_mm)))
+		return;
+
+	exec = vma->vm_flags & VM_EXEC;
+	if (cpu_has_dc_aliases || exec)
+		r4k_blast_dcache();
+	if (exec)
+		r4k_blast_icache();
+}
+
+static void r4k_flush_cache_range(struct vm_area_struct *vma,
+	unsigned long start, unsigned long end)
+{
+	on_each_cpu(local_r4k_flush_cache_range, vma, 1, 1);
+}
+
+static inline void local_r4k_flush_cache_mm(void * args)
+{
+	struct mm_struct *mm = args;
+
+	if (!cpu_context(smp_processor_id(), mm))
+		return;
+
+	r4k_blast_dcache();
+	r4k_blast_icache();
+
+	/*
+	 * Kludge alert.  For obscure reasons R4000SC and R4400SC go nuts if we
+	 * only flush the primary caches but R10000 and R12000 behave sane ...
+	 */
+	if (current_cpu_data.cputype == CPU_R4000SC ||
+	    current_cpu_data.cputype == CPU_R4000MC ||
+	    current_cpu_data.cputype == CPU_R4400SC ||
+	    current_cpu_data.cputype == CPU_R4400MC)
+		r4k_blast_scache();
+}
+
+static void r4k_flush_cache_mm(struct mm_struct *mm)
+{
+	if (!cpu_has_dc_aliases)
+		return;
+
+	on_each_cpu(local_r4k_flush_cache_mm, mm, 1, 1);
+}
+
+struct flush_cache_page_args {
+	struct vm_area_struct *vma;
+	unsigned long page;
+};
+
+static inline void local_r4k_flush_cache_page(void *args)
+{
+	struct flush_cache_page_args *fcp_args = args;
+	struct vm_area_struct *vma = fcp_args->vma;
+	unsigned long page = fcp_args->page;
+	int exec = vma->vm_flags & VM_EXEC;
+	struct mm_struct *mm = vma->vm_mm;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if (!(pte_val(*ptep) & _PAGE_PRESENT))
+		return;
+
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
+		if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
+			r4k_blast_dcache_page(page);
+			if (exec && !cpu_icache_snoops_remote_store)
+				r4k_blast_scache_page(page);
+		}
+		if (exec)
+			r4k_blast_icache_page(page);
+
+		return;
+	}
+
+	/*
+	 * Do indexed flush, too much work to get the (possible) TLB refills
+	 * to work correctly.
+	 */
+	page = INDEX_BASE + (page & (dcache_size - 1));
+	if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
+		r4k_blast_dcache_page_indexed(page);
+		if (exec && !cpu_icache_snoops_remote_store)
+			r4k_blast_scache_page_indexed(page);
+	}
+	if (exec) {
+		if (cpu_has_vtag_icache) {
+			int cpu = smp_processor_id();
+
+			if (cpu_context(cpu, vma->vm_mm) != 0)
+				drop_mmu_context(vma->vm_mm, cpu);
+		} else
+			r4k_blast_icache_page_indexed(page);
+	}
+}
+
+static void r4k_flush_cache_page(struct vm_area_struct *vma, unsigned long page, unsigned long pfn)
+{
+	struct flush_cache_page_args args;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if (cpu_context(smp_processor_id(), vma->vm_mm) == 0)
+		return;
+
+	args.vma = vma;
+	args.page = page;
+
+	on_each_cpu(local_r4k_flush_cache_page, &args, 1, 1);
+}
+
+static inline void local_r4k_flush_data_cache_page(void * addr)
+{
+	r4k_blast_dcache_page((unsigned long) addr);
+}
+
+static void r4k_flush_data_cache_page(unsigned long addr)
+{
+	on_each_cpu(local_r4k_flush_data_cache_page, (void *) addr, 1, 1);
+}
+
+struct flush_icache_range_args {
+	unsigned long start;
+	unsigned long end;
+};
+
+static inline void local_r4k_flush_icache_range(void *args)
+{
+	struct flush_icache_range_args *fir_args = args;
+	unsigned long dc_lsize = current_cpu_data.dcache.linesz;
+	unsigned long ic_lsize = current_cpu_data.icache.linesz;
+	unsigned long sc_lsize = current_cpu_data.scache.linesz;
+	unsigned long start = fir_args->start;
+	unsigned long end = fir_args->end;
+	unsigned long addr, aend;
+
+	if (!cpu_has_ic_fills_f_dc) {
+		if (end - start > dcache_size) {
+			r4k_blast_dcache();
+		} else {
+			addr = start & ~(dc_lsize - 1);
+			aend = (end - 1) & ~(dc_lsize - 1);
+
+			while (1) {
+				/* Hit_Writeback_Inv_D */
+				protected_writeback_dcache_line(addr);
+				if (addr == aend)
+					break;
+				addr += dc_lsize;
+			}
+		}
+
+		if (!cpu_icache_snoops_remote_store) {
+			if (end - start > scache_size) {
+				r4k_blast_scache();
+			} else {
+				addr = start & ~(sc_lsize - 1);
+				aend = (end - 1) & ~(sc_lsize - 1);
+
+				while (1) {
+					/* Hit_Writeback_Inv_D */
+					protected_writeback_scache_line(addr);
+					if (addr == aend)
+						break;
+					addr += sc_lsize;
+				}
+			}
+		}
+	}
+
+	if (end - start > icache_size)
+		r4k_blast_icache();
+	else {
+		addr = start & ~(ic_lsize - 1);
+		aend = (end - 1) & ~(ic_lsize - 1);
+		while (1) {
+			/* Hit_Invalidate_I */
+			protected_flush_icache_line(addr);
+			if (addr == aend)
+				break;
+			addr += ic_lsize;
+		}
+	}
+}
+
+static void r4k_flush_icache_range(unsigned long start, unsigned long end)
+{
+	struct flush_icache_range_args args;
+
+	args.start = start;
+	args.end = end;
+
+	on_each_cpu(local_r4k_flush_icache_range, &args, 1, 1);
+}
+
+/*
+ * Ok, this seriously sucks.  We use them to flush a user page but don't
+ * know the virtual address, so we have to blast away the whole icache
+ * which is significantly more expensive than the real thing.  Otoh we at
+ * least know the kernel address of the page so we can flush it
+ * selectivly.
+ */
+
+struct flush_icache_page_args {
+	struct vm_area_struct *vma;
+	struct page *page;
+};
+
+static inline void local_r4k_flush_icache_page(void *args)
+{
+	struct flush_icache_page_args *fip_args = args;
+	struct vm_area_struct *vma = fip_args->vma;
+	struct page *page = fip_args->page;
+
+	/*
+	 * Tricky ...  Because we don't know the virtual address we've got the
+	 * choice of either invalidating the entire primary and secondary
+	 * caches or invalidating the secondary caches also.  With the subset
+	 * enforcment on R4000SC, R4400SC, R10000 and R12000 invalidating the
+	 * secondary cache will result in any entries in the primary caches
+	 * also getting invalidated which hopefully is a bit more economical.
+	 */
+	if (cpu_has_subset_pcaches) {
+		unsigned long addr = (unsigned long) page_address(page);
+
+		r4k_blast_scache_page(addr);
+		ClearPageDcacheDirty(page);
+
+		return;
+	}
+
+	if (!cpu_has_ic_fills_f_dc) {
+		unsigned long addr = (unsigned long) page_address(page);
+		r4k_blast_dcache_page(addr);
+		if (!cpu_icache_snoops_remote_store)
+			r4k_blast_scache_page(addr);
+		ClearPageDcacheDirty(page);
+	}
+
+	/*
+	 * We're not sure of the virtual address(es) involved here, so
+	 * we have to flush the entire I-cache.
+	 */
+	if (cpu_has_vtag_icache) {
+		int cpu = smp_processor_id();
+
+		if (cpu_context(cpu, vma->vm_mm) != 0)
+			drop_mmu_context(vma->vm_mm, cpu);
+	} else
+		r4k_blast_icache();
+}
+
+static void r4k_flush_icache_page(struct vm_area_struct *vma,
+	struct page *page)
+{
+	struct flush_icache_page_args args;
+
+	/*
+	 * If there's no context yet, or the page isn't executable, no I-cache
+	 * flush is needed.
+	 */
+	if (!(vma->vm_flags & VM_EXEC))
+		return;
+
+	args.vma = vma;
+	args.page = page;
+
+	on_each_cpu(local_r4k_flush_icache_page, &args, 1, 1);
+}
+
+
+#ifdef CONFIG_DMA_NONCOHERENT
+
+static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	/* Catch bad driver code */
+	BUG_ON(size == 0);
+
+	if (cpu_has_subset_pcaches) {
+		unsigned long sc_lsize = current_cpu_data.scache.linesz;
+
+		if (size >= scache_size) {
+			r4k_blast_scache();
+			return;
+		}
+
+		a = addr & ~(sc_lsize - 1);
+		end = (addr + size - 1) & ~(sc_lsize - 1);
+		while (1) {
+			flush_scache_line(a);	/* Hit_Writeback_Inv_SD */
+			if (a == end)
+				break;
+			a += sc_lsize;
+		}
+		return;
+	}
+
+	/*
+	 * Either no secondary cache or the available caches don't have the
+	 * subset property so we have to flush the primary caches
+	 * explicitly
+	 */
+	if (size >= dcache_size) {
+		r4k_blast_dcache();
+	} else {
+		unsigned long dc_lsize = current_cpu_data.dcache.linesz;
+
+		R4600_HIT_CACHEOP_WAR_IMPL;
+		a = addr & ~(dc_lsize - 1);
+		end = (addr + size - 1) & ~(dc_lsize - 1);
+		while (1) {
+			flush_dcache_line(a);	/* Hit_Writeback_Inv_D */
+			if (a == end)
+				break;
+			a += dc_lsize;
+		}
+	}
+
+	bc_wback_inv(addr, size);
+}
+
+static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	/* Catch bad driver code */
+	BUG_ON(size == 0);
+
+	if (cpu_has_subset_pcaches) {
+		unsigned long sc_lsize = current_cpu_data.scache.linesz;
+
+		if (size >= scache_size) {
+			r4k_blast_scache();
+			return;
+		}
+
+		a = addr & ~(sc_lsize - 1);
+		end = (addr + size - 1) & ~(sc_lsize - 1);
+		while (1) {
+			flush_scache_line(a);	/* Hit_Writeback_Inv_SD */
+			if (a == end)
+				break;
+			a += sc_lsize;
+		}
+		return;
+	}
+
+	if (size >= dcache_size) {
+		r4k_blast_dcache();
+	} else {
+		unsigned long dc_lsize = current_cpu_data.dcache.linesz;
+
+		R4600_HIT_CACHEOP_WAR_IMPL;
+		a = addr & ~(dc_lsize - 1);
+		end = (addr + size - 1) & ~(dc_lsize - 1);
+		while (1) {
+			flush_dcache_line(a);	/* Hit_Writeback_Inv_D */
+			if (a == end)
+				break;
+			a += dc_lsize;
+		}
+	}
+
+	bc_inv(addr, size);
+}
+#endif /* CONFIG_DMA_NONCOHERENT */
+
+/*
+ * While we're protected against bad userland addresses we don't care
+ * very much about what happens in that case.  Usually a segmentation
+ * fault will dump the process later on anyway ...
+ */
+static void local_r4k_flush_cache_sigtramp(void * arg)
+{
+	unsigned long ic_lsize = current_cpu_data.icache.linesz;
+	unsigned long dc_lsize = current_cpu_data.dcache.linesz;
+	unsigned long sc_lsize = current_cpu_data.scache.linesz;
+	unsigned long addr = (unsigned long) arg;
+
+	R4600_HIT_CACHEOP_WAR_IMPL;
+	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
+	if (!cpu_icache_snoops_remote_store)
+		protected_writeback_scache_line(addr & ~(sc_lsize - 1));
+	protected_flush_icache_line(addr & ~(ic_lsize - 1));
+	if (MIPS4K_ICACHE_REFILL_WAR) {
+		__asm__ __volatile__ (
+			".set push\n\t"
+			".set noat\n\t"
+			".set mips3\n\t"
+#ifdef CONFIG_MIPS32
+			"la	$at,1f\n\t"
+#endif
+#ifdef CONFIG_MIPS64
+			"dla	$at,1f\n\t"
+#endif
+			"cache	%0,($at)\n\t"
+			"nop; nop; nop\n"
+			"1:\n\t"
+			".set pop"
+			:
+			: "i" (Hit_Invalidate_I));
+	}
+	if (MIPS_CACHE_SYNC_WAR)
+		__asm__ __volatile__ ("sync");
+}
+
+static void r4k_flush_cache_sigtramp(unsigned long addr)
+{
+	on_each_cpu(local_r4k_flush_cache_sigtramp, (void *) addr, 1, 1);
+}
+
+static void r4k_flush_icache_all(void)
+{
+	if (cpu_has_vtag_icache)
+		r4k_blast_icache();
+}
+
+static inline void rm7k_erratum31(void)
+{
+	const unsigned long ic_lsize = 32;
+	unsigned long addr;
+
+	/* RM7000 erratum #31. The icache is screwed at startup. */
+	write_c0_taglo(0);
+	write_c0_taghi(0);
+
+	for (addr = INDEX_BASE; addr <= INDEX_BASE + 4096; addr += ic_lsize) {
+		__asm__ __volatile__ (
+			".set noreorder\n\t"
+			".set mips3\n\t"
+			"cache\t%1, 0(%0)\n\t"
+			"cache\t%1, 0x1000(%0)\n\t"
+			"cache\t%1, 0x2000(%0)\n\t"
+			"cache\t%1, 0x3000(%0)\n\t"
+			"cache\t%2, 0(%0)\n\t"
+			"cache\t%2, 0x1000(%0)\n\t"
+			"cache\t%2, 0x2000(%0)\n\t"
+			"cache\t%2, 0x3000(%0)\n\t"
+			"cache\t%1, 0(%0)\n\t"
+			"cache\t%1, 0x1000(%0)\n\t"
+			"cache\t%1, 0x2000(%0)\n\t"
+			"cache\t%1, 0x3000(%0)\n\t"
+			".set\tmips0\n\t"
+			".set\treorder\n\t"
+			:
+			: "r" (addr), "i" (Index_Store_Tag_I), "i" (Fill));
+	}
+}
+
+static char *way_string[] __initdata = { NULL, "direct mapped", "2-way",
+	"3-way", "4-way", "5-way", "6-way", "7-way", "8-way"
+};
+
+static void __init probe_pcache(void)
+{
+	struct cpuinfo_mips *c = &current_cpu_data;
+	unsigned int config = read_c0_config();
+	unsigned int prid = read_c0_prid();
+	unsigned long config1;
+	unsigned int lsize;
+
+	switch (c->cputype) {
+	case CPU_R4600:			/* QED style two way caches? */
+	case CPU_R4700:
+	case CPU_R5000:
+	case CPU_NEVADA:
+		icache_size = 1 << (12 + ((config & CONF_IC) >> 9));
+		c->icache.linesz = 16 << ((config & CONF_IB) >> 5);
+		c->icache.ways = 2;
+		c->icache.waybit = ffs(icache_size/2) - 1;
+
+		dcache_size = 1 << (12 + ((config & CONF_DC) >> 6));
+		c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
+		c->dcache.ways = 2;
+		c->dcache.waybit= ffs(dcache_size/2) - 1;
+
+		c->options |= MIPS_CPU_CACHE_CDEX_P;
+		break;
+
+	case CPU_R5432:
+	case CPU_R5500:
+		icache_size = 1 << (12 + ((config & CONF_IC) >> 9));
+		c->icache.linesz = 16 << ((config & CONF_IB) >> 5);
+		c->icache.ways = 2;
+		c->icache.waybit= 0;
+
+		dcache_size = 1 << (12 + ((config & CONF_DC) >> 6));
+		c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
+		c->dcache.ways = 2;
+		c->dcache.waybit = 0;
+
+		c->options |= MIPS_CPU_CACHE_CDEX_P;
+		break;
+
+	case CPU_TX49XX:
+		icache_size = 1 << (12 + ((config & CONF_IC) >> 9));
+		c->icache.linesz = 16 << ((config & CONF_IB) >> 5);
+		c->icache.ways = 4;
+		c->icache.waybit= 0;
+
+		dcache_size = 1 << (12 + ((config & CONF_DC) >> 6));
+		c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
+		c->dcache.ways = 4;
+		c->dcache.waybit = 0;
+
+		c->options |= MIPS_CPU_CACHE_CDEX_P;
+		break;
+
+	case CPU_R4000PC:
+	case CPU_R4000SC:
+	case CPU_R4000MC:
+	case CPU_R4400PC:
+	case CPU_R4400SC:
+	case CPU_R4400MC:
+	case CPU_R4300:
+		icache_size = 1 << (12 + ((config & CONF_IC) >> 9));
+		c->icache.linesz = 16 << ((config & CONF_IB) >> 5);
+		c->icache.ways = 1;
+		c->icache.waybit = 0; 	/* doesn't matter */
+
+		dcache_size = 1 << (12 + ((config & CONF_DC) >> 6));
+		c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
+		c->dcache.ways = 1;
+		c->dcache.waybit = 0;	/* does not matter */
+
+		c->options |= MIPS_CPU_CACHE_CDEX_P;
+		break;
+
+	case CPU_R10000:
+	case CPU_R12000:
+		icache_size = 1 << (12 + ((config & R10K_CONF_IC) >> 29));
+		c->icache.linesz = 64;
+		c->icache.ways = 2;
+		c->icache.waybit = 0;
+
+		dcache_size = 1 << (12 + ((config & R10K_CONF_DC) >> 26));
+		c->dcache.linesz = 32;
+		c->dcache.ways = 2;
+		c->dcache.waybit = 0;
+
+		c->options |= MIPS_CPU_PREFETCH;
+		break;
+
+	case CPU_VR4133:
+		write_c0_config(config & ~CONF_EB);
+	case CPU_VR4131:
+		/* Workaround for cache instruction bug of VR4131 */
+		if (c->processor_id == 0x0c80U || c->processor_id == 0x0c81U ||
+		    c->processor_id == 0x0c82U) {
+			config &= ~0x00000030U;
+			config |= 0x00410000U;
+			write_c0_config(config);
+		}
+		icache_size = 1 << (10 + ((config & CONF_IC) >> 9));
+		c->icache.linesz = 16 << ((config & CONF_IB) >> 5);
+		c->icache.ways = 2;
+		c->icache.waybit = ffs(icache_size/2) - 1;
+
+		dcache_size = 1 << (10 + ((config & CONF_DC) >> 6));
+		c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
+		c->dcache.ways = 2;
+		c->dcache.waybit = ffs(dcache_size/2) - 1;
+
+		c->options |= MIPS_CPU_CACHE_CDEX_P;
+		break;
+
+	case CPU_VR41XX:
+	case CPU_VR4111:
+	case CPU_VR4121:
+	case CPU_VR4122:
+	case CPU_VR4181:
+	case CPU_VR4181A:
+		icache_size = 1 << (10 + ((config & CONF_IC) >> 9));
+		c->icache.linesz = 16 << ((config & CONF_IB) >> 5);
+		c->icache.ways = 1;
+		c->icache.waybit = 0; 	/* doesn't matter */
+
+		dcache_size = 1 << (10 + ((config & CONF_DC) >> 6));
+		c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
+		c->dcache.ways = 1;
+		c->dcache.waybit = 0;	/* does not matter */
+
+		c->options |= MIPS_CPU_CACHE_CDEX_P;
+		break;
+
+	case CPU_RM7000:
+		rm7k_erratum31();
+
+	case CPU_RM9000:
+		icache_size = 1 << (12 + ((config & CONF_IC) >> 9));
+		c->icache.linesz = 16 << ((config & CONF_IB) >> 5);
+		c->icache.ways = 4;
+		c->icache.waybit = ffs(icache_size / c->icache.ways) - 1;
+
+		dcache_size = 1 << (12 + ((config & CONF_DC) >> 6));
+		c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
+		c->dcache.ways = 4;
+		c->dcache.waybit = ffs(dcache_size / c->dcache.ways) - 1;
+
+#if !defined(CONFIG_SMP) || !defined(RM9000_CDEX_SMP_WAR)
+		c->options |= MIPS_CPU_CACHE_CDEX_P;
+#endif
+		c->options |= MIPS_CPU_PREFETCH;
+		break;
+
+	default:
+		if (!(config & MIPS_CONF_M))
+			panic("Don't know how to probe P-caches on this cpu.");
+
+		/*
+		 * So we seem to be a MIPS32 or MIPS64 CPU
+		 * So let's probe the I-cache ...
+		 */
+		config1 = read_c0_config1();
+
+		if ((lsize = ((config1 >> 19) & 7)))
+			c->icache.linesz = 2 << lsize;
+		else
+			c->icache.linesz = lsize;
+		c->icache.sets = 64 << ((config1 >> 22) & 7);
+		c->icache.ways = 1 + ((config1 >> 16) & 7);
+
+		icache_size = c->icache.sets *
+		              c->icache.ways *
+		              c->icache.linesz;
+		c->icache.waybit = ffs(icache_size/c->icache.ways) - 1;
+
+		if (config & 0x8)		/* VI bit */
+			c->icache.flags |= MIPS_CACHE_VTAG;
+
+		/*
+		 * Now probe the MIPS32 / MIPS64 data cache.
+		 */
+		c->dcache.flags = 0;
+
+		if ((lsize = ((config1 >> 10) & 7)))
+			c->dcache.linesz = 2 << lsize;
+		else
+			c->dcache.linesz= lsize;
+		c->dcache.sets = 64 << ((config1 >> 13) & 7);
+		c->dcache.ways = 1 + ((config1 >> 7) & 7);
+
+		dcache_size = c->dcache.sets *
+		              c->dcache.ways *
+		              c->dcache.linesz;
+		c->dcache.waybit = ffs(dcache_size/c->dcache.ways) - 1;
+
+		c->options |= MIPS_CPU_PREFETCH;
+		break;
+	}
+
+	/*
+	 * Processor configuration sanity check for the R4000SC erratum
+	 * #5.  With page sizes larger than 32kB there is no possibility
+	 * to get a VCE exception anymore so we don't care about this
+	 * misconfiguration.  The case is rather theoretical anyway;
+	 * presumably no vendor is shipping his hardware in the "bad"
+	 * configuration.
+	 */
+	if ((prid & 0xff00) == PRID_IMP_R4000 && (prid & 0xff) < 0x40 &&
+	    !(config & CONF_SC) && c->icache.linesz != 16 &&
+	    PAGE_SIZE <= 0x8000)
+		panic("Improper R4000SC processor configuration detected");
+
+	/* compute a couple of other cache variables */
+	c->icache.waysize = icache_size / c->icache.ways;
+	c->dcache.waysize = dcache_size / c->dcache.ways;
+
+	c->icache.sets = icache_size / (c->icache.linesz * c->icache.ways);
+	c->dcache.sets = dcache_size / (c->dcache.linesz * c->dcache.ways);
+
+	/*
+	 * R10000 and R12000 P-caches are odd in a positive way.  They're 32kB
+	 * 2-way virtually indexed so normally would suffer from aliases.  So
+	 * normally they'd suffer from aliases but magic in the hardware deals
+	 * with that for us so we don't need to take care ourselves.
+	 */
+	if (c->cputype != CPU_R10000 && c->cputype != CPU_R12000)
+		if (c->dcache.waysize > PAGE_SIZE)
+		        c->dcache.flags |= MIPS_CACHE_ALIASES;
+
+	switch (c->cputype) {
+	case CPU_20KC:
+		/*
+		 * Some older 20Kc chips doesn't have the 'VI' bit in
+		 * the config register.
+		 */
+		c->icache.flags |= MIPS_CACHE_VTAG;
+		break;
+
+	case CPU_AU1500:
+		c->icache.flags |= MIPS_CACHE_IC_F_DC;
+		break;
+	}
+
+	printk("Primary instruction cache %ldkB, %s, %s, linesize %d bytes.\n",
+	       icache_size >> 10,
+	       cpu_has_vtag_icache ? "virtually tagged" : "physically tagged",
+	       way_string[c->icache.ways], c->icache.linesz);
+
+	printk("Primary data cache %ldkB, %s, linesize %d bytes.\n",
+	       dcache_size >> 10, way_string[c->dcache.ways], c->dcache.linesz);
+}
+
+/*
+ * If you even _breathe_ on this function, look at the gcc output and make sure
+ * it does not pop things on and off the stack for the cache sizing loop that
+ * executes in KSEG1 space or else you will crash and burn badly.  You have
+ * been warned.
+ */
+static int __init probe_scache(void)
+{
+	extern unsigned long stext;
+	unsigned long flags, addr, begin, end, pow2;
+	unsigned int config = read_c0_config();
+	struct cpuinfo_mips *c = &current_cpu_data;
+	int tmp;
+
+	if (config & CONF_SC)
+		return 0;
+
+	begin = (unsigned long) &stext;
+	begin &= ~((4 * 1024 * 1024) - 1);
+	end = begin + (4 * 1024 * 1024);
+
+	/*
+	 * This is such a bitch, you'd think they would make it easy to do
+	 * this.  Away you daemons of stupidity!
+	 */
+	local_irq_save(flags);
+
+	/* Fill each size-multiple cache line with a valid tag. */
+	pow2 = (64 * 1024);
+	for (addr = begin; addr < end; addr = (begin + pow2)) {
+		unsigned long *p = (unsigned long *) addr;
+		__asm__ __volatile__("nop" : : "r" (*p)); /* whee... */
+		pow2 <<= 1;
+	}
+
+	/* Load first line with zero (therefore invalid) tag. */
+	write_c0_taglo(0);
+	write_c0_taghi(0);
+	__asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */
+	cache_op(Index_Store_Tag_I, begin);
+	cache_op(Index_Store_Tag_D, begin);
+	cache_op(Index_Store_Tag_SD, begin);
+
+	/* Now search for the wrap around point. */
+	pow2 = (128 * 1024);
+	tmp = 0;
+	for (addr = begin + (128 * 1024); addr < end; addr = begin + pow2) {
+		cache_op(Index_Load_Tag_SD, addr);
+		__asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */
+		if (!read_c0_taglo())
+			break;
+		pow2 <<= 1;
+	}
+	local_irq_restore(flags);
+	addr -= begin;
+
+	scache_size = addr;
+	c->scache.linesz = 16 << ((config & R4K_CONF_SB) >> 22);
+	c->scache.ways = 1;
+	c->dcache.waybit = 0;		/* does not matter */
+
+	return 1;
+}
+
+typedef int (*probe_func_t)(unsigned long);
+extern int r5k_sc_init(void);
+extern int rm7k_sc_init(void);
+
+static void __init setup_scache(void)
+{
+	struct cpuinfo_mips *c = &current_cpu_data;
+	unsigned int config = read_c0_config();
+	probe_func_t probe_scache_kseg1;
+	int sc_present = 0;
+
+	/*
+	 * Do the probing thing on R4000SC and R4400SC processors.  Other
+	 * processors don't have a S-cache that would be relevant to the
+	 * Linux memory managment.
+	 */
+	switch (c->cputype) {
+	case CPU_R4000SC:
+	case CPU_R4000MC:
+	case CPU_R4400SC:
+	case CPU_R4400MC:
+		probe_scache_kseg1 = (probe_func_t) (CKSEG1ADDR(&probe_scache));
+		sc_present = probe_scache_kseg1(config);
+		if (sc_present)
+			c->options |= MIPS_CPU_CACHE_CDEX_S;
+		break;
+
+	case CPU_R10000:
+	case CPU_R12000:
+		scache_size = 0x80000 << ((config & R10K_CONF_SS) >> 16);
+		c->scache.linesz = 64 << ((config >> 13) & 1);
+		c->scache.ways = 2;
+		c->scache.waybit= 0;
+		sc_present = 1;
+		break;
+
+	case CPU_R5000:
+	case CPU_NEVADA:
+#ifdef CONFIG_R5000_CPU_SCACHE
+		r5k_sc_init();
+#endif
+                return;
+
+	case CPU_RM7000:
+	case CPU_RM9000:
+#ifdef CONFIG_RM7000_CPU_SCACHE
+		rm7k_sc_init();
+#endif
+		return;
+
+	default:
+		sc_present = 0;
+	}
+
+	if (!sc_present)
+		return;
+
+	if ((c->isa_level == MIPS_CPU_ISA_M32 ||
+	     c->isa_level == MIPS_CPU_ISA_M64) &&
+	    !(c->scache.flags & MIPS_CACHE_NOT_PRESENT))
+		panic("Dunno how to handle MIPS32 / MIPS64 second level cache");
+
+	/* compute a couple of other cache variables */
+	c->scache.waysize = scache_size / c->scache.ways;
+
+	c->scache.sets = scache_size / (c->scache.linesz * c->scache.ways);
+
+	printk("Unified secondary cache %ldkB %s, linesize %d bytes.\n",
+	       scache_size >> 10, way_string[c->scache.ways], c->scache.linesz);
+
+	c->options |= MIPS_CPU_SUBSET_CACHES;
+}
+
+static inline void coherency_setup(void)
+{
+	change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT);
+
+	/*
+	 * c0_status.cu=0 specifies that updates by the sc instruction use
+	 * the coherency mode specified by the TLB; 1 means cachable
+	 * coherent update on write will be used.  Not all processors have
+	 * this bit and; some wire it to zero, others like Toshiba had the
+	 * silly idea of putting something else there ...
+	 */
+	switch (current_cpu_data.cputype) {
+	case CPU_R4000PC:
+	case CPU_R4000SC:
+	case CPU_R4000MC:
+	case CPU_R4400PC:
+	case CPU_R4400SC:
+	case CPU_R4400MC:
+		clear_c0_config(CONF_CU);
+		break;
+	}
+}
+
+void __init ld_mmu_r4xx0(void)
+{
+	extern void build_clear_page(void);
+	extern void build_copy_page(void);
+	extern char except_vec2_generic;
+	struct cpuinfo_mips *c = &current_cpu_data;
+
+	/* Default cache error handler for R4000 and R5000 family */
+	memcpy((void *)(CAC_BASE   + 0x100), &except_vec2_generic, 0x80);
+	memcpy((void *)(UNCAC_BASE + 0x100), &except_vec2_generic, 0x80);
+
+	probe_pcache();
+	setup_scache();
+
+	if (c->dcache.sets * c->dcache.ways > PAGE_SIZE)
+		c->dcache.flags |= MIPS_CACHE_ALIASES;
+
+	r4k_blast_dcache_page_setup();
+	r4k_blast_dcache_page_indexed_setup();
+	r4k_blast_dcache_setup();
+	r4k_blast_icache_page_setup();
+	r4k_blast_icache_page_indexed_setup();
+	r4k_blast_icache_setup();
+	r4k_blast_scache_page_setup();
+	r4k_blast_scache_page_indexed_setup();
+	r4k_blast_scache_setup();
+
+	/*
+	 * Some MIPS32 and MIPS64 processors have physically indexed caches.
+	 * This code supports virtually indexed processors and will be
+	 * unnecessarily inefficient on physically indexed processors.
+	 */
+	shm_align_mask = max_t( unsigned long,
+				c->dcache.sets * c->dcache.linesz - 1,
+				PAGE_SIZE - 1);
+
+	flush_cache_all		= r4k_flush_cache_all;
+	__flush_cache_all	= r4k___flush_cache_all;
+	flush_cache_mm		= r4k_flush_cache_mm;
+	flush_cache_page	= r4k_flush_cache_page;
+	flush_icache_page	= r4k_flush_icache_page;
+	flush_cache_range	= r4k_flush_cache_range;
+
+	flush_cache_sigtramp	= r4k_flush_cache_sigtramp;
+	flush_icache_all	= r4k_flush_icache_all;
+	flush_data_cache_page	= r4k_flush_data_cache_page;
+	flush_icache_range	= r4k_flush_icache_range;
+
+#ifdef CONFIG_DMA_NONCOHERENT
+	_dma_cache_wback_inv	= r4k_dma_cache_wback_inv;
+	_dma_cache_wback	= r4k_dma_cache_wback_inv;
+	_dma_cache_inv		= r4k_dma_cache_inv;
+#endif
+
+	__flush_cache_all();
+	coherency_setup();
+
+	build_clear_page();
+	build_copy_page();
+}
diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c
new file mode 100644
index 0000000..ab30afd
--- /dev/null
+++ b/arch/mips/mm/c-sb1.c
@@ -0,0 +1,558 @@
+/*
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
+ * Copyright (C) 2004  Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/asm.h>
+#include <asm/bootinfo.h>
+#include <asm/cacheops.h>
+#include <asm/cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/mmu_context.h>
+#include <asm/uaccess.h>
+
+extern void sb1_dma_init(void);
+
+/* These are probed at ld_mmu time */
+static unsigned long icache_size;
+static unsigned long dcache_size;
+
+static unsigned short icache_line_size;
+static unsigned short dcache_line_size;
+
+static unsigned int icache_index_mask;
+static unsigned int dcache_index_mask;
+
+static unsigned short icache_assoc;
+static unsigned short dcache_assoc;
+
+static unsigned short icache_sets;
+static unsigned short dcache_sets;
+
+static unsigned int icache_range_cutoff;
+static unsigned int dcache_range_cutoff;
+
+/*
+ * The dcache is fully coherent to the system, with one
+ * big caveat:  the instruction stream.  In other words,
+ * if we miss in the icache, and have dirty data in the
+ * L1 dcache, then we'll go out to memory (or the L2) and
+ * get the not-as-recent data.
+ *
+ * So the only time we have to flush the dcache is when
+ * we're flushing the icache.  Since the L2 is fully
+ * coherent to everything, including I/O, we never have
+ * to flush it
+ */
+
+#define cache_set_op(op, addr)						\
+	__asm__ __volatile__(						\
+	"	.set	noreorder		\n"			\
+	"	.set	mips64\n\t		\n"			\
+	"	cache	%0, (0<<13)(%1)		\n"			\
+	"	cache	%0, (1<<13)(%1)		\n"			\
+	"	cache	%0, (2<<13)(%1)		\n"			\
+	"	cache	%0, (3<<13)(%1)		\n"			\
+	"	.set	mips0			\n"			\
+	"	.set	reorder"					\
+	:								\
+	: "i" (op), "r" (addr))
+
+#define sync()								\
+	__asm__ __volatile(						\
+	"	.set	mips64\n\t		\n"			\
+	"	sync				\n"			\
+	"	.set	mips0")
+
+#define mispredict()							\
+	__asm__ __volatile__(						\
+	"	bnezl  $0, 1f		\n" /* Force mispredict */	\
+	"1:				\n");
+
+/*
+ * Writeback and invalidate the entire dcache
+ */
+static inline void __sb1_writeback_inv_dcache_all(void)
+{
+	unsigned long addr = 0;
+
+	while (addr < dcache_line_size * dcache_sets) {
+		cache_set_op(Index_Writeback_Inv_D, addr);
+		addr += dcache_line_size;
+	}
+}
+
+/*
+ * Writeback and invalidate a range of the dcache.  The addresses are
+ * virtual, and since we're using index ops and bit 12 is part of both
+ * the virtual frame and physical index, we have to clear both sets
+ * (bit 12 set and cleared).
+ */
+static inline void __sb1_writeback_inv_dcache_range(unsigned long start,
+	unsigned long end)
+{
+	unsigned long index;
+
+	start &= ~(dcache_line_size - 1);
+	end = (end + dcache_line_size - 1) & ~(dcache_line_size - 1);
+
+	while (start != end) {
+		index = start & dcache_index_mask;
+		cache_set_op(Index_Writeback_Inv_D, index);
+		cache_set_op(Index_Writeback_Inv_D, index ^ (1<<12));
+		start += dcache_line_size;
+	}
+	sync();
+}
+
+/*
+ * Writeback and invalidate a range of the dcache.  With physical
+ * addresseses, we don't have to worry about possible bit 12 aliasing.
+ * XXXKW is it worth turning on KX and using hit ops with xkphys?
+ */
+static inline void __sb1_writeback_inv_dcache_phys_range(unsigned long start,
+	unsigned long end)
+{
+	start &= ~(dcache_line_size - 1);
+	end = (end + dcache_line_size - 1) & ~(dcache_line_size - 1);
+
+	while (start != end) {
+		cache_set_op(Index_Writeback_Inv_D, start & dcache_index_mask);
+		start += dcache_line_size;
+	}
+	sync();
+}
+
+
+/*
+ * Invalidate the entire icache
+ */
+static inline void __sb1_flush_icache_all(void)
+{
+	unsigned long addr = 0;
+
+	while (addr < icache_line_size * icache_sets) {
+		cache_set_op(Index_Invalidate_I, addr);
+		addr += icache_line_size;
+	}
+}
+
+/*
+ * Flush the icache for a given physical page.  Need to writeback the
+ * dcache first, then invalidate the icache.  If the page isn't
+ * executable, nothing is required.
+ */
+static void local_sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn)
+{
+	int cpu = smp_processor_id();
+
+#ifndef CONFIG_SMP
+	if (!(vma->vm_flags & VM_EXEC))
+		return;
+#endif
+
+	__sb1_writeback_inv_dcache_range(addr, addr + PAGE_SIZE);
+
+	/*
+	 * Bumping the ASID is probably cheaper than the flush ...
+	 */
+	if (cpu_context(cpu, vma->vm_mm) != 0)
+		drop_mmu_context(vma->vm_mm, cpu);
+}
+
+#ifdef CONFIG_SMP
+struct flush_cache_page_args {
+	struct vm_area_struct *vma;
+	unsigned long addr;
+	unsigned long pfn;
+};
+
+static void sb1_flush_cache_page_ipi(void *info)
+{
+	struct flush_cache_page_args *args = info;
+
+	local_sb1_flush_cache_page(args->vma, args->addr, args->pfn);
+}
+
+/* Dirty dcache could be on another CPU, so do the IPIs */
+static void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn)
+{
+	struct flush_cache_page_args args;
+
+	if (!(vma->vm_flags & VM_EXEC))
+		return;
+
+	addr &= PAGE_MASK;
+	args.vma = vma;
+	args.addr = addr;
+	args.pfn = pfn;
+	on_each_cpu(sb1_flush_cache_page_ipi, (void *) &args, 1, 1);
+}
+#else
+void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn)
+	__attribute__((alias("local_sb1_flush_cache_page")));
+#endif
+
+/*
+ * Invalidate a range of the icache.  The addresses are virtual, and
+ * the cache is virtually indexed and tagged.  However, we don't
+ * necessarily have the right ASID context, so use index ops instead
+ * of hit ops.
+ */
+static inline void __sb1_flush_icache_range(unsigned long start,
+	unsigned long end)
+{
+	start &= ~(icache_line_size - 1);
+	end = (end + icache_line_size - 1) & ~(icache_line_size - 1);
+
+	while (start != end) {
+		cache_set_op(Index_Invalidate_I, start & icache_index_mask);
+		start += icache_line_size;
+	}
+	mispredict();
+	sync();
+}
+
+
+/*
+ * Invalidate all caches on this CPU
+ */
+static void local_sb1___flush_cache_all(void)
+{
+	__sb1_writeback_inv_dcache_all();
+	__sb1_flush_icache_all();
+}
+
+#ifdef CONFIG_SMP
+void sb1___flush_cache_all_ipi(void *ignored)
+	__attribute__((alias("local_sb1___flush_cache_all")));
+
+static void sb1___flush_cache_all(void)
+{
+	on_each_cpu(sb1___flush_cache_all_ipi, 0, 1, 1);
+}
+#else
+void sb1___flush_cache_all(void)
+	__attribute__((alias("local_sb1___flush_cache_all")));
+#endif
+
+/*
+ * When flushing a range in the icache, we have to first writeback
+ * the dcache for the same range, so new ifetches will see any
+ * data that was dirty in the dcache.
+ *
+ * The start/end arguments are Kseg addresses (possibly mapped Kseg).
+ */
+
+static void local_sb1_flush_icache_range(unsigned long start,
+	unsigned long end)
+{
+	/* Just wb-inv the whole dcache if the range is big enough */
+	if ((end - start) > dcache_range_cutoff)
+		__sb1_writeback_inv_dcache_all();
+	else
+		__sb1_writeback_inv_dcache_range(start, end);
+	
+	/* Just flush the whole icache if the range is big enough */
+	if ((end - start) > icache_range_cutoff)
+		__sb1_flush_icache_all();
+	else
+		__sb1_flush_icache_range(start, end);
+}
+
+#ifdef CONFIG_SMP
+struct flush_icache_range_args {
+	unsigned long start;
+	unsigned long end;
+};
+
+static void sb1_flush_icache_range_ipi(void *info)
+{
+	struct flush_icache_range_args *args = info;
+
+	local_sb1_flush_icache_range(args->start, args->end);
+}
+
+void sb1_flush_icache_range(unsigned long start, unsigned long end)
+{
+	struct flush_icache_range_args args;
+
+	args.start = start;
+	args.end = end;
+	on_each_cpu(sb1_flush_icache_range_ipi, &args, 1, 1);
+}
+#else
+void sb1_flush_icache_range(unsigned long start, unsigned long end)
+	__attribute__((alias("local_sb1_flush_icache_range")));
+#endif
+
+/*
+ * Flush the icache for a given physical page.  Need to writeback the
+ * dcache first, then invalidate the icache.  If the page isn't
+ * executable, nothing is required.
+ */
+static void local_sb1_flush_icache_page(struct vm_area_struct *vma,
+	struct page *page)
+{
+	unsigned long start;
+	int cpu = smp_processor_id();
+
+#ifndef CONFIG_SMP
+	if (!(vma->vm_flags & VM_EXEC))
+		return;
+#endif
+
+	/* Need to writeback any dirty data for that page, we have the PA */
+	start = (unsigned long)(page-mem_map) << PAGE_SHIFT;
+	__sb1_writeback_inv_dcache_phys_range(start, start + PAGE_SIZE);
+	/*
+	 * If there's a context, bump the ASID (cheaper than a flush,
+	 * since we don't know VAs!)
+	 */
+	if (cpu_context(cpu, vma->vm_mm) != 0) {
+		drop_mmu_context(vma->vm_mm, cpu);
+	}
+}
+
+#ifdef CONFIG_SMP
+struct flush_icache_page_args {
+	struct vm_area_struct *vma;
+	struct page *page;
+};
+
+static void sb1_flush_icache_page_ipi(void *info)
+{
+	struct flush_icache_page_args *args = info;
+	local_sb1_flush_icache_page(args->vma, args->page);
+}
+
+/* Dirty dcache could be on another CPU, so do the IPIs */
+static void sb1_flush_icache_page(struct vm_area_struct *vma,
+	struct page *page)
+{
+	struct flush_icache_page_args args;
+
+	if (!(vma->vm_flags & VM_EXEC))
+		return;
+	args.vma = vma;
+	args.page = page;
+	on_each_cpu(sb1_flush_icache_page_ipi, (void *) &args, 1, 1);
+}
+#else
+void sb1_flush_icache_page(struct vm_area_struct *vma, struct page *page)
+	__attribute__((alias("local_sb1_flush_icache_page")));
+#endif
+
+/*
+ * A signal trampoline must fit into a single cacheline.
+ */
+static void local_sb1_flush_cache_sigtramp(unsigned long addr)
+{
+	cache_set_op(Index_Writeback_Inv_D, addr & dcache_index_mask);
+	cache_set_op(Index_Writeback_Inv_D, (addr ^ (1<<12)) & dcache_index_mask);
+	cache_set_op(Index_Invalidate_I, addr & icache_index_mask);
+	mispredict();
+}
+
+#ifdef CONFIG_SMP
+static void sb1_flush_cache_sigtramp_ipi(void *info)
+{
+	unsigned long iaddr = (unsigned long) info;
+	local_sb1_flush_cache_sigtramp(iaddr);
+}
+
+static void sb1_flush_cache_sigtramp(unsigned long addr)
+{
+	on_each_cpu(sb1_flush_cache_sigtramp_ipi, (void *) addr, 1, 1);
+}
+#else
+void sb1_flush_cache_sigtramp(unsigned long addr)
+	__attribute__((alias("local_sb1_flush_cache_sigtramp")));
+#endif
+
+
+/*
+ * Anything that just flushes dcache state can be ignored, as we're always
+ * coherent in dcache space.  This is just a dummy function that all the
+ * nop'ed routines point to
+ */
+static void sb1_nop(void)
+{
+}
+
+/*
+ *  Cache set values (from the mips64 spec)
+ * 0 - 64
+ * 1 - 128
+ * 2 - 256
+ * 3 - 512
+ * 4 - 1024
+ * 5 - 2048
+ * 6 - 4096
+ * 7 - Reserved
+ */
+
+static unsigned int decode_cache_sets(unsigned int config_field)
+{
+	if (config_field == 7) {
+		/* JDCXXX - Find a graceful way to abort. */
+		return 0;
+	}
+	return (1<<(config_field + 6));
+}
+
+/*
+ *  Cache line size values (from the mips64 spec)
+ * 0 - No cache present.
+ * 1 - 4 bytes
+ * 2 - 8 bytes
+ * 3 - 16 bytes
+ * 4 - 32 bytes
+ * 5 - 64 bytes
+ * 6 - 128 bytes
+ * 7 - Reserved
+ */
+
+static unsigned int decode_cache_line_size(unsigned int config_field)
+{
+	if (config_field == 0) {
+		return 0;
+	} else if (config_field == 7) {
+		/* JDCXXX - Find a graceful way to abort. */
+		return 0;
+	}
+	return (1<<(config_field + 1));
+}
+
+/*
+ * Relevant bits of the config1 register format (from the MIPS32/MIPS64 specs)
+ *
+ * 24:22 Icache sets per way
+ * 21:19 Icache line size
+ * 18:16 Icache Associativity
+ * 15:13 Dcache sets per way
+ * 12:10 Dcache line size
+ * 9:7   Dcache Associativity
+ */
+
+static char *way_string[] = {
+	"direct mapped", "2-way", "3-way", "4-way",
+	"5-way", "6-way", "7-way", "8-way",
+};
+
+static __init void probe_cache_sizes(void)
+{
+	u32 config1;
+
+	config1 = read_c0_config1();
+	icache_line_size = decode_cache_line_size((config1 >> 19) & 0x7);
+	dcache_line_size = decode_cache_line_size((config1 >> 10) & 0x7);
+	icache_sets = decode_cache_sets((config1 >> 22) & 0x7);
+	dcache_sets = decode_cache_sets((config1 >> 13) & 0x7);
+	icache_assoc = ((config1 >> 16) & 0x7) + 1;
+	dcache_assoc = ((config1 >> 7) & 0x7) + 1;
+	icache_size = icache_line_size * icache_sets * icache_assoc;
+	dcache_size = dcache_line_size * dcache_sets * dcache_assoc;
+	/* Need to remove non-index bits for index ops */
+	icache_index_mask = (icache_sets - 1) * icache_line_size;
+	dcache_index_mask = (dcache_sets - 1) * dcache_line_size;
+	/*
+	 * These are for choosing range (index ops) versus all.
+	 * icache flushes all ways for each set, so drop icache_assoc.
+	 * dcache flushes all ways and each setting of bit 12 for each
+	 * index, so drop dcache_assoc and halve the dcache_sets.
+	 */
+	icache_range_cutoff = icache_sets * icache_line_size;
+	dcache_range_cutoff = (dcache_sets / 2) * icache_line_size;
+
+	printk("Primary instruction cache %ldkB, %s, linesize %d bytes.\n",
+	       icache_size >> 10, way_string[icache_assoc - 1],
+	       icache_line_size);
+	printk("Primary data cache %ldkB, %s, linesize %d bytes.\n",
+	       dcache_size >> 10, way_string[dcache_assoc - 1],
+	       dcache_line_size);
+}
+
+/*
+ * This is called from loadmmu.c.  We have to set up all the
+ * memory management function pointers, as well as initialize
+ * the caches and tlbs
+ */
+void ld_mmu_sb1(void)
+{
+	extern char except_vec2_sb1;
+	extern char handle_vec2_sb1;
+
+	/* Special cache error handler for SB1 */
+	memcpy((void *)(CAC_BASE   + 0x100), &except_vec2_sb1, 0x80);
+	memcpy((void *)(UNCAC_BASE + 0x100), &except_vec2_sb1, 0x80);
+	memcpy((void *)CKSEG1ADDR(&handle_vec2_sb1), &handle_vec2_sb1, 0x80);
+
+	probe_cache_sizes();
+
+#ifdef CONFIG_SIBYTE_DMA_PAGEOPS
+	sb1_dma_init();
+#endif
+
+	/*
+	 * None of these are needed for the SB1 - the Dcache is
+	 * physically indexed and tagged, so no virtual aliasing can
+	 * occur
+	 */
+	flush_cache_range = (void *) sb1_nop;
+	flush_cache_mm = (void (*)(struct mm_struct *))sb1_nop;
+	flush_cache_all = sb1_nop;
+
+	/* These routines are for Icache coherence with the Dcache */
+	flush_icache_range = sb1_flush_icache_range;
+	flush_icache_page = sb1_flush_icache_page;
+	flush_icache_all = __sb1_flush_icache_all; /* local only */
+
+	/* This implies an Icache flush too, so can't be nop'ed */
+	flush_cache_page = sb1_flush_cache_page;
+
+	flush_cache_sigtramp = sb1_flush_cache_sigtramp;
+	flush_data_cache_page = (void *) sb1_nop;
+
+	/* Full flush */
+	__flush_cache_all = sb1___flush_cache_all;
+
+	change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT);
+
+	/*
+	 * This is the only way to force the update of K0 to complete
+	 * before subsequent instruction fetch.
+	 */
+	__asm__ __volatile__(
+		".set	push			\n"
+	"	.set	noat			\n"
+	"	.set	noreorder		\n"
+	"	.set	mips3			\n"
+	"	" STR(PTR_LA) "	$1, 1f		\n"
+	"	" STR(MTC0) "	$1, $14		\n"
+	"	eret				\n"
+	"1:	.set	pop"
+	:
+	:
+	: "memory");
+
+	flush_cache_all();
+}
diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c
new file mode 100644
index 0000000..ff5afab
--- /dev/null
+++ b/arch/mips/mm/c-tx39.c
@@ -0,0 +1,493 @@
+/*
+ * r2300.c: R2000 and R3000 specific mmu/cache code.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ *
+ * with a lot of changes to make this thing work for R3000s
+ * Tx39XX R4k style caches added. HK
+ * Copyright (C) 1998, 1999, 2000 Harald Koerfgen
+ * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/cacheops.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/mmu_context.h>
+#include <asm/system.h>
+#include <asm/isadep.h>
+#include <asm/io.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+
+/* For R3000 cores with R4000 style caches */
+static unsigned long icache_size, dcache_size;		/* Size in bytes */
+
+#include <asm/r4kcache.h>
+
+extern int r3k_have_wired_reg;	/* in r3k-tlb.c */
+
+/* This sequence is required to ensure icache is disabled immediately */
+#define TX39_STOP_STREAMING() \
+__asm__ __volatile__( \
+	".set    push\n\t" \
+	".set    noreorder\n\t" \
+	"b       1f\n\t" \
+	"nop\n\t" \
+	"1:\n\t" \
+	".set pop" \
+	)
+
+/* TX39H-style cache flush routines. */
+static void tx39h_flush_icache_all(void)
+{
+	unsigned long start = KSEG0;
+	unsigned long end = (start + icache_size);
+	unsigned long flags, config;
+
+	/* disable icache (set ICE#) */
+	local_irq_save(flags);
+	config = read_c0_conf();
+	write_c0_conf(config & ~TX39_CONF_ICE);
+	TX39_STOP_STREAMING();
+
+	/* invalidate icache */
+	while (start < end) {
+		cache16_unroll32(start, Index_Invalidate_I);
+		start += 0x200;
+	}
+
+	write_c0_conf(config);
+	local_irq_restore(flags);
+}
+
+static void tx39h_dma_cache_wback_inv(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+	unsigned long dc_lsize = current_cpu_data.dcache.linesz;
+
+	/* Catch bad driver code */
+	BUG_ON(size == 0);
+
+	iob();
+	a = addr & ~(dc_lsize - 1);
+	end = (addr + size - 1) & ~(dc_lsize - 1);
+	while (1) {
+		invalidate_dcache_line(a); /* Hit_Invalidate_D */
+		if (a == end) break;
+		a += dc_lsize;
+	}
+}
+
+
+/* TX39H2,TX39H3 */
+static inline void tx39_blast_dcache_page(unsigned long addr)
+{
+	if (current_cpu_data.cputype != CPU_TX3912)
+		blast_dcache16_page(addr);
+}
+
+static inline void tx39_blast_dcache_page_indexed(unsigned long addr)
+{
+	blast_dcache16_page_indexed(addr);
+}
+
+static inline void tx39_blast_dcache(void)
+{
+	blast_dcache16();
+}
+
+static inline void tx39_blast_icache_page(unsigned long addr)
+{
+	unsigned long flags, config;
+	/* disable icache (set ICE#) */
+	local_irq_save(flags);
+	config = read_c0_conf();
+	write_c0_conf(config & ~TX39_CONF_ICE);
+	TX39_STOP_STREAMING();
+	blast_icache16_page(addr);
+	write_c0_conf(config);
+	local_irq_restore(flags);
+}
+
+static inline void tx39_blast_icache_page_indexed(unsigned long addr)
+{
+	unsigned long flags, config;
+	/* disable icache (set ICE#) */
+	local_irq_save(flags);
+	config = read_c0_conf();
+	write_c0_conf(config & ~TX39_CONF_ICE);
+	TX39_STOP_STREAMING();
+	blast_icache16_page_indexed(addr);
+	write_c0_conf(config);
+	local_irq_restore(flags);
+}
+
+static inline void tx39_blast_icache(void)
+{
+	unsigned long flags, config;
+	/* disable icache (set ICE#) */
+	local_irq_save(flags);
+	config = read_c0_conf();
+	write_c0_conf(config & ~TX39_CONF_ICE);
+	TX39_STOP_STREAMING();
+	blast_icache16();
+	write_c0_conf(config);
+	local_irq_restore(flags);
+}
+
+static inline void tx39_flush_cache_all(void)
+{
+	if (!cpu_has_dc_aliases)
+		return;
+
+	tx39_blast_dcache();
+	tx39_blast_icache();
+}
+
+static inline void tx39___flush_cache_all(void)
+{
+	tx39_blast_dcache();
+	tx39_blast_icache();
+}
+
+static void tx39_flush_cache_mm(struct mm_struct *mm)
+{
+	if (!cpu_has_dc_aliases)
+		return;
+
+	if (cpu_context(smp_processor_id(), mm) != 0) {
+		tx39_flush_cache_all();
+	}
+}
+
+static void tx39_flush_cache_range(struct vm_area_struct *vma,
+	unsigned long start, unsigned long end)
+{
+	struct mm_struct *mm = vma->vm_mm;
+
+	if (!cpu_has_dc_aliases)
+		return;
+
+	if (cpu_context(smp_processor_id(), mm) != 0) {
+		tx39_blast_dcache();
+		tx39_blast_icache();
+	}
+}
+
+static void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page, unsigned long pfn)
+{
+	int exec = vma->vm_flags & VM_EXEC;
+	struct mm_struct *mm = vma->vm_mm;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if (cpu_context(smp_processor_id(), mm) == 0)
+		return;
+
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if (!(pte_val(*ptep) & _PAGE_PRESENT))
+		return;
+
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since stupid R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
+		if (cpu_has_dc_aliases || exec)
+			tx39_blast_dcache_page(page);
+		if (exec)
+			tx39_blast_icache_page(page);
+
+		return;
+	}
+
+	/*
+	 * Do indexed flush, too much work to get the (possible) TLB refills
+	 * to work correctly.
+	 */
+	page = (KSEG0 + (page & (dcache_size - 1)));
+	if (cpu_has_dc_aliases || exec)
+		tx39_blast_dcache_page_indexed(page);
+	if (exec)
+		tx39_blast_icache_page_indexed(page);
+}
+
+static void tx39_flush_data_cache_page(unsigned long addr)
+{
+	tx39_blast_dcache_page(addr);
+}
+
+static void tx39_flush_icache_range(unsigned long start, unsigned long end)
+{
+	unsigned long dc_lsize = current_cpu_data.dcache.linesz;
+	unsigned long addr, aend;
+
+	if (end - start > dcache_size)
+		tx39_blast_dcache();
+	else {
+		addr = start & ~(dc_lsize - 1);
+		aend = (end - 1) & ~(dc_lsize - 1);
+
+		while (1) {
+			/* Hit_Writeback_Inv_D */
+			protected_writeback_dcache_line(addr);
+			if (addr == aend)
+				break;
+			addr += dc_lsize;
+		}
+	}
+
+	if (end - start > icache_size)
+		tx39_blast_icache();
+	else {
+		unsigned long flags, config;
+		addr = start & ~(dc_lsize - 1);
+		aend = (end - 1) & ~(dc_lsize - 1);
+		/* disable icache (set ICE#) */
+		local_irq_save(flags);
+		config = read_c0_conf();
+		write_c0_conf(config & ~TX39_CONF_ICE);
+		TX39_STOP_STREAMING();
+		while (1) {
+			/* Hit_Invalidate_I */
+			protected_flush_icache_line(addr);
+			if (addr == aend)
+				break;
+			addr += dc_lsize;
+		}
+		write_c0_conf(config);
+		local_irq_restore(flags);
+	}
+}
+
+/*
+ * Ok, this seriously sucks.  We use them to flush a user page but don't
+ * know the virtual address, so we have to blast away the whole icache
+ * which is significantly more expensive than the real thing.  Otoh we at
+ * least know the kernel address of the page so we can flush it
+ * selectivly.
+ */
+static void tx39_flush_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+	unsigned long addr;
+	/*
+	 * If there's no context yet, or the page isn't executable, no icache
+	 * flush is needed.
+	 */
+	if (!(vma->vm_flags & VM_EXEC))
+		return;
+
+	addr = (unsigned long) page_address(page);
+	tx39_blast_dcache_page(addr);
+
+	/*
+	 * We're not sure of the virtual address(es) involved here, so
+	 * we have to flush the entire I-cache.
+	 */
+	tx39_blast_icache();
+}
+
+static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	if (((size | addr) & (PAGE_SIZE - 1)) == 0) {
+		end = addr + size;
+		do {
+			tx39_blast_dcache_page(addr);
+			addr += PAGE_SIZE;
+		} while(addr != end);
+	} else if (size > dcache_size) {
+		tx39_blast_dcache();
+	} else {
+		unsigned long dc_lsize = current_cpu_data.dcache.linesz;
+		a = addr & ~(dc_lsize - 1);
+		end = (addr + size - 1) & ~(dc_lsize - 1);
+		while (1) {
+			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
+			if (a == end) break;
+			a += dc_lsize;
+		}
+	}
+}
+
+static void tx39_dma_cache_inv(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	if (((size | addr) & (PAGE_SIZE - 1)) == 0) {
+		end = addr + size;
+		do {
+			tx39_blast_dcache_page(addr);
+			addr += PAGE_SIZE;
+		} while(addr != end);
+	} else if (size > dcache_size) {
+		tx39_blast_dcache();
+	} else {
+		unsigned long dc_lsize = current_cpu_data.dcache.linesz;
+		a = addr & ~(dc_lsize - 1);
+		end = (addr + size - 1) & ~(dc_lsize - 1);
+		while (1) {
+			invalidate_dcache_line(a); /* Hit_Invalidate_D */
+			if (a == end) break;
+			a += dc_lsize;
+		}
+	}
+}
+
+static void tx39_flush_cache_sigtramp(unsigned long addr)
+{
+	unsigned long ic_lsize = current_cpu_data.icache.linesz;
+	unsigned long dc_lsize = current_cpu_data.dcache.linesz;
+	unsigned long config;
+	unsigned long flags;
+
+	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
+
+	/* disable icache (set ICE#) */
+	local_irq_save(flags);
+	config = read_c0_conf();
+	write_c0_conf(config & ~TX39_CONF_ICE);
+	TX39_STOP_STREAMING();
+	protected_flush_icache_line(addr & ~(ic_lsize - 1));
+	write_c0_conf(config);
+	local_irq_restore(flags);
+}
+
+static __init void tx39_probe_cache(void)
+{
+	unsigned long config;
+
+	config = read_c0_conf();
+
+	icache_size = 1 << (10 + ((config & TX39_CONF_ICS_MASK) >>
+				  TX39_CONF_ICS_SHIFT));
+	dcache_size = 1 << (10 + ((config & TX39_CONF_DCS_MASK) >>
+				  TX39_CONF_DCS_SHIFT));
+
+	current_cpu_data.icache.linesz = 16;
+	switch (current_cpu_data.cputype) {
+	case CPU_TX3912:
+		current_cpu_data.icache.ways = 1;
+		current_cpu_data.dcache.ways = 1;
+		current_cpu_data.dcache.linesz = 4;
+		break;
+
+	case CPU_TX3927:
+		current_cpu_data.icache.ways = 2;
+		current_cpu_data.dcache.ways = 2;
+		current_cpu_data.dcache.linesz = 16;
+		break;
+
+	case CPU_TX3922:
+	default:
+		current_cpu_data.icache.ways = 1;
+		current_cpu_data.dcache.ways = 1;
+		current_cpu_data.dcache.linesz = 16;
+		break;
+	}
+}
+
+void __init ld_mmu_tx39(void)
+{
+	extern void build_clear_page(void);
+	extern void build_copy_page(void);
+	unsigned long config;
+
+	config = read_c0_conf();
+	config &= ~TX39_CONF_WBON;
+	write_c0_conf(config);
+
+	tx39_probe_cache();
+
+	switch (current_cpu_data.cputype) {
+	case CPU_TX3912:
+		/* TX39/H core (writethru direct-map cache) */
+		flush_cache_all	= tx39h_flush_icache_all;
+		__flush_cache_all	= tx39h_flush_icache_all;
+		flush_cache_mm		= (void *) tx39h_flush_icache_all;
+		flush_cache_range	= (void *) tx39h_flush_icache_all;
+		flush_cache_page	= (void *) tx39h_flush_icache_all;
+		flush_icache_page	= (void *) tx39h_flush_icache_all;
+		flush_icache_range	= (void *) tx39h_flush_icache_all;
+
+		flush_cache_sigtramp	= (void *) tx39h_flush_icache_all;
+		flush_data_cache_page	= (void *) tx39h_flush_icache_all;
+
+		_dma_cache_wback_inv	= tx39h_dma_cache_wback_inv;
+
+		shm_align_mask		= PAGE_SIZE - 1;
+
+		break;
+
+	case CPU_TX3922:
+	case CPU_TX3927:
+	default:
+		/* TX39/H2,H3 core (writeback 2way-set-associative cache) */
+		r3k_have_wired_reg = 1;
+		write_c0_wired(0);	/* set 8 on reset... */
+		/* board-dependent init code may set WBON */
+
+		flush_cache_all = tx39_flush_cache_all;
+		__flush_cache_all = tx39___flush_cache_all;
+		flush_cache_mm = tx39_flush_cache_mm;
+		flush_cache_range = tx39_flush_cache_range;
+		flush_cache_page = tx39_flush_cache_page;
+		flush_icache_page = tx39_flush_icache_page;
+		flush_icache_range = tx39_flush_icache_range;
+
+		flush_cache_sigtramp = tx39_flush_cache_sigtramp;
+		flush_data_cache_page = tx39_flush_data_cache_page;
+
+		_dma_cache_wback_inv = tx39_dma_cache_wback_inv;
+		_dma_cache_wback = tx39_dma_cache_wback_inv;
+		_dma_cache_inv = tx39_dma_cache_inv;
+
+		shm_align_mask = max_t(unsigned long,
+		                       (dcache_size / current_cpu_data.dcache.ways) - 1,
+		                       PAGE_SIZE - 1);
+
+		break;
+	}
+
+	current_cpu_data.icache.waysize = icache_size / current_cpu_data.icache.ways;
+	current_cpu_data.dcache.waysize = dcache_size / current_cpu_data.dcache.ways;
+
+	current_cpu_data.icache.sets =
+		current_cpu_data.icache.waysize / current_cpu_data.icache.linesz;
+	current_cpu_data.dcache.sets =
+		current_cpu_data.dcache.waysize / current_cpu_data.dcache.linesz;
+
+	if (current_cpu_data.dcache.waysize > PAGE_SIZE)
+		current_cpu_data.dcache.flags |= MIPS_CACHE_ALIASES;
+
+	current_cpu_data.icache.waybit = 0;
+	current_cpu_data.dcache.waybit = 0;
+
+	printk("Primary instruction cache %ldkB, linesize %d bytes\n",
+		icache_size >> 10, current_cpu_data.icache.linesz);
+	printk("Primary data cache %ldkB, linesize %d bytes\n",
+		dcache_size >> 10, current_cpu_data.dcache.linesz);
+
+	build_clear_page();
+	build_copy_page();
+}
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
new file mode 100644
index 0000000..1d95cdb
--- /dev/null
+++ b/arch/mips/mm/cache.c
@@ -0,0 +1,157 @@
+/*
+ * 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) 1994 - 2003 by Ralf Baechle
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/cacheflush.h>
+#include <asm/processor.h>
+#include <asm/cpu.h>
+#include <asm/cpu-features.h>
+
+/* Cache operations. */
+void (*flush_cache_all)(void);
+void (*__flush_cache_all)(void);
+void (*flush_cache_mm)(struct mm_struct *mm);
+void (*flush_cache_range)(struct vm_area_struct *vma, unsigned long start,
+	unsigned long end);
+void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn);
+void (*flush_icache_range)(unsigned long start, unsigned long end);
+void (*flush_icache_page)(struct vm_area_struct *vma, struct page *page);
+
+/* MIPS specific cache operations */
+void (*flush_cache_sigtramp)(unsigned long addr);
+void (*flush_data_cache_page)(unsigned long addr);
+void (*flush_icache_all)(void);
+
+#ifdef CONFIG_DMA_NONCOHERENT
+
+/* DMA cache operations. */
+void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size);
+void (*_dma_cache_wback)(unsigned long start, unsigned long size);
+void (*_dma_cache_inv)(unsigned long start, unsigned long size);
+
+EXPORT_SYMBOL(_dma_cache_wback_inv);
+EXPORT_SYMBOL(_dma_cache_wback);
+EXPORT_SYMBOL(_dma_cache_inv);
+
+#endif /* CONFIG_DMA_NONCOHERENT */
+
+/*
+ * We could optimize the case where the cache argument is not BCACHE but
+ * that seems very atypical use ...
+ */
+asmlinkage int sys_cacheflush(unsigned long addr, unsigned long int bytes,
+	unsigned int cache)
+{
+	if (!access_ok(VERIFY_WRITE, (void *) addr, bytes))
+		return -EFAULT;
+
+	flush_icache_range(addr, addr + bytes);
+
+	return 0;
+}
+
+void __flush_dcache_page(struct page *page)
+{
+	struct address_space *mapping = page_mapping(page);
+	unsigned long addr;
+
+	if (mapping && !mapping_mapped(mapping)) {
+		SetPageDcacheDirty(page);
+		return;
+	}
+
+	/*
+	 * We could delay the flush for the !page_mapping case too.  But that
+	 * case is for exec env/arg pages and those are %99 certainly going to
+	 * get faulted into the tlb (and thus flushed) anyways.
+	 */
+	addr = (unsigned long) page_address(page);
+	flush_data_cache_page(addr);
+}
+
+EXPORT_SYMBOL(__flush_dcache_page);
+
+void __update_cache(struct vm_area_struct *vma, unsigned long address,
+	pte_t pte)
+{
+	struct page *page;
+	unsigned long pfn, addr;
+
+	pfn = pte_pfn(pte);
+	if (pfn_valid(pfn) && (page = pfn_to_page(pfn), page_mapping(page)) &&
+	    Page_dcache_dirty(page)) {
+		if (pages_do_alias((unsigned long)page_address(page),
+		                   address & PAGE_MASK)) {
+			addr = (unsigned long) page_address(page);
+			flush_data_cache_page(addr);
+		}
+
+		ClearPageDcacheDirty(page);
+	}
+}
+
+extern void ld_mmu_r23000(void);
+extern void ld_mmu_r4xx0(void);
+extern void ld_mmu_tx39(void);
+extern void ld_mmu_r6000(void);
+extern void ld_mmu_tfp(void);
+extern void ld_mmu_andes(void);
+extern void ld_mmu_sb1(void);
+
+void __init cpu_cache_init(void)
+{
+	if (cpu_has_4ktlb) {
+#if defined(CONFIG_CPU_R4X00)  || defined(CONFIG_CPU_VR41XX) || \
+    defined(CONFIG_CPU_R4300)  || defined(CONFIG_CPU_R5000)  || \
+    defined(CONFIG_CPU_NEVADA) || defined(CONFIG_CPU_R5432)  || \
+    defined(CONFIG_CPU_R5500)  || defined(CONFIG_CPU_MIPS32) || \
+    defined(CONFIG_CPU_MIPS64) || defined(CONFIG_CPU_TX49XX) || \
+    defined(CONFIG_CPU_RM7000) || defined(CONFIG_CPU_RM9000)
+		ld_mmu_r4xx0();
+#endif
+	} else switch (current_cpu_data.cputype) {
+#ifdef CONFIG_CPU_R3000
+	case CPU_R2000:
+	case CPU_R3000:
+	case CPU_R3000A:
+	case CPU_R3081E:
+		ld_mmu_r23000();
+		break;
+#endif
+#ifdef CONFIG_CPU_TX39XX
+	case CPU_TX3912:
+	case CPU_TX3922:
+	case CPU_TX3927:
+		ld_mmu_tx39();
+		break;
+#endif
+#ifdef CONFIG_CPU_R10000
+	case CPU_R10000:
+	case CPU_R12000:
+		ld_mmu_r4xx0();
+		break;
+#endif
+#ifdef CONFIG_CPU_SB1
+	case CPU_SB1:
+		ld_mmu_sb1();
+		break;
+#endif
+
+	case CPU_R8000:
+		panic("R8000 is unsupported");
+		break;
+
+	default:
+		panic("Yeee, unsupported cache architecture.");
+	}
+}
diff --git a/arch/mips/mm/cerr-sb1.c b/arch/mips/mm/cerr-sb1.c
new file mode 100644
index 0000000..13d96d6
--- /dev/null
+++ b/arch/mips/mm/cerr-sb1.c
@@ -0,0 +1,543 @@
+/*
+ * Copyright (C) 2001,2002,2003 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <asm/mipsregs.h>
+#include <asm/sibyte/sb1250.h>
+
+#ifndef CONFIG_SIBYTE_BUS_WATCHER
+#include <asm/io.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_scd.h>
+#endif
+ 
+/* SB1 definitions */
+
+/* XXX should come from config1 XXX */
+#define SB1_CACHE_INDEX_MASK   0x1fe0
+
+#define CP0_ERRCTL_RECOVERABLE (1 << 31)
+#define CP0_ERRCTL_DCACHE      (1 << 30)
+#define CP0_ERRCTL_ICACHE      (1 << 29)
+#define CP0_ERRCTL_MULTIBUS    (1 << 23)
+#define CP0_ERRCTL_MC_TLB      (1 << 15)
+#define CP0_ERRCTL_MC_TIMEOUT  (1 << 14)
+
+#define CP0_CERRI_TAG_PARITY   (1 << 29)
+#define CP0_CERRI_DATA_PARITY  (1 << 28)
+#define CP0_CERRI_EXTERNAL     (1 << 26)
+
+#define CP0_CERRI_IDX_VALID(c) (!((c) & CP0_CERRI_EXTERNAL))
+#define CP0_CERRI_DATA         (CP0_CERRI_DATA_PARITY)
+
+#define CP0_CERRD_MULTIPLE     (1 << 31)
+#define CP0_CERRD_TAG_STATE    (1 << 30)
+#define CP0_CERRD_TAG_ADDRESS  (1 << 29)
+#define CP0_CERRD_DATA_SBE     (1 << 28)
+#define CP0_CERRD_DATA_DBE     (1 << 27)
+#define CP0_CERRD_EXTERNAL     (1 << 26)
+#define CP0_CERRD_LOAD         (1 << 25)
+#define CP0_CERRD_STORE        (1 << 24)
+#define CP0_CERRD_FILLWB       (1 << 23)
+#define CP0_CERRD_COHERENCY    (1 << 22)
+#define CP0_CERRD_DUPTAG       (1 << 21)
+
+#define CP0_CERRD_DPA_VALID(c) (!((c) & CP0_CERRD_EXTERNAL))
+#define CP0_CERRD_IDX_VALID(c) \
+   (((c) & (CP0_CERRD_LOAD | CP0_CERRD_STORE)) ? (!((c) & CP0_CERRD_EXTERNAL)) : 0)
+#define CP0_CERRD_CAUSES \
+   (CP0_CERRD_LOAD | CP0_CERRD_STORE | CP0_CERRD_FILLWB | CP0_CERRD_COHERENCY | CP0_CERRD_DUPTAG)
+#define CP0_CERRD_TYPES \
+   (CP0_CERRD_TAG_STATE | CP0_CERRD_TAG_ADDRESS | CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE | CP0_CERRD_EXTERNAL)
+#define CP0_CERRD_DATA         (CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE)
+
+static uint32_t	extract_ic(unsigned short addr, int data);
+static uint32_t	extract_dc(unsigned short addr, int data);
+
+static inline void breakout_errctl(unsigned int val)
+{
+	if (val & CP0_ERRCTL_RECOVERABLE)
+		prom_printf(" recoverable");
+	if (val & CP0_ERRCTL_DCACHE)
+		prom_printf(" dcache");
+	if (val & CP0_ERRCTL_ICACHE)
+		prom_printf(" icache");
+	if (val & CP0_ERRCTL_MULTIBUS)
+		prom_printf(" multiple-buserr");
+	prom_printf("\n");
+}
+
+static inline void breakout_cerri(unsigned int val)
+{
+	if (val & CP0_CERRI_TAG_PARITY)
+		prom_printf(" tag-parity");
+	if (val & CP0_CERRI_DATA_PARITY)
+		prom_printf(" data-parity");
+	if (val & CP0_CERRI_EXTERNAL)
+		prom_printf(" external");
+	prom_printf("\n");
+}
+
+static inline void breakout_cerrd(unsigned int val)
+{
+	switch (val & CP0_CERRD_CAUSES) {
+	case CP0_CERRD_LOAD:
+		prom_printf(" load,");
+		break;
+	case CP0_CERRD_STORE:
+		prom_printf(" store,");
+		break;
+	case CP0_CERRD_FILLWB:
+		prom_printf(" fill/wb,");
+		break;
+	case CP0_CERRD_COHERENCY:
+		prom_printf(" coherency,");
+		break;
+	case CP0_CERRD_DUPTAG:
+		prom_printf(" duptags,");
+		break;
+	default:
+		prom_printf(" NO CAUSE,");
+		break;
+	}
+	if (!(val & CP0_CERRD_TYPES))
+		prom_printf(" NO TYPE");
+	else {
+		if (val & CP0_CERRD_MULTIPLE)
+			prom_printf(" multi-err");
+		if (val & CP0_CERRD_TAG_STATE)
+			prom_printf(" tag-state");
+		if (val & CP0_CERRD_TAG_ADDRESS)
+			prom_printf(" tag-address");
+		if (val & CP0_CERRD_DATA_SBE)
+			prom_printf(" data-SBE");
+		if (val & CP0_CERRD_DATA_DBE)
+			prom_printf(" data-DBE");
+		if (val & CP0_CERRD_EXTERNAL)
+			prom_printf(" external");
+	}
+	prom_printf("\n");
+}
+
+#ifndef CONFIG_SIBYTE_BUS_WATCHER
+
+static void check_bus_watcher(void)              
+{                               
+	uint32_t status, l2_err, memio_err;
+
+	/* Destructive read, clears register and interrupt */
+	status = csr_in32(IOADDR(A_SCD_BUS_ERR_STATUS));
+	/* Bit 31 is always on, but there's no #define for that */
+	if (status & ~(1UL << 31)) {  
+		l2_err = csr_in32(IOADDR(A_BUS_L2_ERRORS));
+		memio_err = csr_in32(IOADDR(A_BUS_MEM_IO_ERRORS));
+		prom_printf("Bus watcher error counters: %08x %08x\n", l2_err, memio_err);
+		prom_printf("\nLast recorded signature:\n");
+		prom_printf("Request %02x from %d, answered by %d with Dcode %d\n",
+		       (unsigned int)(G_SCD_BERR_TID(status) & 0x3f),
+		       (int)(G_SCD_BERR_TID(status) >> 6),
+		       (int)G_SCD_BERR_RID(status),
+		       (int)G_SCD_BERR_DCODE(status));
+	} else {		
+		prom_printf("Bus watcher indicates no error\n"); 
+	}			
+}                                       
+#else                                                    
+extern void check_bus_watcher(void);    
+#endif                                          
+                                
+asmlinkage void sb1_cache_error(void)
+{
+	uint64_t cerr_dpa;
+	uint32_t errctl, cerr_i, cerr_d, dpalo, dpahi, eepc, res;
+
+	prom_printf("Cache error exception on CPU %x:\n",
+		    (read_c0_prid() >> 25) & 0x7);
+
+	__asm__ __volatile__ (
+	"	.set	push\n\t"
+	"	.set	mips64\n\t"
+	"	.set	noat\n\t"
+	"	mfc0	%0, $26\n\t"
+	"	mfc0	%1, $27\n\t"
+	"	mfc0	%2, $27, 1\n\t"
+	"	dmfc0	$1, $27, 3\n\t"
+	"	dsrl32	%3, $1, 0 \n\t"
+	"	sll	%4, $1, 0 \n\t"
+	"	mfc0	%5, $30\n\t"
+	"	.set	pop"
+	: "=r" (errctl), "=r" (cerr_i), "=r" (cerr_d),
+	  "=r" (dpahi), "=r" (dpalo), "=r" (eepc));
+
+	cerr_dpa = (((uint64_t)dpahi) << 32) | dpalo;
+	prom_printf(" c0_errorepc ==   %08x\n", eepc);
+	prom_printf(" c0_errctl   ==   %08x", errctl);
+	breakout_errctl(errctl);
+	if (errctl & CP0_ERRCTL_ICACHE) {
+		prom_printf(" c0_cerr_i   ==   %08x", cerr_i);
+		breakout_cerri(cerr_i);
+		if (CP0_CERRI_IDX_VALID(cerr_i)) {
+			/* Check index of EPC, allowing for delay slot */
+			if (((eepc & SB1_CACHE_INDEX_MASK) != (cerr_i & SB1_CACHE_INDEX_MASK)) &&
+			    ((eepc & SB1_CACHE_INDEX_MASK) != ((cerr_i & SB1_CACHE_INDEX_MASK) - 4)))
+				prom_printf(" cerr_i idx doesn't match eepc\n");
+			else {
+				res = extract_ic(cerr_i & SB1_CACHE_INDEX_MASK,
+						 (cerr_i & CP0_CERRI_DATA) != 0);
+				if (!(res & cerr_i))
+					prom_printf("...didn't see indicated icache problem\n");
+			}
+		}
+	}
+	if (errctl & CP0_ERRCTL_DCACHE) {
+		prom_printf(" c0_cerr_d   ==   %08x", cerr_d);
+		breakout_cerrd(cerr_d);
+		if (CP0_CERRD_DPA_VALID(cerr_d)) {
+			prom_printf(" c0_cerr_dpa == %010llx\n", cerr_dpa);
+			if (!CP0_CERRD_IDX_VALID(cerr_d)) {
+				res = extract_dc(cerr_dpa & SB1_CACHE_INDEX_MASK,
+						 (cerr_d & CP0_CERRD_DATA) != 0);
+				if (!(res & cerr_d))
+					prom_printf("...didn't see indicated dcache problem\n");
+			} else {
+				if ((cerr_dpa & SB1_CACHE_INDEX_MASK) != (cerr_d & SB1_CACHE_INDEX_MASK))
+					prom_printf(" cerr_d idx doesn't match cerr_dpa\n");
+				else {
+					res = extract_dc(cerr_d & SB1_CACHE_INDEX_MASK,
+							 (cerr_d & CP0_CERRD_DATA) != 0);
+					if (!(res & cerr_d))
+						prom_printf("...didn't see indicated problem\n");
+				}
+			}
+		}
+	}
+
+	check_bus_watcher();
+
+	while (1);
+	/*
+	 * This tends to make things get really ugly; let's just stall instead.
+	 *    panic("Can't handle the cache error!");
+	 */
+}
+
+
+/* Parity lookup table. */
+static const uint8_t parity[256] = {
+	0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
+	1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
+	1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
+	0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
+	1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
+	0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
+	0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
+	1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0
+};
+
+/* Masks to select bits for Hamming parity, mask_72_64[i] for bit[i] */
+static const uint64_t mask_72_64[8] = {
+	0x0738C808099264FFULL,
+	0x38C808099264FF07ULL,
+	0xC808099264FF0738ULL,
+	0x08099264FF0738C8ULL,
+	0x099264FF0738C808ULL,
+	0x9264FF0738C80809ULL,
+	0x64FF0738C8080992ULL,
+	0xFF0738C808099264ULL
+};
+
+/* Calculate the parity on a range of bits */
+static char range_parity(uint64_t dword, int max, int min)
+{
+	char parity = 0;
+	int i;
+	dword >>= min;
+	for (i=max-min; i>=0; i--) {
+		if (dword & 0x1)
+			parity = !parity;
+		dword >>= 1;
+	}
+	return parity;
+}
+
+/* Calculate the 4-bit even byte-parity for an instruction */
+static unsigned char inst_parity(uint32_t word)
+{
+	int i, j;
+	char parity = 0;
+	for (j=0; j<4; j++) {
+		char byte_parity = 0;
+		for (i=0; i<8; i++) {
+			if (word & 0x80000000)
+				byte_parity = !byte_parity;
+			word <<= 1;
+		}
+		parity <<= 1;
+		parity |= byte_parity;
+	}
+	return parity;
+}
+
+static uint32_t extract_ic(unsigned short addr, int data)
+{
+	unsigned short way;
+	int valid;
+	uint64_t taglo, va, tlo_tmp;
+	uint32_t taghi, taglolo, taglohi;
+	uint8_t lru;
+	int res = 0;
+
+	prom_printf("Icache index 0x%04x  ", addr);
+	for (way = 0; way < 4; way++) {
+		/* Index-load-tag-I */
+		__asm__ __volatile__ (
+		"	.set	push		\n\t"
+		"	.set	noreorder	\n\t"
+		"	.set	mips64		\n\t"
+		"	.set	noat		\n\t"
+		"	cache	4, 0(%3)	\n\t"
+		"	mfc0	%0, $29		\n\t"
+		"	dmfc0	$1, $28		\n\t"
+		"	dsrl32	%1, $1, 0	\n\t"
+		"	sll	%2, $1, 0	\n\t"
+		"	.set	pop"
+		: "=r" (taghi), "=r" (taglohi), "=r" (taglolo)
+		: "r" ((way << 13) | addr));
+
+		taglo = ((unsigned long long)taglohi << 32) | taglolo;
+		if (way == 0) {
+			lru = (taghi >> 14) & 0xff;
+			prom_printf("[Bank %d Set 0x%02x]  LRU > %d %d %d %d > MRU\n",
+				    ((addr >> 5) & 0x3), /* bank */
+				    ((addr >> 7) & 0x3f), /* index */
+				    (lru & 0x3),
+				    ((lru >> 2) & 0x3),
+				    ((lru >> 4) & 0x3),
+				    ((lru >> 6) & 0x3));
+		}
+		va = (taglo & 0xC0000FFFFFFFE000ULL) | addr;
+		if ((taglo & (1 << 31)) && (((taglo >> 62) & 0x3) == 3))
+			va |= 0x3FFFF00000000000ULL;
+		valid = ((taghi >> 29) & 1);
+		if (valid) {
+			tlo_tmp = taglo & 0xfff3ff;
+			if (((taglo >> 10) & 1) ^ range_parity(tlo_tmp, 23, 0)) {
+				prom_printf("   ** bad parity in VTag0/G/ASID\n");
+				res |= CP0_CERRI_TAG_PARITY;
+			}
+			if (((taglo >> 11) & 1) ^ range_parity(taglo, 63, 24)) {
+				prom_printf("   ** bad parity in R/VTag1\n");
+				res |= CP0_CERRI_TAG_PARITY;
+			}
+		}
+		if (valid ^ ((taghi >> 27) & 1)) {
+			prom_printf("   ** bad parity for valid bit\n");
+			res |= CP0_CERRI_TAG_PARITY;
+		}
+		prom_printf(" %d  [VA %016llx]  [Vld? %d]  raw tags: %08X-%016llX\n",
+			    way, va, valid, taghi, taglo);
+
+		if (data) {
+			uint32_t datahi, insta, instb;
+			uint8_t predecode;
+			int offset;
+
+			/* (hit all banks and ways) */
+			for (offset = 0; offset < 4; offset++) {
+				/* Index-load-data-I */
+				__asm__ __volatile__ (
+				"	.set	push\n\t"
+				"	.set	noreorder\n\t"
+				"	.set	mips64\n\t"
+				"	.set	noat\n\t"
+				"	cache	6, 0(%3)  \n\t"
+				"	mfc0	%0, $29, 1\n\t"
+				"	dmfc0  $1, $28, 1\n\t"
+				"	dsrl32 %1, $1, 0 \n\t"
+				"	sll    %2, $1, 0 \n\t"
+				"	.set	pop         \n"
+				: "=r" (datahi), "=r" (insta), "=r" (instb)
+				: "r" ((way << 13) | addr | (offset << 3)));
+				predecode = (datahi >> 8) & 0xff;
+				if (((datahi >> 16) & 1) != (uint32_t)range_parity(predecode, 7, 0)) {
+					prom_printf("   ** bad parity in predecode\n");
+					res |= CP0_CERRI_DATA_PARITY;
+				}
+				/* XXXKW should/could check predecode bits themselves */
+				if (((datahi >> 4) & 0xf) ^ inst_parity(insta)) {
+					prom_printf("   ** bad parity in instruction a\n");
+					res |= CP0_CERRI_DATA_PARITY;
+				}
+				if ((datahi & 0xf) ^ inst_parity(instb)) {
+					prom_printf("   ** bad parity in instruction b\n");
+					res |= CP0_CERRI_DATA_PARITY;
+				}
+				prom_printf("  %05X-%08X%08X", datahi, insta, instb);
+			}
+			prom_printf("\n");
+		}
+	}
+	return res;
+}
+
+/* Compute the ECC for a data doubleword */
+static uint8_t dc_ecc(uint64_t dword)
+{
+	uint64_t t;
+	uint32_t w;
+	uint8_t  p;
+	int      i;
+
+	p = 0;
+	for (i = 7; i >= 0; i--)
+	{
+		p <<= 1;
+		t = dword & mask_72_64[i];
+		w = (uint32_t)(t >> 32);
+		p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF]
+		      ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]);
+		w = (uint32_t)(t & 0xFFFFFFFF);
+		p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF]
+		      ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]);
+	}
+	return p;
+}
+
+struct dc_state {
+	unsigned char val;
+	char *name;
+};
+
+static struct dc_state dc_states[] = {
+	{ 0x00, "INVALID" },
+	{ 0x0f, "COH-SHD" },
+	{ 0x13, "NCO-E-C" },
+	{ 0x19, "NCO-E-D" },
+	{ 0x16, "COH-E-C" },
+	{ 0x1c, "COH-E-D" },
+	{ 0xff, "*ERROR*" }
+};
+
+#define DC_TAG_VALID(state) \
+    (((state) == 0xf) || ((state) == 0x13) || ((state) == 0x19) || ((state == 0x16)) || ((state) == 0x1c))
+
+static char *dc_state_str(unsigned char state)
+{
+	struct dc_state *dsc = dc_states;
+	while (dsc->val != 0xff) {
+		if (dsc->val == state)
+			break;
+		dsc++;
+	}
+	return dsc->name;
+}
+
+static uint32_t extract_dc(unsigned short addr, int data)
+{
+	int valid, way;
+	unsigned char state;
+	uint64_t taglo, pa;
+	uint32_t taghi, taglolo, taglohi;
+	uint8_t ecc, lru;
+	int res = 0;
+
+	prom_printf("Dcache index 0x%04x  ", addr);
+	for (way = 0; way < 4; way++) {
+		__asm__ __volatile__ (
+		"	.set	push\n\t"
+		"	.set	noreorder\n\t"
+		"	.set	mips64\n\t"
+		"	.set	noat\n\t"
+		"	cache	5, 0(%3)\n\t"	/* Index-load-tag-D */
+		"	mfc0	%0, $29, 2\n\t"
+		"	dmfc0	$1, $28, 2\n\t"
+		"	dsrl32	%1, $1, 0\n\t"
+		"	sll	%2, $1, 0\n\t"
+		"	.set	pop"
+		: "=r" (taghi), "=r" (taglohi), "=r" (taglolo)
+		: "r" ((way << 13) | addr));
+
+		taglo = ((unsigned long long)taglohi << 32) | taglolo;
+		pa = (taglo & 0xFFFFFFE000ULL) | addr;
+		if (way == 0) {
+			lru = (taghi >> 14) & 0xff;
+			prom_printf("[Bank %d Set 0x%02x]  LRU > %d %d %d %d > MRU\n",
+				    ((addr >> 11) & 0x2) | ((addr >> 5) & 1), /* bank */
+				    ((addr >> 6) & 0x3f), /* index */
+				    (lru & 0x3),
+				    ((lru >> 2) & 0x3),
+				    ((lru >> 4) & 0x3),
+				    ((lru >> 6) & 0x3));
+		}
+		state = (taghi >> 25) & 0x1f;
+		valid = DC_TAG_VALID(state);
+		prom_printf(" %d  [PA %010llx]  [state %s (%02x)]  raw tags: %08X-%016llX\n",
+			    way, pa, dc_state_str(state), state, taghi, taglo);
+		if (valid) {
+			if (((taglo >> 11) & 1) ^ range_parity(taglo, 39, 26)) {
+				prom_printf("   ** bad parity in PTag1\n");
+				res |= CP0_CERRD_TAG_ADDRESS;
+			}
+			if (((taglo >> 10) & 1) ^ range_parity(taglo, 25, 13)) {
+				prom_printf("   ** bad parity in PTag0\n");
+				res |= CP0_CERRD_TAG_ADDRESS;
+			}
+		} else {
+			res |= CP0_CERRD_TAG_STATE;
+		}
+
+		if (data) {
+			uint64_t datalo;
+			uint32_t datalohi, datalolo, datahi;
+			int offset;
+
+			for (offset = 0; offset < 4; offset++) {
+				/* Index-load-data-D */
+				__asm__ __volatile__ (
+				"	.set	push\n\t"
+				"	.set	noreorder\n\t"
+				"	.set	mips64\n\t"
+				"	.set	noat\n\t"
+				"	cache	7, 0(%3)\n\t" /* Index-load-data-D */
+				"	mfc0	%0, $29, 3\n\t"
+				"	dmfc0	$1, $28, 3\n\t"
+				"	dsrl32	%1, $1, 0 \n\t"
+				"	sll	%2, $1, 0 \n\t"
+				"	.set	pop"
+				: "=r" (datahi), "=r" (datalohi), "=r" (datalolo)
+				: "r" ((way << 13) | addr | (offset << 3)));
+				datalo = ((unsigned long long)datalohi << 32) | datalolo;
+				ecc = dc_ecc(datalo);
+				if (ecc != datahi) {
+					int bits = 0;
+					prom_printf("  ** bad ECC (%02x %02x) ->",
+						    datahi, ecc);
+					ecc ^= datahi;
+					while (ecc) {
+						if (ecc & 1) bits++;
+						ecc >>= 1;
+					}
+					res |= (bits == 1) ? CP0_CERRD_DATA_SBE : CP0_CERRD_DATA_DBE;
+				}
+				prom_printf("  %02X-%016llX", datahi, datalo);
+			}
+			prom_printf("\n");
+		}
+	}
+	return res;
+}
diff --git a/arch/mips/mm/cex-gen.S b/arch/mips/mm/cex-gen.S
new file mode 100644
index 0000000..e743622
--- /dev/null
+++ b/arch/mips/mm/cex-gen.S
@@ -0,0 +1,42 @@
+/*
+ * 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 - 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ *
+ * Cache error handler
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+
+/*
+ * Game over.  Go to the button.  Press gently.  Swear where allowed by
+ * legislation.
+ */
+	LEAF(except_vec2_generic)
+	.set	noreorder
+	.set	noat
+	.set    mips0
+	/*
+	 * This is a very bad place to be.  Our cache error
+	 * detection has triggered.  If we have write-back data
+	 * in the cache, we may not be able to recover.  As a
+	 * first-order desperate measure, turn off KSEG0 cacheing.
+	 */
+	mfc0	k0,CP0_CONFIG
+	li	k1,~CONF_CM_CMASK
+	and	k0,k0,k1
+	ori	k0,k0,CONF_CM_UNCACHED
+	mtc0	k0,CP0_CONFIG
+	/* Give it a few cycles to sink in... */
+	nop
+	nop
+	nop
+
+	j	cache_parity_error
+	nop
+	END(except_vec2_generic)
diff --git a/arch/mips/mm/cex-sb1.S b/arch/mips/mm/cex-sb1.S
new file mode 100644
index 0000000..2c3a23a
--- /dev/null
+++ b/arch/mips/mm/cex-sb1.S
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2001,2002,2003 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+#include <linux/init.h>
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+#include <asm/cacheops.h>
+#include <asm/sibyte/board.h>
+
+#define C0_ERRCTL     $26             /* CP0: Error info */
+#define C0_CERR_I     $27             /* CP0: Icache error */
+#define C0_CERR_D     $27,1           /* CP0: Dcache error */
+
+	/*
+	 * Based on SiByte sample software cache-err/cerr.S
+	 * CVS revision 1.8.  Only the 'unrecoverable' case
+	 * is changed.
+	 */
+
+        __INIT
+
+	.set	mips64
+	.set	noreorder
+	.set	noat
+
+	/*
+	 * sb1_cerr_vec: code to be copied to the Cache Error
+	 * Exception vector.  The code must be pushed out to memory
+	 * (either by copying to Kseg0 and Kseg1 both, or by flushing
+	 * the L1 and L2) since it is fetched as 0xa0000100.
+	 *
+	 * NOTE: Be sure this handler is at most 28 instructions long
+	 * since the final 16 bytes of the exception vector memory
+	 * (0x170-0x17f) are used to preserve k0, k1, and ra.
+	 */
+
+LEAF(except_vec2_sb1)
+	/*
+	 * If this error is recoverable, we need to exit the handler
+	 * without having dirtied any registers.  To do this,
+	 * save/restore k0 and k1 from low memory (Useg is direct
+	 * mapped while ERL=1). Note that we can't save to a
+	 * CPU-specific location without ruining a register in the
+	 * process.  This means we are vulnerable to data corruption
+	 * whenever the handler is reentered by a second CPU.
+	 */
+	sd	k0,0x170($0)
+	sd	k1,0x178($0)
+
+	/*
+	 * M_ERRCTL_RECOVERABLE is bit 31, which makes it easy to tell
+	 * if we can fast-path out of here for a h/w-recovered error.
+	 */
+	mfc0	k1,C0_ERRCTL
+	bgtz	k1,attempt_recovery
+	 sll	k0,k1,1
+
+recovered_dcache:
+	/*
+	 * Unlock CacheErr-D (which in turn unlocks CacheErr-DPA).
+	 * Ought to log the occurence of this recovered dcache error.
+	 */
+	b	recovered
+	 mtc0	$0,C0_CERR_D
+
+attempt_recovery:
+	/*
+	 * k0 has C0_ERRCTL << 1, which puts 'DC' at bit 31.  Any
+	 * Dcache errors we can recover from will take more extensive
+	 * processing.  For now, they are considered "unrecoverable".
+	 * Note that 'DC' becoming set (outside of ERL mode) will
+	 * cause 'IC' to clear; so if there's an Icache error, we'll
+	 * only find out about it if we recover from this error and
+	 * continue executing.
+	 */
+	bltz	k0,unrecoverable
+	 sll	k0,1
+
+	/*
+	 * k0 has C0_ERRCTL << 2, which puts 'IC' at bit 31.  If an
+	 * Icache error isn't indicated, I'm not sure why we got here.
+	 * Consider that case "unrecoverable" for now.
+	 */
+	bgez	k0,unrecoverable
+
+attempt_icache_recovery:
+	/*
+	 * External icache errors are due to uncorrectable ECC errors
+	 * in the L2 cache or Memory Controller and cannot be
+	 * recovered here.
+	 */
+	 mfc0	k0,C0_CERR_I		/* delay slot */
+	li	k1,1 << 26		/* ICACHE_EXTERNAL */
+	and	k1,k0
+	bnez	k1,unrecoverable
+	 andi	k0,0x1fe0
+
+	/*
+	 * Since the error is internal, the 'IDX' field from
+	 * CacheErr-I is valid and we can just invalidate all blocks
+	 * in that set.
+	 */
+	cache	Index_Invalidate_I,(0<<13)(k0)
+	cache	Index_Invalidate_I,(1<<13)(k0)
+	cache	Index_Invalidate_I,(2<<13)(k0)
+	cache	Index_Invalidate_I,(3<<13)(k0)
+
+	/* Ought to log this recovered icache error */
+
+recovered:
+	/* Restore the saved registers */
+	ld	k0,0x170($0)
+	ld	k1,0x178($0)
+	eret
+
+unrecoverable:
+	/* Unrecoverable Icache or Dcache error; log it and/or fail */
+	j	handle_vec2_sb1
+	 nop
+
+END(except_vec2_sb1)
+
+	__FINIT
+
+	LEAF(handle_vec2_sb1)
+	mfc0	k0,CP0_CONFIG
+	li	k1,~CONF_CM_CMASK
+	and	k0,k0,k1
+	ori	k0,k0,CONF_CM_UNCACHED
+	mtc0	k0,CP0_CONFIG
+
+	SSNOP
+	SSNOP
+	SSNOP
+	SSNOP
+	bnezl	$0, 1f
+1:
+	mfc0	k0, CP0_STATUS
+	sll	k0, k0, 3			# check CU0 (kernel?)
+	bltz	k0, 2f
+	 nop
+
+	/* Get a valid Kseg0 stack pointer.  Any task's stack pointer
+	 * will do, although if we ever want to resume execution we
+	 * better not have corrupted any state. */
+	get_saved_sp
+	move	sp, k1
+
+2:
+	j	sb1_cache_error
+	 nop
+
+	END(handle_vec2_sb1)
diff --git a/arch/mips/mm/dma-coherent.c b/arch/mips/mm/dma-coherent.c
new file mode 100644
index 0000000..97a50d3
--- /dev/null
+++ b/arch/mips/mm/dma-coherent.c
@@ -0,0 +1,255 @@
+/*
+ * 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) 2000  Ani Joshi <ajoshi@unixbox.com>
+ * Copyright (C) 2000, 2001  Ralf Baechle <ralf@gnu.org>
+ * swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+
+#include <asm/cache.h>
+#include <asm/io.h>
+
+void *dma_alloc_noncoherent(struct device *dev, size_t size,
+	dma_addr_t * dma_handle, int gfp)
+{
+	void *ret;
+	/* ignore region specifiers */
+	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
+
+	if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
+		gfp |= GFP_DMA;
+	ret = (void *) __get_free_pages(gfp, get_order(size));
+
+	if (ret != NULL) {
+		memset(ret, 0, size);
+		*dma_handle = virt_to_phys(ret);
+	}
+
+	return ret;
+}
+
+EXPORT_SYMBOL(dma_alloc_noncoherent);
+
+void *dma_alloc_coherent(struct device *dev, size_t size,
+	dma_addr_t * dma_handle, int gfp)
+	__attribute__((alias("dma_alloc_noncoherent")));
+
+EXPORT_SYMBOL(dma_alloc_coherent);
+
+void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
+	dma_addr_t dma_handle)
+{
+	unsigned long addr = (unsigned long) vaddr;
+
+	free_pages(addr, get_order(size));
+}
+
+EXPORT_SYMBOL(dma_free_noncoherent);
+
+void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
+	dma_addr_t dma_handle) __attribute__((alias("dma_free_noncoherent")));
+
+EXPORT_SYMBOL(dma_free_coherent);
+
+dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
+	enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+
+	return __pa(ptr);
+}
+
+EXPORT_SYMBOL(dma_map_single);
+
+void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+		 enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+EXPORT_SYMBOL(dma_unmap_single);
+
+int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+	enum dma_data_direction direction)
+{
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	for (i = 0; i < nents; i++, sg++) {
+		sg->dma_address = (dma_addr_t)page_to_phys(sg->page) + sg->offset;
+	}
+
+	return nents;
+}
+
+EXPORT_SYMBOL(dma_map_sg);
+
+dma_addr_t dma_map_page(struct device *dev, struct page *page,
+	unsigned long offset, size_t size, enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+
+	return page_to_phys(page) + offset;
+}
+
+EXPORT_SYMBOL(dma_map_page);
+
+void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+	       enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+EXPORT_SYMBOL(dma_unmap_page);
+
+void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+	     enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+EXPORT_SYMBOL(dma_unmap_sg);
+
+void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
+	size_t size, enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+EXPORT_SYMBOL(dma_sync_single_for_cpu);
+
+void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
+	size_t size, enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+EXPORT_SYMBOL(dma_sync_single_for_device);
+
+void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
+		      unsigned long offset, size_t size,
+		      enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
+
+void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
+		      unsigned long offset, size_t size,
+		      enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+EXPORT_SYMBOL(dma_sync_single_range_for_device);
+
+void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+		 enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+EXPORT_SYMBOL(dma_sync_sg_for_cpu);
+
+void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
+		 enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+EXPORT_SYMBOL(dma_sync_sg_for_device);
+
+int dma_mapping_error(dma_addr_t dma_addr)
+{
+	return 0;
+}
+
+EXPORT_SYMBOL(dma_mapping_error);
+
+int dma_supported(struct device *dev, u64 mask)
+{
+	/*
+	 * we fall back to GFP_DMA when the mask isn't all 1s,
+	 * so we can't guarantee allocations that must be
+	 * within a tighter range than GFP_DMA..
+	 */
+	if (mask < 0x00ffffff)
+		return 0;
+
+	return 1;
+}
+
+EXPORT_SYMBOL(dma_supported);
+
+int dma_is_consistent(dma_addr_t dma_addr)
+{
+	return 1;
+}
+
+EXPORT_SYMBOL(dma_is_consistent);
+
+void dma_cache_sync(void *vaddr, size_t size,
+	       enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+EXPORT_SYMBOL(dma_cache_sync);
+
+/* The DAC routines are a PCIism.. */
+
+#ifdef CONFIG_PCI
+
+#include <linux/pci.h>
+
+dma64_addr_t pci_dac_page_to_dma(struct pci_dev *pdev,
+	struct page *page, unsigned long offset, int direction)
+{
+	return (dma64_addr_t)page_to_phys(page) + offset;
+}
+
+EXPORT_SYMBOL(pci_dac_page_to_dma);
+
+struct page *pci_dac_dma_to_page(struct pci_dev *pdev,
+	dma64_addr_t dma_addr)
+{
+	return mem_map + (dma_addr >> PAGE_SHIFT);
+}
+
+EXPORT_SYMBOL(pci_dac_dma_to_page);
+
+unsigned long pci_dac_dma_to_offset(struct pci_dev *pdev,
+	dma64_addr_t dma_addr)
+{
+	return dma_addr & ~PAGE_MASK;
+}
+
+EXPORT_SYMBOL(pci_dac_dma_to_offset);
+
+void pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev,
+	dma64_addr_t dma_addr, size_t len, int direction)
+{
+	BUG_ON(direction == PCI_DMA_NONE);
+}
+
+EXPORT_SYMBOL(pci_dac_dma_sync_single_for_cpu);
+
+void pci_dac_dma_sync_single_for_device(struct pci_dev *pdev,
+	dma64_addr_t dma_addr, size_t len, int direction)
+{
+	BUG_ON(direction == PCI_DMA_NONE);
+}
+
+EXPORT_SYMBOL(pci_dac_dma_sync_single_for_device);
+
+#endif /* CONFIG_PCI */
diff --git a/arch/mips/mm/dma-ip27.c b/arch/mips/mm/dma-ip27.c
new file mode 100644
index 0000000..aa7c94b
--- /dev/null
+++ b/arch/mips/mm/dma-ip27.c
@@ -0,0 +1,257 @@
+/*
+ * 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) 2000  Ani Joshi <ajoshi@unixbox.com>
+ * Copyright (C) 2000, 2001  Ralf Baechle <ralf@gnu.org>
+ * swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
+ */
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+
+#include <asm/cache.h>
+#include <asm/pci/bridge.h>
+
+#define pdev_to_baddr(pdev, addr) \
+	(BRIDGE_CONTROLLER(pdev->bus)->baddr + (addr))
+#define dev_to_baddr(dev, addr) \
+	pdev_to_baddr(to_pci_dev(dev), (addr))
+
+void *dma_alloc_noncoherent(struct device *dev, size_t size,
+	dma_addr_t * dma_handle, int gfp)
+{
+	void *ret;
+
+	/* ignore region specifiers */
+	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
+
+	if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
+		gfp |= GFP_DMA;
+	ret = (void *) __get_free_pages(gfp, get_order(size));
+
+	if (ret != NULL) {
+		memset(ret, 0, size);
+		*dma_handle = dev_to_baddr(dev, virt_to_phys(ret));
+	}
+
+	return ret;
+}
+
+EXPORT_SYMBOL(dma_alloc_noncoherent);
+
+void *dma_alloc_coherent(struct device *dev, size_t size,
+	dma_addr_t * dma_handle, int gfp)
+	__attribute__((alias("dma_alloc_noncoherent")));
+
+EXPORT_SYMBOL(dma_alloc_coherent);
+
+void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
+	dma_addr_t dma_handle)
+{
+	unsigned long addr = (unsigned long) vaddr;
+
+	free_pages(addr, get_order(size));
+}
+
+EXPORT_SYMBOL(dma_free_noncoherent);
+
+void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
+	dma_addr_t dma_handle) __attribute__((alias("dma_free_noncoherent")));
+
+EXPORT_SYMBOL(dma_free_coherent);
+
+dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
+	enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+
+	return dev_to_baddr(dev, __pa(ptr));
+}
+
+EXPORT_SYMBOL(dma_map_single);
+
+void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+		 enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+EXPORT_SYMBOL(dma_unmap_single);
+
+int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+	enum dma_data_direction direction)
+{
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	for (i = 0; i < nents; i++, sg++) {
+		sg->dma_address = (dma_addr_t) dev_to_baddr(dev,
+			page_to_phys(sg->page) + sg->offset);
+	}
+
+	return nents;
+}
+
+EXPORT_SYMBOL(dma_map_sg);
+
+dma_addr_t dma_map_page(struct device *dev, struct page *page,
+	unsigned long offset, size_t size, enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+
+	return dev_to_baddr(dev, page_to_phys(page) + offset);
+}
+
+EXPORT_SYMBOL(dma_map_page);
+
+void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+	       enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+EXPORT_SYMBOL(dma_unmap_page);
+
+void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+	     enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+EXPORT_SYMBOL(dma_unmap_sg);
+
+void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
+		enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+EXPORT_SYMBOL(dma_sync_single_for_cpu);
+
+void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
+		enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+EXPORT_SYMBOL(dma_sync_single_for_device);
+
+void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
+		      unsigned long offset, size_t size,
+		      enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
+
+void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
+		      unsigned long offset, size_t size,
+		      enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+EXPORT_SYMBOL(dma_sync_single_range_for_device);
+
+void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+		 enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+EXPORT_SYMBOL(dma_sync_sg_for_cpu);
+
+void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
+		 enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+EXPORT_SYMBOL(dma_sync_sg_for_device);
+
+int dma_mapping_error(dma_addr_t dma_addr)
+{
+	return 0;
+}
+
+EXPORT_SYMBOL(dma_mapping_error);
+
+int dma_supported(struct device *dev, u64 mask)
+{
+	/*
+	 * we fall back to GFP_DMA when the mask isn't all 1s,
+	 * so we can't guarantee allocations that must be
+	 * within a tighter range than GFP_DMA..
+	 */
+	if (mask < 0x00ffffff)
+		return 0;
+
+	return 1;
+}
+
+EXPORT_SYMBOL(dma_supported);
+
+int dma_is_consistent(dma_addr_t dma_addr)
+{
+	return 1;
+}
+
+EXPORT_SYMBOL(dma_is_consistent);
+
+void dma_cache_sync(void *vaddr, size_t size,
+	       enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+EXPORT_SYMBOL(dma_cache_sync);
+
+dma64_addr_t pci_dac_page_to_dma(struct pci_dev *pdev,
+	struct page *page, unsigned long offset, int direction)
+{
+	dma64_addr_t addr = page_to_phys(page) + offset;
+
+	return (dma64_addr_t) pdev_to_baddr(pdev, addr);
+}
+
+EXPORT_SYMBOL(pci_dac_page_to_dma);
+
+struct page *pci_dac_dma_to_page(struct pci_dev *pdev,
+	dma64_addr_t dma_addr)
+{
+	struct bridge_controller *bc = BRIDGE_CONTROLLER(pdev->bus);
+
+	return pfn_to_page((dma_addr - bc->baddr) >> PAGE_SHIFT);
+}
+
+EXPORT_SYMBOL(pci_dac_dma_to_page);
+
+unsigned long pci_dac_dma_to_offset(struct pci_dev *pdev,
+	dma64_addr_t dma_addr)
+{
+	return dma_addr & ~PAGE_MASK;
+}
+
+EXPORT_SYMBOL(pci_dac_dma_to_offset);
+
+void pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev,
+	dma64_addr_t dma_addr, size_t len, int direction)
+{
+	BUG_ON(direction == PCI_DMA_NONE);
+}
+
+EXPORT_SYMBOL(pci_dac_dma_sync_single_for_cpu);
+
+void pci_dac_dma_sync_single_for_device(struct pci_dev *pdev,
+	dma64_addr_t dma_addr, size_t len, int direction)
+{
+	BUG_ON(direction == PCI_DMA_NONE);
+}
+
+EXPORT_SYMBOL(pci_dac_dma_sync_single_for_device);
diff --git a/arch/mips/mm/dma-ip32.c b/arch/mips/mm/dma-ip32.c
new file mode 100644
index 0000000..2cbe196
--- /dev/null
+++ b/arch/mips/mm/dma-ip32.c
@@ -0,0 +1,382 @@
+/*
+ * 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) 2000  Ani Joshi <ajoshi@unixbox.com>
+ * Copyright (C) 2000, 2001  Ralf Baechle <ralf@gnu.org>
+ * Copyright (C) 2005 Ilya A. Volynets-Evenbakh <ilya@total-knowledge.com>
+ * swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
+ * IP32 changes by Ilya.
+ */
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/cache.h>
+#include <asm/io.h>
+#include <asm/ip32/crime.h>
+
+/*
+ * Warning on the terminology - Linux calls an uncached area coherent;
+ * MIPS terminology calls memory areas with hardware maintained coherency
+ * coherent.
+ */
+
+/*
+ * Few notes.
+ * 1. CPU sees memory as two chunks: 0-256M@0x0, and the rest @0x40000000+256M
+ * 2. PCI sees memory as one big chunk @0x0 (or we could use 0x40000000 for native-endian)
+ * 3. All other devices see memory as one big chunk at 0x40000000
+ * 4. Non-PCI devices will pass NULL as struct device*
+ * Thus we translate differently, depending on device.
+ */
+
+#define RAM_OFFSET_MASK	0x3fffffff
+
+void *dma_alloc_noncoherent(struct device *dev, size_t size,
+	dma_addr_t * dma_handle, int gfp)
+{
+	void *ret;
+	/* ignore region specifiers */
+	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
+
+	if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
+		gfp |= GFP_DMA;
+	ret = (void *) __get_free_pages(gfp, get_order(size));
+
+	if (ret != NULL) {
+		unsigned long addr = virt_to_phys(ret)&RAM_OFFSET_MASK;
+		memset(ret, 0, size);
+		if(dev==NULL)
+		    addr+= CRIME_HI_MEM_BASE;
+		*dma_handle = addr;
+	}
+
+	return ret;
+}
+
+EXPORT_SYMBOL(dma_alloc_noncoherent);
+
+void *dma_alloc_coherent(struct device *dev, size_t size,
+	dma_addr_t * dma_handle, int gfp)
+{
+	void *ret;
+
+	ret = dma_alloc_noncoherent(dev, size, dma_handle, gfp);
+	if (ret) {
+		dma_cache_wback_inv((unsigned long) ret, size);
+		ret = UNCAC_ADDR(ret);
+	}
+
+	return ret;
+}
+
+EXPORT_SYMBOL(dma_alloc_coherent);
+
+void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
+	dma_addr_t dma_handle)
+{
+	free_pages((unsigned long) vaddr, get_order(size));
+}
+
+EXPORT_SYMBOL(dma_free_noncoherent);
+
+void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
+	dma_addr_t dma_handle)
+{
+	unsigned long addr = (unsigned long) vaddr;
+
+	addr = CAC_ADDR(addr);
+	free_pages(addr, get_order(size));
+}
+
+EXPORT_SYMBOL(dma_free_coherent);
+
+static inline void __dma_sync(unsigned long addr, size_t size,
+	enum dma_data_direction direction)
+{
+	switch (direction) {
+	case DMA_TO_DEVICE:
+		dma_cache_wback(addr, size);
+		break;
+
+	case DMA_FROM_DEVICE:
+		dma_cache_inv(addr, size);
+		break;
+
+	case DMA_BIDIRECTIONAL:
+		dma_cache_wback_inv(addr, size);
+		break;
+
+	default:
+		BUG();
+	}
+}
+
+dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
+	enum dma_data_direction direction)
+{
+	unsigned long addr = (unsigned long) ptr;
+
+	switch (direction) {
+	case DMA_TO_DEVICE:
+		dma_cache_wback(addr, size);
+		break;
+
+	case DMA_FROM_DEVICE:
+		dma_cache_inv(addr, size);
+		break;
+
+	case DMA_BIDIRECTIONAL:
+		dma_cache_wback_inv(addr, size);
+		break;
+
+	default:
+		BUG();
+	}
+
+	addr = virt_to_phys(ptr)&RAM_OFFSET_MASK;;
+	if(dev == NULL)
+	    addr+=CRIME_HI_MEM_BASE;
+	return (dma_addr_t)addr;
+}
+
+EXPORT_SYMBOL(dma_map_single);
+
+void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+	enum dma_data_direction direction)
+{
+	switch (direction) {
+	case DMA_TO_DEVICE:
+		break;
+
+	case DMA_FROM_DEVICE:
+		break;
+
+	case DMA_BIDIRECTIONAL:
+		break;
+
+	default:
+		BUG();
+	}
+}
+
+EXPORT_SYMBOL(dma_unmap_single);
+
+int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+	enum dma_data_direction direction)
+{
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	for (i = 0; i < nents; i++, sg++) {
+		unsigned long addr;
+
+		addr = (unsigned long) page_address(sg->page)+sg->offset;
+		if (addr)
+			__dma_sync(addr, sg->length, direction);
+		addr = __pa(addr)&RAM_OFFSET_MASK;;
+		if(dev == NULL)
+			addr +=  CRIME_HI_MEM_BASE;
+		sg->dma_address = (dma_addr_t)addr;
+	}
+
+	return nents;
+}
+
+EXPORT_SYMBOL(dma_map_sg);
+
+dma_addr_t dma_map_page(struct device *dev, struct page *page,
+	unsigned long offset, size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	addr = (unsigned long) page_address(page) + offset;
+	dma_cache_wback_inv(addr, size);
+	addr = __pa(addr)&RAM_OFFSET_MASK;;
+	if(dev == NULL)
+		addr +=  CRIME_HI_MEM_BASE;
+
+	return (dma_addr_t)addr;
+}
+
+EXPORT_SYMBOL(dma_map_page);
+
+void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+	enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+
+	if (direction != DMA_TO_DEVICE) {
+		unsigned long addr;
+
+		dma_address&=RAM_OFFSET_MASK;
+		addr = dma_address + PAGE_OFFSET;
+		if(dma_address>=256*1024*1024)
+			addr+=CRIME_HI_MEM_BASE;
+		dma_cache_wback_inv(addr, size);
+	}
+}
+
+EXPORT_SYMBOL(dma_unmap_page);
+
+void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+	enum dma_data_direction direction)
+{
+	unsigned long addr;
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	if (direction == DMA_TO_DEVICE)
+		return;
+
+	for (i = 0; i < nhwentries; i++, sg++) {
+		addr = (unsigned long) page_address(sg->page);
+		if (!addr)
+			continue;
+		dma_cache_wback_inv(addr + sg->offset, sg->length);
+	}
+}
+
+EXPORT_SYMBOL(dma_unmap_sg);
+
+void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
+	size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	dma_handle&=RAM_OFFSET_MASK;
+	addr = dma_handle + PAGE_OFFSET;
+	if(dma_handle>=256*1024*1024)
+	    addr+=CRIME_HI_MEM_BASE;
+	__dma_sync(addr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_single_for_cpu);
+
+void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
+	size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	dma_handle&=RAM_OFFSET_MASK;
+	addr = dma_handle + PAGE_OFFSET;
+	if(dma_handle>=256*1024*1024)
+	    addr+=CRIME_HI_MEM_BASE;
+	__dma_sync(addr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_single_for_device);
+
+void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
+	unsigned long offset, size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	dma_handle&=RAM_OFFSET_MASK;
+	addr = dma_handle + offset + PAGE_OFFSET;
+	if(dma_handle>=256*1024*1024)
+	    addr+=CRIME_HI_MEM_BASE;
+	__dma_sync(addr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
+
+void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
+	unsigned long offset, size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	dma_handle&=RAM_OFFSET_MASK;
+	addr = dma_handle + offset + PAGE_OFFSET;
+	if(dma_handle>=256*1024*1024)
+	    addr+=CRIME_HI_MEM_BASE;
+	__dma_sync(addr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_single_range_for_device);
+
+void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+	enum dma_data_direction direction)
+{
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	/* Make sure that gcc doesn't leave the empty loop body.  */
+	for (i = 0; i < nelems; i++, sg++)
+		__dma_sync((unsigned long)page_address(sg->page),
+		           sg->length, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_sg_for_cpu);
+
+void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
+	enum dma_data_direction direction)
+{
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	/* Make sure that gcc doesn't leave the empty loop body.  */
+	for (i = 0; i < nelems; i++, sg++)
+		__dma_sync((unsigned long)page_address(sg->page),
+		           sg->length, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_sg_for_device);
+
+int dma_mapping_error(dma_addr_t dma_addr)
+{
+	return 0;
+}
+
+EXPORT_SYMBOL(dma_mapping_error);
+
+int dma_supported(struct device *dev, u64 mask)
+{
+	/*
+	 * we fall back to GFP_DMA when the mask isn't all 1s,
+	 * so we can't guarantee allocations that must be
+	 * within a tighter range than GFP_DMA..
+	 */
+	if (mask < 0x00ffffff)
+		return 0;
+
+	return 1;
+}
+
+EXPORT_SYMBOL(dma_supported);
+
+int dma_is_consistent(dma_addr_t dma_addr)
+{
+	return 1;
+}
+
+EXPORT_SYMBOL(dma_is_consistent);
+
+void dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction)
+{
+	if (direction == DMA_NONE)
+		return;
+
+	dma_cache_wback_inv((unsigned long)vaddr, size);
+}
+
+EXPORT_SYMBOL(dma_cache_sync);
+
diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
new file mode 100644
index 0000000..9895e32
--- /dev/null
+++ b/arch/mips/mm/dma-noncoherent.c
@@ -0,0 +1,400 @@
+/*
+ * 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) 2000  Ani Joshi <ajoshi@unixbox.com>
+ * Copyright (C) 2000, 2001  Ralf Baechle <ralf@gnu.org>
+ * swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/cache.h>
+#include <asm/io.h>
+
+/*
+ * Warning on the terminology - Linux calls an uncached area coherent;
+ * MIPS terminology calls memory areas with hardware maintained coherency
+ * coherent.
+ */
+
+void *dma_alloc_noncoherent(struct device *dev, size_t size,
+	dma_addr_t * dma_handle, int gfp)
+{
+	void *ret;
+	/* ignore region specifiers */
+	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
+
+	if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
+		gfp |= GFP_DMA;
+	ret = (void *) __get_free_pages(gfp, get_order(size));
+
+	if (ret != NULL) {
+		memset(ret, 0, size);
+		*dma_handle = virt_to_phys(ret);
+	}
+
+	return ret;
+}
+
+EXPORT_SYMBOL(dma_alloc_noncoherent);
+
+void *dma_alloc_coherent(struct device *dev, size_t size,
+	dma_addr_t * dma_handle, int gfp)
+{
+	void *ret;
+
+	ret = dma_alloc_noncoherent(dev, size, dma_handle, gfp);
+	if (ret) {
+		dma_cache_wback_inv((unsigned long) ret, size);
+		ret = UNCAC_ADDR(ret);
+	}
+
+	return ret;
+}
+
+EXPORT_SYMBOL(dma_alloc_coherent);
+
+void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
+	dma_addr_t dma_handle)
+{
+	free_pages((unsigned long) vaddr, get_order(size));
+}
+
+EXPORT_SYMBOL(dma_free_noncoherent);
+
+void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
+	dma_addr_t dma_handle)
+{
+	unsigned long addr = (unsigned long) vaddr;
+
+	addr = CAC_ADDR(addr);
+	free_pages(addr, get_order(size));
+}
+
+EXPORT_SYMBOL(dma_free_coherent);
+
+static inline void __dma_sync(unsigned long addr, size_t size,
+	enum dma_data_direction direction)
+{
+	switch (direction) {
+	case DMA_TO_DEVICE:
+		dma_cache_wback(addr, size);
+		break;
+
+	case DMA_FROM_DEVICE:
+		dma_cache_inv(addr, size);
+		break;
+
+	case DMA_BIDIRECTIONAL:
+		dma_cache_wback_inv(addr, size);
+		break;
+
+	default:
+		BUG();
+	}
+}
+
+dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
+	enum dma_data_direction direction)
+{
+	unsigned long addr = (unsigned long) ptr;
+
+	switch (direction) {
+	case DMA_TO_DEVICE:
+		dma_cache_wback(addr, size);
+		break;
+
+	case DMA_FROM_DEVICE:
+		dma_cache_inv(addr, size);
+		break;
+
+	case DMA_BIDIRECTIONAL:
+		dma_cache_wback_inv(addr, size);
+		break;
+
+	default:
+		BUG();
+	}
+
+	return virt_to_phys(ptr);
+}
+
+EXPORT_SYMBOL(dma_map_single);
+
+void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+	enum dma_data_direction direction)
+{
+	unsigned long addr;
+	addr = dma_addr + PAGE_OFFSET;
+
+	switch (direction) {
+	case DMA_TO_DEVICE:
+		//dma_cache_wback(addr, size);
+		break;
+
+	case DMA_FROM_DEVICE:
+		//dma_cache_inv(addr, size);
+		break;
+
+	case DMA_BIDIRECTIONAL:
+		//dma_cache_wback_inv(addr, size);
+		break;
+
+	default:
+		BUG();
+	}
+}
+
+EXPORT_SYMBOL(dma_unmap_single);
+
+int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+	enum dma_data_direction direction)
+{
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	for (i = 0; i < nents; i++, sg++) {
+		unsigned long addr;
+ 
+		addr = (unsigned long) page_address(sg->page);
+		if (addr)
+			__dma_sync(addr + sg->offset, sg->length, direction);
+		sg->dma_address = (dma_addr_t)
+			(page_to_phys(sg->page) + sg->offset);
+	}
+
+	return nents;
+}
+
+EXPORT_SYMBOL(dma_map_sg);
+
+dma_addr_t dma_map_page(struct device *dev, struct page *page,
+	unsigned long offset, size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	addr = (unsigned long) page_address(page) + offset;
+	dma_cache_wback_inv(addr, size);
+
+	return page_to_phys(page) + offset;
+}
+
+EXPORT_SYMBOL(dma_map_page);
+
+void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+	enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+
+	if (direction != DMA_TO_DEVICE) {
+		unsigned long addr;
+
+		addr = dma_address + PAGE_OFFSET;
+		dma_cache_wback_inv(addr, size);
+	}
+}
+
+EXPORT_SYMBOL(dma_unmap_page);
+
+void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+	enum dma_data_direction direction)
+{
+	unsigned long addr;
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	if (direction == DMA_TO_DEVICE)
+		return;
+
+	for (i = 0; i < nhwentries; i++, sg++) {
+		addr = (unsigned long) page_address(sg->page);
+		if (!addr)
+			continue;
+		dma_cache_wback_inv(addr + sg->offset, sg->length);
+	}
+}
+
+EXPORT_SYMBOL(dma_unmap_sg);
+
+void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
+	size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+ 
+	BUG_ON(direction == DMA_NONE);
+ 
+	addr = dma_handle + PAGE_OFFSET;
+	__dma_sync(addr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_single_for_cpu);
+
+void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
+	size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	addr = dma_handle + PAGE_OFFSET;
+	__dma_sync(addr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_single_for_device);
+
+void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
+	unsigned long offset, size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	addr = dma_handle + offset + PAGE_OFFSET;
+	__dma_sync(addr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
+
+void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
+	unsigned long offset, size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	addr = dma_handle + offset + PAGE_OFFSET;
+	__dma_sync(addr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_single_range_for_device);
+
+void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+	enum dma_data_direction direction)
+{
+	int i;
+ 
+	BUG_ON(direction == DMA_NONE);
+ 
+	/* Make sure that gcc doesn't leave the empty loop body.  */
+	for (i = 0; i < nelems; i++, sg++)
+		__dma_sync((unsigned long)page_address(sg->page),
+		           sg->length, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_sg_for_cpu);
+
+void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
+	enum dma_data_direction direction)
+{
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	/* Make sure that gcc doesn't leave the empty loop body.  */
+	for (i = 0; i < nelems; i++, sg++)
+		__dma_sync((unsigned long)page_address(sg->page),
+		           sg->length, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_sg_for_device);
+
+int dma_mapping_error(dma_addr_t dma_addr)
+{
+	return 0;
+}
+
+EXPORT_SYMBOL(dma_mapping_error);
+
+int dma_supported(struct device *dev, u64 mask)
+{
+	/*
+	 * we fall back to GFP_DMA when the mask isn't all 1s,
+	 * so we can't guarantee allocations that must be
+	 * within a tighter range than GFP_DMA..
+	 */
+	if (mask < 0x00ffffff)
+		return 0;
+
+	return 1;
+}
+
+EXPORT_SYMBOL(dma_supported);
+
+int dma_is_consistent(dma_addr_t dma_addr)
+{
+	return 1;
+}
+
+EXPORT_SYMBOL(dma_is_consistent);
+
+void dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction)
+{
+	if (direction == DMA_NONE)
+		return;
+
+	dma_cache_wback_inv((unsigned long)vaddr, size);
+}
+
+EXPORT_SYMBOL(dma_cache_sync);
+
+/* The DAC routines are a PCIism.. */
+
+#ifdef CONFIG_PCI
+
+#include <linux/pci.h>
+
+dma64_addr_t pci_dac_page_to_dma(struct pci_dev *pdev,
+	struct page *page, unsigned long offset, int direction)
+{
+	return (dma64_addr_t)page_to_phys(page) + offset;
+}
+
+EXPORT_SYMBOL(pci_dac_page_to_dma);
+
+struct page *pci_dac_dma_to_page(struct pci_dev *pdev,
+	dma64_addr_t dma_addr)
+{
+	return mem_map + (dma_addr >> PAGE_SHIFT);
+}
+
+EXPORT_SYMBOL(pci_dac_dma_to_page);
+
+unsigned long pci_dac_dma_to_offset(struct pci_dev *pdev,
+	dma64_addr_t dma_addr)
+{
+	return dma_addr & ~PAGE_MASK;
+}
+
+EXPORT_SYMBOL(pci_dac_dma_to_offset);
+
+void pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev,
+	dma64_addr_t dma_addr, size_t len, int direction)
+{
+	BUG_ON(direction == PCI_DMA_NONE);
+
+	dma_cache_wback_inv(dma_addr + PAGE_OFFSET, len);
+}
+
+EXPORT_SYMBOL(pci_dac_dma_sync_single_for_cpu);
+
+void pci_dac_dma_sync_single_for_device(struct pci_dev *pdev,
+	dma64_addr_t dma_addr, size_t len, int direction)
+{
+	BUG_ON(direction == PCI_DMA_NONE);
+
+	dma_cache_wback_inv(dma_addr + PAGE_OFFSET, len);
+}
+
+EXPORT_SYMBOL(pci_dac_dma_sync_single_for_device);
+
+#endif /* CONFIG_PCI */
diff --git a/arch/mips/mm/extable.c b/arch/mips/mm/extable.c
new file mode 100644
index 0000000..297fb9f
--- /dev/null
+++ b/arch/mips/mm/extable.c
@@ -0,0 +1,21 @@
+/*
+ * linux/arch/mips/mm/extable.c
+ */
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <asm/branch.h>
+#include <asm/uaccess.h>
+
+int fixup_exception(struct pt_regs *regs)
+{
+	const struct exception_table_entry *fixup;
+
+	fixup = search_exception_tables(exception_epc(regs));
+	if (fixup) {
+		regs->cp0_epc = fixup->nextinsn;
+
+		return 1;
+	}
+
+	return 0;
+}
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
new file mode 100644
index 0000000..ec8077c
--- /dev/null
+++ b/arch/mips/mm/fault.c
@@ -0,0 +1,236 @@
+/*
+ * 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 - 2000 by Ralf Baechle
+ */
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/vt_kern.h>		/* For unblank_screen() */
+#include <linux/module.h>
+
+#include <asm/branch.h>
+#include <asm/mmu_context.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/ptrace.h>
+
+/*
+ * This routine handles page faults.  It determines the address,
+ * and the problem, and then passes it off to one of the appropriate
+ * routines.
+ */
+asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
+			      unsigned long address)
+{
+	struct vm_area_struct * vma = NULL;
+	struct task_struct *tsk = current;
+	struct mm_struct *mm = tsk->mm;
+	const int field = sizeof(unsigned long) * 2;
+	siginfo_t info;
+
+#if 0
+	printk("Cpu%d[%s:%d:%0*lx:%ld:%0*lx]\n", smp_processor_id(),
+	       current->comm, current->pid, field, address, write,
+	       field, regs->cp0_epc);
+#endif
+
+	info.si_code = SEGV_MAPERR;
+
+	/*
+	 * We fault-in kernel-space virtual memory on-demand. The
+	 * 'reference' page table is init_mm.pgd.
+	 *
+	 * NOTE! We MUST NOT take any locks for this case. We may
+	 * be in an interrupt or a critical region, and should
+	 * only copy the information from the master page table,
+	 * nothing more.
+	 */
+	if (unlikely(address >= VMALLOC_START))
+		goto vmalloc_fault;
+
+	/*
+	 * If we're in an interrupt or have no user
+	 * context, we must not take the fault..
+	 */
+	if (in_atomic() || !mm)
+		goto bad_area_nosemaphore;
+
+	down_read(&mm->mmap_sem);
+	vma = find_vma(mm, address);
+	if (!vma)
+		goto bad_area;
+	if (vma->vm_start <= address)
+		goto good_area;
+	if (!(vma->vm_flags & VM_GROWSDOWN))
+		goto bad_area;
+	if (expand_stack(vma, address))
+		goto bad_area;
+/*
+ * Ok, we have a good vm_area for this memory access, so
+ * we can handle it..
+ */
+good_area:
+	info.si_code = SEGV_ACCERR;
+
+	if (write) {
+		if (!(vma->vm_flags & VM_WRITE))
+			goto bad_area;
+	} else {
+		if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+			goto bad_area;
+	}
+
+survive:
+	/*
+	 * If for any reason at all we couldn't handle the fault,
+	 * make sure we exit gracefully rather than endlessly redo
+	 * the fault.
+	 */
+	switch (handle_mm_fault(mm, vma, address, write)) {
+	case VM_FAULT_MINOR:
+		tsk->min_flt++;
+		break;
+	case VM_FAULT_MAJOR:
+		tsk->maj_flt++;
+		break;
+	case VM_FAULT_SIGBUS:
+		goto do_sigbus;
+	case VM_FAULT_OOM:
+		goto out_of_memory;
+	default:
+		BUG();
+	}
+
+	up_read(&mm->mmap_sem);
+	return;
+
+/*
+ * Something tried to access memory that isn't in our memory map..
+ * Fix it, but check if it's kernel or user first..
+ */
+bad_area:
+	up_read(&mm->mmap_sem);
+
+bad_area_nosemaphore:
+	/* User mode accesses just cause a SIGSEGV */
+	if (user_mode(regs)) {
+		tsk->thread.cp0_badvaddr = address;
+		tsk->thread.error_code = write;
+#if 0
+		printk("do_page_fault() #2: sending SIGSEGV to %s for "
+		       "invalid %s\n%0*lx (epc == %0*lx, ra == %0*lx)\n",
+		       tsk->comm,
+		       write ? "write access to" : "read access from",
+		       field, address,
+		       field, (unsigned long) regs->cp0_epc,
+		       field, (unsigned long) regs->regs[31]);
+#endif
+		info.si_signo = SIGSEGV;
+		info.si_errno = 0;
+		/* info.si_code has been set above */
+		info.si_addr = (void *) address;
+		force_sig_info(SIGSEGV, &info, tsk);
+		return;
+	}
+
+no_context:
+	/* Are we prepared to handle this kernel fault?  */
+	if (fixup_exception(regs)) {
+		current->thread.cp0_baduaddr = address;
+		return;
+	}
+
+	/*
+	 * Oops. The kernel tried to access some bad page. We'll have to
+	 * terminate things with extreme prejudice.
+	 */
+
+	bust_spinlocks(1);
+
+	printk(KERN_ALERT "CPU %d Unable to handle kernel paging request at "
+	       "virtual address %0*lx, epc == %0*lx, ra == %0*lx\n",
+	       smp_processor_id(), field, address, field, regs->cp0_epc,
+	       field,  regs->regs[31]);
+	die("Oops", regs);
+
+/*
+ * We ran out of memory, or some other thing happened to us that made
+ * us unable to handle the page fault gracefully.
+ */
+out_of_memory:
+	up_read(&mm->mmap_sem);
+	if (tsk->pid == 1) {
+		yield();
+		down_read(&mm->mmap_sem);
+		goto survive;
+	}
+	printk("VM: killing process %s\n", tsk->comm);
+	if (user_mode(regs))
+		do_exit(SIGKILL);
+	goto no_context;
+
+do_sigbus:
+	up_read(&mm->mmap_sem);
+
+	/* Kernel mode? Handle exceptions or die */
+	if (!user_mode(regs))
+		goto no_context;
+
+	/*
+	 * Send a sigbus, regardless of whether we were in kernel
+	 * or user mode.
+	 */
+	tsk->thread.cp0_badvaddr = address;
+	info.si_signo = SIGBUS;
+	info.si_errno = 0;
+	info.si_code = BUS_ADRERR;
+	info.si_addr = (void *) address;
+	force_sig_info(SIGBUS, &info, tsk);
+
+	return;
+
+vmalloc_fault:
+	{
+		/*
+		 * Synchronize this task's top level page-table
+		 * with the 'reference' page table.
+		 *
+		 * Do _not_ use "tsk" here. We might be inside
+		 * an interrupt in the middle of a task switch..
+		 */
+		int offset = __pgd_offset(address);
+		pgd_t *pgd, *pgd_k;
+		pmd_t *pmd, *pmd_k;
+		pte_t *pte_k;
+
+		pgd = (pgd_t *) pgd_current[smp_processor_id()] + offset;
+		pgd_k = init_mm.pgd + offset;
+
+		if (!pgd_present(*pgd_k))
+			goto no_context;
+		set_pgd(pgd, *pgd_k);
+
+		pmd = pmd_offset(pgd, address);
+		pmd_k = pmd_offset(pgd_k, address);
+		if (!pmd_present(*pmd_k))
+			goto no_context;
+		set_pmd(pmd, *pmd_k);
+
+		pte_k = pte_offset_kernel(pmd_k, address);
+		if (!pte_present(*pte_k))
+			goto no_context;
+		return;
+	}
+}
diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c
new file mode 100644
index 0000000..dd5e2e3
--- /dev/null
+++ b/arch/mips/mm/highmem.c
@@ -0,0 +1,103 @@
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/highmem.h>
+#include <asm/tlbflush.h>
+
+void *__kmap(struct page *page)
+{
+	void *addr;
+
+	might_sleep();
+	if (!PageHighMem(page))
+		return page_address(page);
+	addr = kmap_high(page);
+	flush_tlb_one((unsigned long)addr);
+
+	return addr;
+}
+
+void __kunmap(struct page *page)
+{
+	if (in_interrupt())
+		BUG();
+	if (!PageHighMem(page))
+		return;
+	kunmap_high(page);
+}
+
+/*
+ * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because
+ * no global lock is needed and because the kmap code must perform a global TLB
+ * invalidation when the kmap pool wraps.
+ *
+ * However when holding an atomic kmap is is not legal to sleep, so atomic
+ * kmaps are appropriate for short, tight code paths only.
+ */
+
+void *__kmap_atomic(struct page *page, enum km_type type)
+{
+	enum fixed_addresses idx;
+	unsigned long vaddr;
+
+	/* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
+	inc_preempt_count();
+	if (!PageHighMem(page))
+		return page_address(page);
+
+	idx = type + KM_TYPE_NR*smp_processor_id();
+	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+#ifdef CONFIG_DEBUG_HIGHMEM
+	if (!pte_none(*(kmap_pte-idx)))
+		BUG();
+#endif
+	set_pte(kmap_pte-idx, mk_pte(page, kmap_prot));
+	local_flush_tlb_one((unsigned long)vaddr);
+
+	return (void*) vaddr;
+}
+
+void __kunmap_atomic(void *kvaddr, enum km_type type)
+{
+#ifdef CONFIG_DEBUG_HIGHMEM
+	unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
+	enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
+
+	if (vaddr < FIXADDR_START) { // FIXME
+		dec_preempt_count();
+		preempt_check_resched();
+		return;
+	}
+
+	if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx))
+		BUG();
+
+	/*
+	 * force other mappings to Oops if they'll try to access
+	 * this pte without first remap it
+	 */
+	pte_clear(&init_mm, vaddr, kmap_pte-idx);
+	local_flush_tlb_one(vaddr);
+#endif
+
+	dec_preempt_count();
+	preempt_check_resched();
+}
+
+struct page *__kmap_atomic_to_page(void *ptr)
+{
+	unsigned long idx, vaddr = (unsigned long)ptr;
+	pte_t *pte;
+
+	if (vaddr < FIXADDR_START)
+		return virt_to_page(ptr);
+
+	idx = virt_to_fix(vaddr);
+	pte = kmap_pte - (idx - FIX_KMAP_BEGIN);
+	return pte_page(*pte);
+}
+
+EXPORT_SYMBOL(__kmap);
+EXPORT_SYMBOL(__kunmap);
+EXPORT_SYMBOL(__kmap_atomic);
+EXPORT_SYMBOL(__kunmap_atomic);
+EXPORT_SYMBOL(__kmap_atomic_to_page);
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
new file mode 100644
index 0000000..b027ce7
--- /dev/null
+++ b/arch/mips/mm/init.c
@@ -0,0 +1,304 @@
+/*
+ * 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) 1994 - 2000 Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/pagemap.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <linux/swap.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cachectl.h>
+#include <asm/cpu.h>
+#include <asm/dma.h>
+#include <asm/mmu_context.h>
+#include <asm/sections.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/tlb.h>
+
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
+
+unsigned long highstart_pfn, highend_pfn;
+
+/*
+ * We have up to 8 empty zeroed pages so we can map one of the right colour
+ * when needed.  This is necessary only on R4000 / R4400 SC and MC versions
+ * where we have to avoid VCED / VECI exceptions for good performance at
+ * any price.  Since page is never written to after the initialization we
+ * don't have to care about aliases on other CPUs.
+ */
+unsigned long empty_zero_page, zero_page_mask;
+
+/*
+ * Not static inline because used by IP27 special magic initialization code
+ */
+unsigned long setup_zero_pages(void)
+{
+	unsigned long order, size;
+	struct page *page;
+
+	if (cpu_has_vce)
+		order = 3;
+	else
+		order = 0;
+
+	empty_zero_page = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
+	if (!empty_zero_page)
+		panic("Oh boy, that early out of memory?");
+
+	page = virt_to_page(empty_zero_page);
+	while (page < virt_to_page(empty_zero_page + (PAGE_SIZE << order))) {
+		set_bit(PG_reserved, &page->flags);
+		set_page_count(page, 0);
+		page++;
+	}
+
+	size = PAGE_SIZE << order;
+	zero_page_mask = (size - 1) & PAGE_MASK;
+
+	return 1UL << order;
+}
+
+#ifdef CONFIG_HIGHMEM
+pte_t *kmap_pte;
+pgprot_t kmap_prot;
+
+#define kmap_get_fixmap_pte(vaddr)					\
+	pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
+
+static void __init kmap_init(void)
+{
+	unsigned long kmap_vstart;
+
+	/* cache the first kmap pte */
+	kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
+	kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
+
+	kmap_prot = PAGE_KERNEL;
+}
+
+#ifdef CONFIG_MIPS64
+static void __init fixrange_init(unsigned long start, unsigned long end,
+	pgd_t *pgd_base)
+{
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *pte;
+	int i, j;
+	unsigned long vaddr;
+
+	vaddr = start;
+	i = __pgd_offset(vaddr);
+	j = __pmd_offset(vaddr);
+	pgd = pgd_base + i;
+
+	for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
+		pmd = (pmd_t *)pgd;
+		for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
+			if (pmd_none(*pmd)) {
+				pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+				set_pmd(pmd, __pmd(pte));
+				if (pte != pte_offset_kernel(pmd, 0))
+					BUG();
+			}
+			vaddr += PMD_SIZE;
+		}
+		j = 0;
+	}
+}
+#endif /* CONFIG_MIPS64 */
+#endif /* CONFIG_HIGHMEM */
+
+#ifndef CONFIG_DISCONTIGMEM
+extern void pagetable_init(void);
+
+void __init paging_init(void)
+{
+	unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+	unsigned long max_dma, high, low;
+
+	pagetable_init();
+
+#ifdef CONFIG_HIGHMEM
+	kmap_init();
+#endif
+
+	max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+	low = max_low_pfn;
+	high = highend_pfn;
+
+#ifdef CONFIG_ISA
+	if (low < max_dma)
+		zones_size[ZONE_DMA] = low;
+	else {
+		zones_size[ZONE_DMA] = max_dma;
+		zones_size[ZONE_NORMAL] = low - max_dma;
+	}
+#else
+	zones_size[ZONE_DMA] = low;
+#endif
+#ifdef CONFIG_HIGHMEM
+	if (cpu_has_dc_aliases) {
+		printk(KERN_WARNING "This processor doesn't support highmem.");
+		if (high - low)
+			printk(" %ldk highmem ignored", high - low);
+		printk("\n");
+	} else
+		zones_size[ZONE_HIGHMEM] = high - low;
+#endif
+
+	free_area_init(zones_size);
+}
+
+#define PFN_UP(x)	(((x) + PAGE_SIZE - 1) >> PAGE_SHIFT)
+#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
+
+static inline int page_is_ram(unsigned long pagenr)
+{
+	int i;
+
+	for (i = 0; i < boot_mem_map.nr_map; i++) {
+		unsigned long addr, end;
+
+		if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
+			/* not usable memory */
+			continue;
+
+		addr = PFN_UP(boot_mem_map.map[i].addr);
+		end = PFN_DOWN(boot_mem_map.map[i].addr +
+			       boot_mem_map.map[i].size);
+
+		if (pagenr >= addr && pagenr < end)
+			return 1;
+	}
+
+	return 0;
+}
+
+void __init mem_init(void)
+{
+	unsigned long codesize, reservedpages, datasize, initsize;
+	unsigned long tmp, ram;
+
+#ifdef CONFIG_HIGHMEM
+#ifdef CONFIG_DISCONTIGMEM
+#error "CONFIG_HIGHMEM and CONFIG_DISCONTIGMEM dont work together yet"
+#endif
+	max_mapnr = num_physpages = highend_pfn;
+#else
+	max_mapnr = num_physpages = max_low_pfn;
+#endif
+	high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
+
+	totalram_pages += free_all_bootmem();
+	totalram_pages -= setup_zero_pages();	/* Setup zeroed pages.  */
+
+	reservedpages = ram = 0;
+	for (tmp = 0; tmp < max_low_pfn; tmp++)
+		if (page_is_ram(tmp)) {
+			ram++;
+			if (PageReserved(mem_map+tmp))
+				reservedpages++;
+		}
+
+#ifdef CONFIG_HIGHMEM
+	for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) {
+		struct page *page = mem_map + tmp;
+
+		if (!page_is_ram(tmp)) {
+			SetPageReserved(page);
+			continue;
+		}
+		ClearPageReserved(page);
+#ifdef CONFIG_LIMITED_DMA
+		set_page_address(page, lowmem_page_address(page));
+#endif
+		set_bit(PG_highmem, &page->flags);
+		set_page_count(page, 1);
+		__free_page(page);
+		totalhigh_pages++;
+	}
+	totalram_pages += totalhigh_pages;
+#endif
+
+	codesize =  (unsigned long) &_etext - (unsigned long) &_text;
+	datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
+	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
+
+	printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, "
+	       "%ldk reserved, %ldk data, %ldk init, %ldk highmem)\n",
+	       (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
+	       ram << (PAGE_SHIFT-10),
+	       codesize >> 10,
+	       reservedpages << (PAGE_SHIFT-10),
+	       datasize >> 10,
+	       initsize >> 10,
+	       (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)));
+}
+#endif /* !CONFIG_DISCONTIGMEM */
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+#ifdef CONFIG_MIPS64
+	/* Switch from KSEG0 to XKPHYS addresses */
+	start = (unsigned long)phys_to_virt(CPHYSADDR(start));
+	end = (unsigned long)phys_to_virt(CPHYSADDR(end));
+#endif
+	if (start < end)
+		printk(KERN_INFO "Freeing initrd memory: %ldk freed\n",
+		       (end - start) >> 10);
+
+	for (; start < end; start += PAGE_SIZE) {
+		ClearPageReserved(virt_to_page(start));
+		set_page_count(virt_to_page(start), 1);
+		free_page(start);
+		totalram_pages++;
+	}
+}
+#endif
+
+extern unsigned long prom_free_prom_memory(void);
+
+void free_initmem(void)
+{
+	unsigned long addr, page, freed;
+
+	freed = prom_free_prom_memory();
+
+	addr = (unsigned long) &__init_begin;
+	while (addr < (unsigned long) &__init_end) {
+#ifdef CONFIG_MIPS64
+		page = PAGE_OFFSET | CPHYSADDR(addr);
+#else
+		page = addr;
+#endif
+		ClearPageReserved(virt_to_page(page));
+		set_page_count(virt_to_page(page), 1);
+		free_page(page);
+		totalram_pages++;
+		freed += PAGE_SIZE;
+		addr += PAGE_SIZE;
+	}
+	printk(KERN_INFO "Freeing unused kernel memory: %ldk freed\n",
+	       freed >> 10);
+}
diff --git a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c
new file mode 100644
index 0000000..adf3522
--- /dev/null
+++ b/arch/mips/mm/ioremap.c
@@ -0,0 +1,202 @@
+/*
+ * 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.
+ *
+ * (C) Copyright 1995 1996 Linus Torvalds
+ * (C) Copyright 2001, 2002 Ralf Baechle
+ */
+#include <linux/module.h>
+#include <asm/addrspace.h>
+#include <asm/byteorder.h>
+
+#include <linux/vmalloc.h>
+#include <asm/cacheflush.h>
+#include <asm/io.h>
+#include <asm/tlbflush.h>
+
+static inline void remap_area_pte(pte_t * pte, unsigned long address,
+	phys_t size, phys_t phys_addr, unsigned long flags)
+{
+	phys_t end;
+	unsigned long pfn;
+	pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE
+	                           | __WRITEABLE | flags);
+
+	address &= ~PMD_MASK;
+	end = address + size;
+	if (end > PMD_SIZE)
+		end = PMD_SIZE;
+	if (address >= end)
+		BUG();
+	pfn = phys_addr >> PAGE_SHIFT;
+	do {
+		if (!pte_none(*pte)) {
+			printk("remap_area_pte: page already exists\n");
+			BUG();
+		}
+		set_pte(pte, pfn_pte(pfn, pgprot));
+		address += PAGE_SIZE;
+		pfn++;
+		pte++;
+	} while (address && (address < end));
+}
+
+static inline int remap_area_pmd(pmd_t * pmd, unsigned long address,
+	phys_t size, phys_t phys_addr, unsigned long flags)
+{
+	phys_t end;
+
+	address &= ~PGDIR_MASK;
+	end = address + size;
+	if (end > PGDIR_SIZE)
+		end = PGDIR_SIZE;
+	phys_addr -= address;
+	if (address >= end)
+		BUG();
+	do {
+		pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
+		if (!pte)
+			return -ENOMEM;
+		remap_area_pte(pte, address, end - address, address + phys_addr, flags);
+		address = (address + PMD_SIZE) & PMD_MASK;
+		pmd++;
+	} while (address && (address < end));
+	return 0;
+}
+
+static int remap_area_pages(unsigned long address, phys_t phys_addr,
+	phys_t size, unsigned long flags)
+{
+	int error;
+	pgd_t * dir;
+	unsigned long end = address + size;
+
+	phys_addr -= address;
+	dir = pgd_offset(&init_mm, address);
+	flush_cache_all();
+	if (address >= end)
+		BUG();
+	spin_lock(&init_mm.page_table_lock);
+	do {
+		pmd_t *pmd;
+		pmd = pmd_alloc(&init_mm, dir, address);
+		error = -ENOMEM;
+		if (!pmd)
+			break;
+		if (remap_area_pmd(pmd, address, end - address,
+					 phys_addr + address, flags))
+			break;
+		error = 0;
+		address = (address + PGDIR_SIZE) & PGDIR_MASK;
+		dir++;
+	} while (address && (address < end));
+	spin_unlock(&init_mm.page_table_lock);
+	flush_tlb_all();
+	return error;
+}
+
+/*
+ * Allow physical addresses to be fixed up to help 36 bit peripherals.
+ */
+phys_t __attribute__ ((weak))
+fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+{
+	return phys_addr;
+}
+
+/*
+ * Generic mapping function (not visible outside):
+ */
+
+/*
+ * Remap an arbitrary physical address space into the kernel virtual
+ * address space. Needed when the kernel wants to access high addresses
+ * directly.
+ *
+ * NOTE! We need to allow non-page-aligned mappings too: we will obviously
+ * have to convert them into an offset in a page-aligned mapping, but the
+ * caller shouldn't need to know that small detail.
+ */
+
+#define IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL))
+
+void * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
+{
+	struct vm_struct * area;
+	unsigned long offset;
+	phys_t last_addr;
+	void * addr;
+
+	phys_addr = fixup_bigphys_addr(phys_addr, size);
+
+	/* Don't allow wraparound or zero size */
+	last_addr = phys_addr + size - 1;
+	if (!size || last_addr < phys_addr)
+		return NULL;
+
+	/*
+	 * Map uncached objects in the low 512mb of address space using KSEG1,
+	 * otherwise map using page tables.
+	 */
+	if (IS_LOW512(phys_addr) && IS_LOW512(last_addr) &&
+	    flags == _CACHE_UNCACHED)
+		return (void *) KSEG1ADDR(phys_addr);
+
+	/*
+	 * Don't allow anybody to remap normal RAM that we're using..
+	 */
+	if (phys_addr < virt_to_phys(high_memory)) {
+		char *t_addr, *t_end;
+		struct page *page;
+
+		t_addr = __va(phys_addr);
+		t_end = t_addr + (size - 1);
+
+		for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++)
+			if(!PageReserved(page))
+				return NULL;
+	}
+
+	/*
+	 * Mappings have to be page-aligned
+	 */
+	offset = phys_addr & ~PAGE_MASK;
+	phys_addr &= PAGE_MASK;
+	size = PAGE_ALIGN(last_addr + 1) - phys_addr;
+
+	/*
+	 * Ok, go for it..
+	 */
+	area = get_vm_area(size, VM_IOREMAP);
+	if (!area)
+		return NULL;
+	addr = area->addr;
+	if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
+		vunmap(addr);
+		return NULL;
+	}
+
+	return (void *) (offset + (char *)addr);
+}
+
+#define IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == KSEG1)
+
+void __iounmap(volatile void __iomem *addr)
+{
+	struct vm_struct *p;
+
+	if (IS_KSEG1(addr))
+		return;
+
+	p = remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
+	if (!p) {
+		printk(KERN_ERR "iounmap: bad address %p\n", addr);
+		return;
+	}
+
+        kfree(p);
+}
+
+EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(__iounmap);
diff --git a/arch/mips/mm/pg-r4k.c b/arch/mips/mm/pg-r4k.c
new file mode 100644
index 0000000..9f8b165
--- /dev/null
+++ b/arch/mips/mm/pg-r4k.c
@@ -0,0 +1,489 @@
+/*
+ * 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) 2003, 04, 05 Ralf Baechle (ralf@linux-mips.org)
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+
+#include <asm/cacheops.h>
+#include <asm/inst.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/prefetch.h>
+#include <asm/system.h>
+#include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
+#include <asm/mmu_context.h>
+#include <asm/cpu.h>
+#include <asm/war.h>
+
+#define half_scache_line_size()		(cpu_scache_line_size() >> 1)
+
+/*
+ * Maximum sizes:
+ *
+ * R4000 128 bytes S-cache:		0x58 bytes
+ * R4600 v1.7:				0x5c bytes
+ * R4600 v2.0:				0x60 bytes
+ * With prefetching, 16 byte strides	0xa0 bytes
+ */
+
+static unsigned int clear_page_array[0x130 / 4];
+
+void clear_page(void * page) __attribute__((alias("clear_page_array")));
+
+EXPORT_SYMBOL(clear_page);
+
+/*
+ * Maximum sizes:
+ *
+ * R4000 128 bytes S-cache:		0x11c bytes
+ * R4600 v1.7:				0x080 bytes
+ * R4600 v2.0:				0x07c bytes
+ * With prefetching, 16 byte strides	0x0b8 bytes
+ */
+static unsigned int copy_page_array[0x148 / 4];
+
+void copy_page(void *to, void *from) __attribute__((alias("copy_page_array")));
+
+EXPORT_SYMBOL(copy_page);
+
+/*
+ * This is suboptimal for 32-bit kernels; we assume that R10000 is only used
+ * with 64-bit kernels.  The prefetch offsets have been experimentally tuned
+ * an Origin 200.
+ */
+static int pref_offset_clear __initdata = 512;
+static int pref_offset_copy  __initdata = 256;
+
+static unsigned int pref_src_mode __initdata;
+static unsigned int pref_dst_mode __initdata;
+
+static int load_offset __initdata;
+static int store_offset __initdata;
+
+static unsigned int __initdata *dest, *epc;
+
+static unsigned int instruction_pending;
+static union mips_instruction delayed_mi;
+
+static void __init emit_instruction(union mips_instruction mi)
+{
+	if (instruction_pending)
+		*epc++ = delayed_mi.word;
+
+	instruction_pending = 1;
+	delayed_mi = mi;
+}
+
+static inline void flush_delay_slot_or_nop(void)
+{
+	if (instruction_pending) {
+		*epc++ = delayed_mi.word;
+		instruction_pending = 0;
+		return;
+	}
+
+	*epc++ = 0;
+}
+
+static inline unsigned int *label(void)
+{
+	if (instruction_pending) {
+		*epc++ = delayed_mi.word;
+		instruction_pending = 0;
+	}
+
+	return epc;
+}
+
+static inline void build_insn_word(unsigned int word)
+{
+	union mips_instruction mi;
+
+	mi.word		 = word;
+
+	emit_instruction(mi);
+}
+
+static inline void build_nop(void)
+{
+	build_insn_word(0);			/* nop */
+}
+
+static inline void build_src_pref(int advance)
+{
+	if (!(load_offset & (cpu_dcache_line_size() - 1))) {
+		union mips_instruction mi;
+
+		mi.i_format.opcode     = pref_op;
+		mi.i_format.rs         = 5;		/* $a1 */
+		mi.i_format.rt         = pref_src_mode;
+		mi.i_format.simmediate = load_offset + advance;
+
+		emit_instruction(mi);
+	}
+}
+
+static inline void __build_load_reg(int reg)
+{
+	union mips_instruction mi;
+	unsigned int width;
+
+	if (cpu_has_64bit_gp_regs) {
+		mi.i_format.opcode     = ld_op;
+		width = 8;
+	} else {
+		mi.i_format.opcode     = lw_op;
+		width = 4;
+	}
+	mi.i_format.rs         = 5;		/* $a1 */
+	mi.i_format.rt         = reg;		/* $reg */
+	mi.i_format.simmediate = load_offset;
+
+	load_offset += width;
+	emit_instruction(mi);
+}
+
+static inline void build_load_reg(int reg)
+{
+	if (cpu_has_prefetch)
+		build_src_pref(pref_offset_copy);
+
+	__build_load_reg(reg);
+}
+
+static inline void build_dst_pref(int advance)
+{
+	if (!(store_offset & (cpu_dcache_line_size() - 1))) {
+		union mips_instruction mi;
+
+		mi.i_format.opcode     = pref_op;
+		mi.i_format.rs         = 4;		/* $a0 */
+		mi.i_format.rt         = pref_dst_mode;
+		mi.i_format.simmediate = store_offset + advance;
+
+		emit_instruction(mi);
+	}
+}
+
+static inline void build_cdex_s(void)
+{
+	union mips_instruction mi;
+
+	if ((store_offset & (cpu_scache_line_size() - 1)))
+		return;
+
+	mi.c_format.opcode     = cache_op;
+	mi.c_format.rs         = 4;		/* $a0 */
+	mi.c_format.c_op       = 3;		/* Create Dirty Exclusive */
+	mi.c_format.cache      = 3;		/* Secondary Data Cache */
+	mi.c_format.simmediate = store_offset;
+
+	emit_instruction(mi);
+}
+
+static inline void build_cdex_p(void)
+{
+	union mips_instruction mi;
+
+	if (store_offset & (cpu_dcache_line_size() - 1))
+		return;
+
+	if (R4600_V1_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2010)) {
+		build_nop();
+		build_nop();
+		build_nop();
+		build_nop();
+	}
+
+	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020))
+		build_insn_word(0x8c200000);	/* lw      $zero, ($at) */
+
+	mi.c_format.opcode     = cache_op;
+	mi.c_format.rs         = 4;		/* $a0 */
+	mi.c_format.c_op       = 3;		/* Create Dirty Exclusive */
+	mi.c_format.cache      = 1;		/* Data Cache */
+	mi.c_format.simmediate = store_offset;
+
+	emit_instruction(mi);
+}
+
+static void __init __build_store_reg(int reg)
+{
+	union mips_instruction mi;
+	unsigned int width;
+
+	if (cpu_has_64bit_gp_regs ||
+	    (cpu_has_64bit_zero_reg && reg == 0)) {
+		mi.i_format.opcode     = sd_op;
+		width = 8;
+	} else {
+		mi.i_format.opcode     = sw_op;
+		width = 4;
+	}
+	mi.i_format.rs         = 4;		/* $a0 */
+	mi.i_format.rt         = reg;		/* $reg */
+	mi.i_format.simmediate = store_offset;
+
+	store_offset += width;
+	emit_instruction(mi);
+}
+
+static inline void build_store_reg(int reg)
+{
+	if (cpu_has_prefetch)
+		if (reg)
+			build_dst_pref(pref_offset_copy);
+		else
+			build_dst_pref(pref_offset_clear);
+	else if (cpu_has_cache_cdex_s)
+		build_cdex_s();
+	else if (cpu_has_cache_cdex_p)
+		build_cdex_p();
+
+	__build_store_reg(reg);
+}
+
+static inline void build_addiu_a2_a0(unsigned long offset)
+{
+	union mips_instruction mi;
+
+	BUG_ON(offset > 0x7fff);
+
+	mi.i_format.opcode     = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op;
+	mi.i_format.rs         = 4;		/* $a0 */
+	mi.i_format.rt         = 6;		/* $a2 */
+	mi.i_format.simmediate = offset;
+
+	emit_instruction(mi);
+}
+
+static inline void build_addiu_a1(unsigned long offset)
+{
+	union mips_instruction mi;
+
+	BUG_ON(offset > 0x7fff);
+
+	mi.i_format.opcode     = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op;
+	mi.i_format.rs         = 5;		/* $a1 */
+	mi.i_format.rt         = 5;		/* $a1 */
+	mi.i_format.simmediate = offset;
+
+	load_offset -= offset;
+
+	emit_instruction(mi);
+}
+
+static inline void build_addiu_a0(unsigned long offset)
+{
+	union mips_instruction mi;
+
+	BUG_ON(offset > 0x7fff);
+
+	mi.i_format.opcode     = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op;
+	mi.i_format.rs         = 4;		/* $a0 */
+	mi.i_format.rt         = 4;		/* $a0 */
+	mi.i_format.simmediate = offset;
+
+	store_offset -= offset;
+
+	emit_instruction(mi);
+}
+
+static inline void build_bne(unsigned int *dest)
+{
+	union mips_instruction mi;
+
+	mi.i_format.opcode = bne_op;
+	mi.i_format.rs     = 6;			/* $a2 */
+	mi.i_format.rt     = 4;			/* $a0 */
+	mi.i_format.simmediate = dest - epc - 1;
+
+	*epc++ = mi.word;
+	flush_delay_slot_or_nop();
+}
+
+static inline void build_jr_ra(void)
+{
+	union mips_instruction mi;
+
+	mi.r_format.opcode = spec_op;
+	mi.r_format.rs     = 31;
+	mi.r_format.rt     = 0;
+	mi.r_format.rd     = 0;
+	mi.r_format.re     = 0;
+	mi.r_format.func   = jr_op;
+
+	*epc++ = mi.word;
+	flush_delay_slot_or_nop();
+}
+
+void __init build_clear_page(void)
+{
+	unsigned int loop_start;
+
+	epc = (unsigned int *) &clear_page_array;
+	instruction_pending = 0;
+	store_offset = 0;
+
+	if (cpu_has_prefetch) {
+		switch (current_cpu_data.cputype) {
+		case CPU_RM9000:
+			/*
+			 * As a workaround for erratum G105 which make the
+			 * PrepareForStore hint unusable we fall back to
+			 * StoreRetained on the RM9000.  Once it is known which
+			 * versions of the RM9000 we'll be able to condition-
+			 * alize this.
+			 */
+
+		case CPU_R10000:
+		case CPU_R12000:
+			pref_src_mode = Pref_LoadStreamed;
+			pref_dst_mode = Pref_StoreStreamed;
+			break;
+
+		default:
+			pref_src_mode = Pref_LoadStreamed;
+			pref_dst_mode = Pref_PrepareForStore;
+			break;
+		}
+	}
+
+	build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0));
+
+	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020))
+		build_insn_word(0x3c01a000);	/* lui     $at, 0xa000  */
+
+dest = label();
+	do {
+		build_store_reg(0);
+		build_store_reg(0);
+		build_store_reg(0);
+		build_store_reg(0);
+	} while (store_offset < half_scache_line_size());
+	build_addiu_a0(2 * store_offset);
+	loop_start = store_offset;
+	do {
+		build_store_reg(0);
+		build_store_reg(0);
+		build_store_reg(0);
+		build_store_reg(0);
+	} while ((store_offset - loop_start) < half_scache_line_size());
+	build_bne(dest);
+
+	if (cpu_has_prefetch && pref_offset_clear) {
+		build_addiu_a2_a0(pref_offset_clear);
+	dest = label();
+		loop_start = store_offset;
+		do {
+			__build_store_reg(0);
+			__build_store_reg(0);
+			__build_store_reg(0);
+			__build_store_reg(0);
+		} while ((store_offset - loop_start) < half_scache_line_size());
+		build_addiu_a0(2 * store_offset);
+		loop_start = store_offset;
+		do {
+			__build_store_reg(0);
+			__build_store_reg(0);
+			__build_store_reg(0);
+			__build_store_reg(0);
+		} while ((store_offset - loop_start) < half_scache_line_size());
+		build_bne(dest);
+	}
+
+	build_jr_ra();
+
+	flush_icache_range((unsigned long)&clear_page_array,
+	                   (unsigned long) epc);
+
+	BUG_ON(epc > clear_page_array + ARRAY_SIZE(clear_page_array));
+}
+
+void __init build_copy_page(void)
+{
+	unsigned int loop_start;
+
+	epc = (unsigned int *) &copy_page_array;
+	store_offset = load_offset = 0;
+	instruction_pending = 0;
+
+	build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0));
+
+	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020))
+		build_insn_word(0x3c01a000);	/* lui     $at, 0xa000  */
+
+dest = label();
+	loop_start = store_offset;
+	do {
+		build_load_reg( 8);
+		build_load_reg( 9);
+		build_load_reg(10);
+		build_load_reg(11);
+		build_store_reg( 8);
+		build_store_reg( 9);
+		build_store_reg(10);
+		build_store_reg(11);
+	} while ((store_offset - loop_start) < half_scache_line_size());
+	build_addiu_a0(2 * store_offset);
+	build_addiu_a1(2 * load_offset);
+	loop_start = store_offset;
+	do {
+		build_load_reg( 8);
+		build_load_reg( 9);
+		build_load_reg(10);
+		build_load_reg(11);
+		build_store_reg( 8);
+		build_store_reg( 9);
+		build_store_reg(10);
+		build_store_reg(11);
+	} while ((store_offset - loop_start) < half_scache_line_size());
+	build_bne(dest);
+
+	if (cpu_has_prefetch && pref_offset_copy) {
+		build_addiu_a2_a0(pref_offset_copy);
+	dest = label();
+		loop_start = store_offset;
+		do {
+			__build_load_reg( 8);
+			__build_load_reg( 9);
+			__build_load_reg(10);
+			__build_load_reg(11);
+			__build_store_reg( 8);
+			__build_store_reg( 9);
+			__build_store_reg(10);
+			__build_store_reg(11);
+		} while ((store_offset - loop_start) < half_scache_line_size());
+		build_addiu_a0(2 * store_offset);
+		build_addiu_a1(2 * load_offset);
+		loop_start = store_offset;
+		do {
+			__build_load_reg( 8);
+			__build_load_reg( 9);
+			__build_load_reg(10);
+			__build_load_reg(11);
+			__build_store_reg( 8);
+			__build_store_reg( 9);
+			__build_store_reg(10);
+			__build_store_reg(11);
+		} while ((store_offset - loop_start) < half_scache_line_size());
+		build_bne(dest);
+	}
+
+	build_jr_ra();
+
+	flush_icache_range((unsigned long)&copy_page_array,
+	                   (unsigned long) epc);
+
+	BUG_ON(epc > copy_page_array + ARRAY_SIZE(copy_page_array));
+}
diff --git a/arch/mips/mm/pg-sb1.c b/arch/mips/mm/pg-sb1.c
new file mode 100644
index 0000000..59d131b
--- /dev/null
+++ b/arch/mips/mm/pg-sb1.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 2000 SiByte, Inc.
+ * Copyright (C) 2005 Thiemo Seufer
+ *
+ * Written by Justin Carlson of SiByte, Inc.
+ *         and Kip Walker of Broadcom Corp.
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+
+#include <asm/io.h>
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_dma.h>
+
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+#define SB1_PREF_LOAD_STREAMED_HINT "0"
+#define SB1_PREF_STORE_STREAMED_HINT "1"
+#else
+#define SB1_PREF_LOAD_STREAMED_HINT "4"
+#define SB1_PREF_STORE_STREAMED_HINT "5"
+#endif
+
+static inline void clear_page_cpu(void *page)
+{
+	unsigned char *addr = (unsigned char *) page;
+	unsigned char *end = addr + PAGE_SIZE;
+
+	/*
+	 * JDCXXX - This should be bottlenecked by the write buffer, but these
+	 * things tend to be mildly unpredictable...should check this on the
+	 * performance model
+	 *
+	 * We prefetch 4 lines ahead.  We're also "cheating" slightly here...
+	 * since we know we're on an SB1, we force the assembler to take
+	 * 64-bit operands to speed things up
+	 */
+	__asm__ __volatile__(
+	"	.set	push		\n"
+	"	.set	mips4		\n"
+	"	.set	noreorder	\n"
+#ifdef CONFIG_CPU_HAS_PREFETCH
+	"	daddiu	%0, %0, 128	\n"
+	"	pref	" SB1_PREF_STORE_STREAMED_HINT ", -128(%0)  \n"  /* Prefetch the first 4 lines */
+	"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -96(%0)  \n"
+	"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -64(%0)  \n"
+	"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -32(%0)  \n"
+	"1:	sd	$0, -128(%0)	\n"  /* Throw out a cacheline of 0's */
+	"	sd	$0, -120(%0)	\n"
+	"	sd	$0, -112(%0)	\n"
+	"	sd	$0, -104(%0)	\n"
+	"	daddiu	%0, %0, 32	\n"
+	"	bnel	%0, %1, 1b	\n"
+	"	 pref	" SB1_PREF_STORE_STREAMED_HINT ",  -32(%0)  \n"
+	"	daddiu	%0, %0, -128	\n"
+#endif
+	"	sd	$0, 0(%0)	\n"  /* Throw out a cacheline of 0's */
+	"1:	sd	$0, 8(%0)	\n"
+	"	sd	$0, 16(%0)	\n"
+	"	sd	$0, 24(%0)	\n"
+	"	daddiu	%0, %0, 32	\n"
+	"	bnel	%0, %1, 1b	\n"
+	"	 sd	$0, 0(%0)	\n"
+	"	.set	pop		\n"
+	: "+r" (addr)
+	: "r" (end)
+	: "memory");
+}
+
+static inline void copy_page_cpu(void *to, void *from)
+{
+	unsigned char *src = (unsigned char *)from;
+	unsigned char *dst = (unsigned char *)to;
+	unsigned char *end = src + PAGE_SIZE;
+
+	/*
+	 * The pref's used here are using "streaming" hints, which cause the
+	 * copied data to be kicked out of the cache sooner.  A page copy often
+	 * ends up copying a lot more data than is commonly used, so this seems
+	 * to make sense in terms of reducing cache pollution, but I've no real
+	 * performance data to back this up
+	 */
+	__asm__ __volatile__(
+	"	.set	push		\n"
+	"	.set	mips4		\n"
+	"	.set	noreorder	\n"
+#ifdef CONFIG_CPU_HAS_PREFETCH
+	"	daddiu	%0, %0, 128	\n"
+	"	daddiu	%1, %1, 128	\n"
+	"	pref	" SB1_PREF_LOAD_STREAMED_HINT  ", -128(%0)\n"  /* Prefetch the first 4 lines */
+	"	pref	" SB1_PREF_STORE_STREAMED_HINT ", -128(%1)\n"
+	"	pref	" SB1_PREF_LOAD_STREAMED_HINT  ",  -96(%0)\n"
+	"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -96(%1)\n"
+	"	pref	" SB1_PREF_LOAD_STREAMED_HINT  ",  -64(%0)\n"
+	"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -64(%1)\n"
+	"	pref	" SB1_PREF_LOAD_STREAMED_HINT  ",  -32(%0)\n"
+	"1:	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -32(%1)\n"
+# ifdef CONFIG_MIPS64
+	"	ld	$8, -128(%0)	\n"  /* Block copy a cacheline */
+	"	ld	$9, -120(%0)	\n"
+	"	ld	$10, -112(%0)	\n"
+	"	ld	$11, -104(%0)	\n"
+	"	sd	$8, -128(%1)	\n"
+	"	sd	$9, -120(%1)	\n"
+	"	sd	$10, -112(%1)	\n"
+	"	sd	$11, -104(%1)	\n"
+# else
+	"	lw	$2, -128(%0)	\n"  /* Block copy a cacheline */
+	"	lw	$3, -124(%0)	\n"
+	"	lw	$6, -120(%0)	\n"
+	"	lw	$7, -116(%0)	\n"
+	"	lw	$8, -112(%0)	\n"
+	"	lw	$9, -108(%0)	\n"
+	"	lw	$10, -104(%0)	\n"
+	"	lw	$11, -100(%0)	\n"
+	"	sw	$2, -128(%1)	\n"
+	"	sw	$3, -124(%1)	\n"
+	"	sw	$6, -120(%1)	\n"
+	"	sw	$7, -116(%1)	\n"
+	"	sw	$8, -112(%1)	\n"
+	"	sw	$9, -108(%1)	\n"
+	"	sw	$10, -104(%1)	\n"
+	"	sw	$11, -100(%1)	\n"
+# endif
+	"	daddiu	%0, %0, 32	\n"
+	"	daddiu	%1, %1, 32	\n"
+	"	bnel	%0, %2, 1b	\n"
+	"	 pref	" SB1_PREF_LOAD_STREAMED_HINT  ",  -32(%0)\n"
+	"	daddiu	%0, %0, -128	\n"
+	"	daddiu	%1, %1, -128	\n"
+#endif
+#ifdef CONFIG_MIPS64
+	"	ld	$8, 0(%0)	\n"  /* Block copy a cacheline */
+	"1:	ld	$9, 8(%0)	\n"
+	"	ld	$10, 16(%0)	\n"
+	"	ld	$11, 24(%0)	\n"
+	"	sd	$8, 0(%1)	\n"
+	"	sd	$9, 8(%1)	\n"
+	"	sd	$10, 16(%1)	\n"
+	"	sd	$11, 24(%1)	\n"
+#else
+	"	lw	$2, 0(%0)	\n"  /* Block copy a cacheline */
+	"1:	lw	$3, 4(%0)	\n"
+	"	lw	$6, 8(%0)	\n"
+	"	lw	$7, 12(%0)	\n"
+	"	lw	$8, 16(%0)	\n"
+	"	lw	$9, 20(%0)	\n"
+	"	lw	$10, 24(%0)	\n"
+	"	lw	$11, 28(%0)	\n"
+	"	sw	$2, 0(%1)	\n"
+	"	sw	$3, 4(%1)	\n"
+	"	sw	$6, 8(%1)	\n"
+	"	sw	$7, 12(%1)	\n"
+	"	sw	$8, 16(%1)	\n"
+	"	sw	$9, 20(%1)	\n"
+	"	sw	$10, 24(%1)	\n"
+	"	sw	$11, 28(%1)	\n"
+#endif
+	"	daddiu	%0, %0, 32	\n"
+	"	daddiu	%1, %1, 32	\n"
+	"	bnel	%0, %2, 1b	\n"
+#ifdef CONFIG_MIPS64
+	"	 ld	$8, 0(%0)	\n"
+#else
+	"	 lw	$2, 0(%0)	\n"
+#endif
+	"	.set	pop		\n"
+	: "+r" (src), "+r" (dst)
+	: "r" (end)
+#ifdef CONFIG_MIPS64
+	: "$8","$9","$10","$11","memory");
+#else
+	: "$2","$3","$6","$7","$8","$9","$10","$11","memory");
+#endif
+}
+
+
+#ifdef CONFIG_SIBYTE_DMA_PAGEOPS
+
+/*
+ * Pad descriptors to cacheline, since each is exclusively owned by a
+ * particular CPU. 
+ */
+typedef struct dmadscr_s {
+	u64 dscr_a;
+	u64 dscr_b;
+	u64 pad_a;
+	u64 pad_b;
+} dmadscr_t;
+
+static dmadscr_t page_descr[NR_CPUS] __attribute__((aligned(SMP_CACHE_BYTES)));
+
+void sb1_dma_init(void)
+{
+	int cpu = smp_processor_id();
+	u64 base_val = CPHYSADDR(&page_descr[cpu]) | V_DM_DSCR_BASE_RINGSZ(1);
+
+	bus_writeq(base_val,
+		   (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+	bus_writeq(base_val | M_DM_DSCR_BASE_RESET,
+		   (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+	bus_writeq(base_val | M_DM_DSCR_BASE_ENABL,
+		   (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+}
+
+void clear_page(void *page)
+{
+	int cpu = smp_processor_id();
+
+	/* if the page is above Kseg0, use old way */
+	if ((long)KSEGX(page) != (long)CKSEG0)
+		return clear_page_cpu(page);
+
+	page_descr[cpu].dscr_a = CPHYSADDR(page) | M_DM_DSCRA_ZERO_MEM | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
+	page_descr[cpu].dscr_b = V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
+	bus_writeq(1, (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
+
+	/*
+	 * Don't really want to do it this way, but there's no
+	 * reliable way to delay completion detection.
+	 */
+	while (!(bus_readq((void *)(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) &
+			   M_DM_DSCR_BASE_INTERRUPT))))
+		;
+	bus_readq((void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+}
+
+void copy_page(void *to, void *from)
+{
+	unsigned long from_phys = CPHYSADDR(from);
+	unsigned long to_phys = CPHYSADDR(to);
+	int cpu = smp_processor_id();
+
+	/* if either page is above Kseg0, use old way */
+	if ((long)KSEGX(to) != (long)CKSEG0
+	    || (long)KSEGX(from) != (long)CKSEG0)
+		return copy_page_cpu(to, from);
+
+	page_descr[cpu].dscr_a = CPHYSADDR(to_phys) | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
+	page_descr[cpu].dscr_b = CPHYSADDR(from_phys) | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
+	bus_writeq(1, (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
+
+	/*
+	 * Don't really want to do it this way, but there's no
+	 * reliable way to delay completion detection.
+	 */
+	while (!(bus_readq((void *)(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) &
+				    M_DM_DSCR_BASE_INTERRUPT))))
+		;
+	bus_readq((void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+}
+
+#else /* !CONFIG_SIBYTE_DMA_PAGEOPS */
+
+void clear_page(void *page)
+{
+	return clear_page_cpu(page);
+}
+
+void copy_page(void *to, void *from)
+{
+	return copy_page_cpu(to, from);
+}
+
+#endif /* !CONFIG_SIBYTE_DMA_PAGEOPS */
+
+EXPORT_SYMBOL(clear_page);
+EXPORT_SYMBOL(copy_page);
diff --git a/arch/mips/mm/pgtable-32.c b/arch/mips/mm/pgtable-32.c
new file mode 100644
index 0000000..4f07f81
--- /dev/null
+++ b/arch/mips/mm/pgtable-32.c
@@ -0,0 +1,97 @@
+/*
+ * 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) 2003 by Ralf Baechle
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <asm/pgtable.h>
+
+void pgd_init(unsigned long page)
+{
+	unsigned long *p = (unsigned long *) page;
+	int i;
+
+	for (i = 0; i < USER_PTRS_PER_PGD; i+=8) {
+		p[i + 0] = (unsigned long) invalid_pte_table;
+		p[i + 1] = (unsigned long) invalid_pte_table;
+		p[i + 2] = (unsigned long) invalid_pte_table;
+		p[i + 3] = (unsigned long) invalid_pte_table;
+		p[i + 4] = (unsigned long) invalid_pte_table;
+		p[i + 5] = (unsigned long) invalid_pte_table;
+		p[i + 6] = (unsigned long) invalid_pte_table;
+		p[i + 7] = (unsigned long) invalid_pte_table;
+	}
+}
+
+#ifdef CONFIG_HIGHMEM
+static void __init fixrange_init (unsigned long start, unsigned long end,
+	pgd_t *pgd_base)
+{
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *pte;
+	int i, j;
+	unsigned long vaddr;
+
+	vaddr = start;
+	i = __pgd_offset(vaddr);
+	j = __pmd_offset(vaddr);
+	pgd = pgd_base + i;
+
+	for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
+		pmd = (pmd_t *)pgd;
+		for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
+			if (pmd_none(*pmd)) {
+				pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+				set_pmd(pmd, __pmd((unsigned long)pte));
+				if (pte != pte_offset_kernel(pmd, 0))
+					BUG();
+			}
+			vaddr += PMD_SIZE;
+		}
+		j = 0;
+	}
+}
+#endif
+
+void __init pagetable_init(void)
+{
+#ifdef CONFIG_HIGHMEM
+	unsigned long vaddr;
+	pgd_t *pgd, *pgd_base;
+	pmd_t *pmd;
+	pte_t *pte;
+#endif
+
+	/* Initialize the entire pgd.  */
+	pgd_init((unsigned long)swapper_pg_dir);
+	pgd_init((unsigned long)swapper_pg_dir
+		 + sizeof(pgd_t) * USER_PTRS_PER_PGD);
+
+#ifdef CONFIG_HIGHMEM
+	pgd_base = swapper_pg_dir;
+
+	/*
+	 * Fixed mappings:
+	 */
+	vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
+	fixrange_init(vaddr, 0, pgd_base);
+
+	/*
+	 * Permanent kmaps:
+	 */
+	vaddr = PKMAP_BASE;
+	fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
+
+	pgd = swapper_pg_dir + __pgd_offset(vaddr);
+	pmd = pmd_offset(pgd, vaddr);
+	pte = pte_offset_kernel(pmd, vaddr);
+	pkmap_page_table = pte;
+#endif
+}
diff --git a/arch/mips/mm/pgtable-64.c b/arch/mips/mm/pgtable-64.c
new file mode 100644
index 0000000..44b5e97f
--- /dev/null
+++ b/arch/mips/mm/pgtable-64.c
@@ -0,0 +1,58 @@
+/*
+ * 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) 1999, 2000 by Silicon Graphics
+ * Copyright (C) 2003 by Ralf Baechle
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <asm/pgtable.h>
+
+void pgd_init(unsigned long page)
+{
+	unsigned long *p, *end;
+
+ 	p = (unsigned long *) page;
+	end = p + PTRS_PER_PGD;
+
+	while (p < end) {
+		p[0] = (unsigned long) invalid_pmd_table;
+		p[1] = (unsigned long) invalid_pmd_table;
+		p[2] = (unsigned long) invalid_pmd_table;
+		p[3] = (unsigned long) invalid_pmd_table;
+		p[4] = (unsigned long) invalid_pmd_table;
+		p[5] = (unsigned long) invalid_pmd_table;
+		p[6] = (unsigned long) invalid_pmd_table;
+		p[7] = (unsigned long) invalid_pmd_table;
+		p += 8;
+	}
+}
+
+void pmd_init(unsigned long addr, unsigned long pagetable)
+{
+	unsigned long *p, *end;
+
+ 	p = (unsigned long *) addr;
+	end = p + PTRS_PER_PMD;
+
+	while (p < end) {
+		p[0] = (unsigned long)pagetable;
+		p[1] = (unsigned long)pagetable;
+		p[2] = (unsigned long)pagetable;
+		p[3] = (unsigned long)pagetable;
+		p[4] = (unsigned long)pagetable;
+		p[5] = (unsigned long)pagetable;
+		p[6] = (unsigned long)pagetable;
+		p[7] = (unsigned long)pagetable;
+		p += 8;
+	}
+}
+
+void __init pagetable_init(void)
+{
+	/* Initialize the entire pgd.  */
+	pgd_init((unsigned long)swapper_pg_dir);
+	pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table);
+}
diff --git a/arch/mips/mm/pgtable.c b/arch/mips/mm/pgtable.c
new file mode 100644
index 0000000..3b88fde
--- /dev/null
+++ b/arch/mips/mm/pgtable.c
@@ -0,0 +1,36 @@
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+
+void show_mem(void)
+{
+#ifndef CONFIG_DISCONTIGMEM  /* XXX(hch): later.. */
+	int pfn, total = 0, reserved = 0;
+	int shared = 0, cached = 0;
+	int highmem = 0;
+	struct page *page;
+
+	printk("Mem-info:\n");
+	show_free_areas();
+	printk("Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
+	pfn = max_mapnr;
+	while (pfn-- > 0) {
+		page = pfn_to_page(pfn);
+		total++;
+		if (PageHighMem(page))
+			highmem++;
+		if (PageReserved(page))
+			reserved++;
+		else if (PageSwapCache(page))
+			cached++;
+		else if (page_count(page))
+			shared += page_count(page) - 1;
+	}
+	printk("%d pages of RAM\n", total);
+	printk("%d pages of HIGHMEM\n",highmem);
+	printk("%d reserved pages\n",reserved);
+	printk("%d pages shared\n",shared);
+	printk("%d pages swap cached\n",cached);
+#endif
+}
diff --git a/arch/mips/mm/sc-ip22.c b/arch/mips/mm/sc-ip22.c
new file mode 100644
index 0000000..d236cf8
--- /dev/null
+++ b/arch/mips/mm/sc-ip22.c
@@ -0,0 +1,177 @@
+/*
+ * sc-ip22.c: Indy cache management functions.
+ *
+ * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org),
+ * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com).
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/bcache.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/bootinfo.h>
+#include <asm/sgi/ip22.h>
+#include <asm/sgi/mc.h>
+
+/* Secondary cache size in bytes, if present.  */
+static unsigned long scache_size;
+
+#undef DEBUG_CACHE
+
+#define SC_SIZE 0x00080000
+#define SC_LINE 32
+#define CI_MASK (SC_SIZE - SC_LINE)
+#define SC_INDEX(n) ((n) & CI_MASK)
+
+static inline void indy_sc_wipe(unsigned long first, unsigned long last)
+{
+	unsigned long tmp;
+
+	__asm__ __volatile__(
+	".set\tpush\t\t\t# indy_sc_wipe\n\t"
+	".set\tnoreorder\n\t"
+	".set\tmips3\n\t"
+	".set\tnoat\n\t"
+	"mfc0\t%2, $12\n\t"
+	"li\t$1, 0x80\t\t\t# Go 64 bit\n\t"
+	"mtc0\t$1, $12\n\t"
+
+	"dli\t$1, 0x9000000080000000\n\t"
+	"or\t%0, $1\t\t\t# first line to flush\n\t"
+	"or\t%1, $1\t\t\t# last line to flush\n\t"
+	".set\tat\n\t"
+
+	"1:\tsw\t$0, 0(%0)\n\t"
+	"bne\t%0, %1, 1b\n\t"
+	" daddu\t%0, 32\n\t"
+
+	"mtc0\t%2, $12\t\t\t# Back to 32 bit\n\t"
+	"nop; nop; nop; nop;\n\t"
+	".set\tpop"
+	: "=r" (first), "=r" (last), "=&r" (tmp)
+	: "0" (first), "1" (last));
+}
+
+static void indy_sc_wback_invalidate(unsigned long addr, unsigned long size)
+{
+	unsigned long first_line, last_line;
+	unsigned long flags;
+
+#ifdef DEBUG_CACHE
+	printk("indy_sc_wback_invalidate[%08lx,%08lx]", addr, size);
+#endif
+
+	/* Catch bad driver code */
+	BUG_ON(size == 0);
+
+	/* Which lines to flush?  */
+	first_line = SC_INDEX(addr);
+	last_line = SC_INDEX(addr + size - 1);
+
+	local_irq_save(flags);
+	if (first_line <= last_line) {
+		indy_sc_wipe(first_line, last_line);
+		goto out;
+	}
+
+	indy_sc_wipe(first_line, SC_SIZE - SC_LINE);
+	indy_sc_wipe(0, last_line);
+out:
+	local_irq_restore(flags);
+}
+
+static void indy_sc_enable(void)
+{
+	unsigned long addr, tmp1, tmp2;
+
+	/* This is really cool... */
+#ifdef DEBUG_CACHE
+	printk("Enabling R4600 SCACHE\n");
+#endif
+	__asm__ __volatile__(
+	".set\tpush\n\t"
+	".set\tnoreorder\n\t"
+	".set\tmips3\n\t"
+	"mfc0\t%2, $12\n\t"
+	"nop; nop; nop; nop;\n\t"
+	"li\t%1, 0x80\n\t"
+	"mtc0\t%1, $12\n\t"
+	"nop; nop; nop; nop;\n\t"
+	"li\t%0, 0x1\n\t"
+	"dsll\t%0, 31\n\t"
+	"lui\t%1, 0x9000\n\t"
+	"dsll32\t%1, 0\n\t"
+	"or\t%0, %1, %0\n\t"
+	"sb\t$0, 0(%0)\n\t"
+	"mtc0\t$0, $12\n\t"
+	"nop; nop; nop; nop;\n\t"
+	"mtc0\t%2, $12\n\t"
+	"nop; nop; nop; nop;\n\t"
+	".set\tpop"
+	: "=r" (tmp1), "=r" (tmp2), "=r" (addr));
+}
+
+static void indy_sc_disable(void)
+{
+	unsigned long tmp1, tmp2, tmp3;
+
+#ifdef DEBUG_CACHE
+	printk("Disabling R4600 SCACHE\n");
+#endif
+	__asm__ __volatile__(
+	".set\tpush\n\t"
+	".set\tnoreorder\n\t"
+	".set\tmips3\n\t"
+	"li\t%0, 0x1\n\t"
+	"dsll\t%0, 31\n\t"
+	"lui\t%1, 0x9000\n\t"
+	"dsll32\t%1, 0\n\t"
+	"or\t%0, %1, %0\n\t"
+	"mfc0\t%2, $12\n\t"
+	"nop; nop; nop; nop\n\t"
+	"li\t%1, 0x80\n\t"
+	"mtc0\t%1, $12\n\t"
+	"nop; nop; nop; nop\n\t"
+	"sh\t$0, 0(%0)\n\t"
+	"mtc0\t$0, $12\n\t"
+	"nop; nop; nop; nop\n\t"
+	"mtc0\t%2, $12\n\t"
+	"nop; nop; nop; nop\n\t"
+	".set\tpop"
+	: "=r" (tmp1), "=r" (tmp2), "=r" (tmp3));
+}
+
+static inline int __init indy_sc_probe(void)
+{
+	unsigned int size = ip22_eeprom_read(&sgimc->eeprom, 17);
+	if (size == 0)
+		return 0;
+
+	size <<= PAGE_SHIFT;
+	printk(KERN_INFO "R4600/R5000 SCACHE size %dK, linesize 32 bytes.\n",
+	       size >> 10);
+	scache_size = size;
+
+	return 1;
+}
+
+/* XXX Check with wje if the Indy caches can differenciate between
+   writeback + invalidate and just invalidate.  */
+struct bcache_ops indy_sc_ops = {
+	.bc_enable = indy_sc_enable,
+	.bc_disable = indy_sc_disable,
+	.bc_wback_inv = indy_sc_wback_invalidate,
+	.bc_inv = indy_sc_wback_invalidate
+};
+
+void __init indy_sc_init(void)
+{
+	if (indy_sc_probe()) {
+		indy_sc_enable();
+		bcops = &indy_sc_ops;
+	}
+}
diff --git a/arch/mips/mm/sc-r5k.c b/arch/mips/mm/sc-r5k.c
new file mode 100644
index 0000000..d35b6c1
--- /dev/null
+++ b/arch/mips/mm/sc-r5k.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org),
+ * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com).
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/mipsregs.h>
+#include <asm/bcache.h>
+#include <asm/cacheops.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+#include <asm/r4kcache.h>
+
+/* Secondary cache size in bytes, if present.  */
+static unsigned long scache_size;
+
+#define SC_LINE 32
+#define SC_PAGE (128*SC_LINE)
+
+static inline void blast_r5000_scache(void)
+{
+	unsigned long start = INDEX_BASE;
+	unsigned long end = start + scache_size;
+
+	while(start < end) {
+		cache_op(R5K_Page_Invalidate_S, start);
+		start += SC_PAGE;
+	}
+}
+
+static void r5k_dma_cache_inv_sc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	/* Catch bad driver code */
+	BUG_ON(size == 0);
+
+	if (size >= scache_size) {
+		blast_r5000_scache();
+		return;
+	}
+
+	/* On the R5000 secondary cache we cannot
+	 * invalidate less than a page at a time.
+	 * The secondary cache is physically indexed, write-through.
+	 */
+	a = addr & ~(SC_PAGE - 1);
+	end = (addr + size - 1) & ~(SC_PAGE - 1);
+	while (a <= end) {
+		cache_op(R5K_Page_Invalidate_S, a);
+		a += SC_PAGE;
+	}
+}
+
+static void r5k_sc_enable(void)
+{
+        unsigned long flags;
+
+	local_irq_save(flags);
+	set_c0_config(R5K_CONF_SE);
+	blast_r5000_scache();
+	local_irq_restore(flags);
+}
+
+static void r5k_sc_disable(void)
+{
+        unsigned long flags;
+
+	local_irq_save(flags);
+	blast_r5000_scache();
+	clear_c0_config(R5K_CONF_SE);
+	local_irq_restore(flags);
+}
+
+static inline int __init r5k_sc_probe(void)
+{
+	unsigned long config = read_c0_config();
+
+	if (config & CONF_SC)
+		return(0);
+
+	scache_size = (512 * 1024) << ((config & R5K_CONF_SS) >> 20);
+
+	printk("R5000 SCACHE size %ldkB, linesize 32 bytes.\n",
+			scache_size >> 10);
+
+	return 1;
+}
+
+static struct bcache_ops r5k_sc_ops = {
+	.bc_enable = r5k_sc_enable,
+	.bc_disable = r5k_sc_disable,
+	.bc_wback_inv = r5k_dma_cache_inv_sc,
+	.bc_inv = r5k_dma_cache_inv_sc
+};
+
+void __init r5k_sc_init(void)
+{
+	if (r5k_sc_probe()) {
+		r5k_sc_enable();
+		bcops = &r5k_sc_ops;
+	}
+}
diff --git a/arch/mips/mm/sc-rm7k.c b/arch/mips/mm/sc-rm7k.c
new file mode 100644
index 0000000..4e92f93
--- /dev/null
+++ b/arch/mips/mm/sc-rm7k.c
@@ -0,0 +1,193 @@
+/*
+ * sc-rm7k.c: RM7000 cache management functions.
+ *
+ * Copyright (C) 1997, 2001, 2003, 2004 Ralf Baechle (ralf@linux-mips.org)
+ */
+
+#undef DEBUG
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+
+#include <asm/addrspace.h>
+#include <asm/bcache.h>
+#include <asm/cacheops.h>
+#include <asm/mipsregs.h>
+#include <asm/processor.h>
+
+/* Primary cache parameters. */
+#define sc_lsize	32
+#define tc_pagesize	(32*128)
+
+/* Secondary cache parameters. */
+#define scache_size	(256*1024)	/* Fixed to 256KiB on RM7000 */
+
+extern unsigned long icache_way_size, dcache_way_size;
+
+#include <asm/r4kcache.h>
+
+int rm7k_tcache_enabled;
+
+/*
+ * Writeback and invalidate the primary cache dcache before DMA.
+ * (XXX These need to be fixed ...)
+ */
+static void rm7k_sc_wback_inv(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	pr_debug("rm7k_sc_wback_inv[%08lx,%08lx]", addr, size);
+
+	/* Catch bad driver code */
+	BUG_ON(size == 0);
+
+	a = addr & ~(sc_lsize - 1);
+	end = (addr + size - 1) & ~(sc_lsize - 1);
+	while (1) {
+		flush_scache_line(a);	/* Hit_Writeback_Inv_SD */
+		if (a == end)
+			break;
+		a += sc_lsize;
+	}
+
+	if (!rm7k_tcache_enabled)
+		return;
+
+	a = addr & ~(tc_pagesize - 1);
+	end = (addr + size - 1) & ~(tc_pagesize - 1);
+	while(1) {
+		invalidate_tcache_page(a);	/* Page_Invalidate_T */
+		if (a == end)
+			break;
+		a += tc_pagesize;
+	}
+}
+
+static void rm7k_sc_inv(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	pr_debug("rm7k_sc_inv[%08lx,%08lx]", addr, size);
+
+	/* Catch bad driver code */
+	BUG_ON(size == 0);
+
+	a = addr & ~(sc_lsize - 1);
+	end = (addr + size - 1) & ~(sc_lsize - 1);
+	while (1) {
+		invalidate_scache_line(a);	/* Hit_Invalidate_SD */
+		if (a == end)
+			break;
+		a += sc_lsize;
+	}
+
+	if (!rm7k_tcache_enabled)
+		return;
+
+	a = addr & ~(tc_pagesize - 1);
+	end = (addr + size - 1) & ~(tc_pagesize - 1);
+	while(1) {
+		invalidate_tcache_page(a);	/* Page_Invalidate_T */
+		if (a == end)
+			break;
+		a += tc_pagesize;
+	}
+}
+
+/*
+ * This function is executed in the uncached segment CKSEG1.
+ * It must not touch the stack, because the stack pointer still points
+ * into CKSEG0.
+ *
+ * Three options:
+ *	- Write it in assembly and guarantee that we don't use the stack.
+ *	- Disable caching for CKSEG0 before calling it.
+ *	- Pray that GCC doesn't randomly start using the stack.
+ *
+ * This being Linux, we obviously take the least sane of those options -
+ * following DaveM's lead in c-r4k.c
+ *
+ * It seems we get our kicks from relying on unguaranteed behaviour in GCC
+ */
+static __init void __rm7k_sc_enable(void)
+{
+	int i;
+
+	set_c0_config(1 << 3);				/* CONF_SE */
+
+	write_c0_taglo(0);
+	write_c0_taghi(0);
+
+	for (i = 0; i < scache_size; i += sc_lsize) {
+		__asm__ __volatile__ (
+		      ".set noreorder\n\t"
+		      ".set mips3\n\t"
+		      "cache %1, (%0)\n\t"
+		      ".set mips0\n\t"
+		      ".set reorder"
+		      :
+		      : "r" (KSEG0ADDR(i)), "i" (Index_Store_Tag_SD));
+	}
+}
+
+static __init void rm7k_sc_enable(void)
+{
+	void (*func)(void) = (void *) KSEG1ADDR(&__rm7k_sc_enable);
+
+	if (read_c0_config() & 0x08)			/* CONF_SE */
+		return;
+
+	printk(KERN_INFO "Enabling secondary cache...");
+	func();
+}
+
+static void rm7k_sc_disable(void)
+{
+	clear_c0_config(1<<3);				/* CONF_SE */
+}
+
+struct bcache_ops rm7k_sc_ops = {
+	.bc_enable = rm7k_sc_enable,
+	.bc_disable = rm7k_sc_disable,
+	.bc_wback_inv = rm7k_sc_wback_inv,
+	.bc_inv = rm7k_sc_inv
+};
+
+void __init rm7k_sc_init(void)
+{
+	unsigned int config = read_c0_config();
+
+	if ((config >> 31) & 1)		/* Bit 31 set -> no S-Cache */
+		return;
+
+	printk(KERN_INFO "Secondary cache size %dK, linesize %d bytes.\n",
+	       (scache_size >> 10), sc_lsize);
+
+	if (!((config >> 3) & 1))	/* CONF_SE */
+		rm7k_sc_enable();
+
+	/*
+	 * While we're at it let's deal with the tertiary cache.
+	 */
+	if (!((config >> 17) & 1)) {
+
+		/*
+		 * We can't enable the L3 cache yet. There may be board-specific
+		 * magic necessary to turn it on, and blindly asking the CPU to
+		 * start using it would may give cache errors.
+		 *
+		 * Also, board-specific knowledge may allow us to use the
+		 * CACHE Flash_Invalidate_T instruction if the tag RAM supports
+		 * it, and may specify the size of the L3 cache so we don't have
+		 * to probe it.
+		 */
+		printk(KERN_INFO "Tertiary cache present, %s enabled\n",
+		       config&(1<<12) ? "already" : "not (yet)");
+
+		if ((config >> 12) & 1)
+			rm7k_tcache_enabled = 1;
+	}
+
+	bcops = &rm7k_sc_ops;
+}
diff --git a/arch/mips/mm/tlb-andes.c b/arch/mips/mm/tlb-andes.c
new file mode 100644
index 0000000..167e08e
--- /dev/null
+++ b/arch/mips/mm/tlb-andes.c
@@ -0,0 +1,257 @@
+/*
+ * 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) 1997, 1998, 1999 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 2000 Kanoj Sarcar (kanoj@sgi.com)
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+
+extern void build_tlb_refill_handler(void);
+
+#define NTLB_ENTRIES       64
+#define NTLB_ENTRIES_HALF  32
+
+void local_flush_tlb_all(void)
+{
+	unsigned long flags;
+	unsigned long old_ctx;
+	unsigned long entry;
+
+	local_irq_save(flags);
+	/* Save old context and create impossible VPN2 value */
+	old_ctx = read_c0_entryhi() & ASID_MASK;
+	write_c0_entryhi(CKSEG0);
+	write_c0_entrylo0(0);
+	write_c0_entrylo1(0);
+
+	entry = read_c0_wired();
+
+	/* Blast 'em all away. */
+	while (entry < NTLB_ENTRIES) {
+		write_c0_index(entry);
+		tlb_write_indexed();
+		entry++;
+	}
+	write_c0_entryhi(old_ctx);
+	local_irq_restore(flags);
+}
+
+void local_flush_tlb_mm(struct mm_struct *mm)
+{
+	int cpu = smp_processor_id();
+	if (cpu_context(cpu, mm) != 0) {
+		drop_mmu_context(mm,cpu);
+	}
+}
+
+void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
+                           unsigned long end)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	int cpu = smp_processor_id();
+
+	if (cpu_context(cpu, mm) != 0) {
+		unsigned long flags;
+		int size;
+
+		local_irq_save(flags);
+		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+		size = (size + 1) >> 1;
+		if (size <= NTLB_ENTRIES_HALF) {
+			int oldpid = (read_c0_entryhi() & ASID_MASK);
+			int newpid = (cpu_context(smp_processor_id(), mm)
+				      & ASID_MASK);
+
+			start &= (PAGE_MASK << 1);
+			end += ((PAGE_SIZE << 1) - 1);
+			end &= (PAGE_MASK << 1);
+			while(start < end) {
+				int idx;
+
+				write_c0_entryhi(start | newpid);
+				start += (PAGE_SIZE << 1);
+				tlb_probe();
+				idx = read_c0_index();
+				write_c0_entrylo0(0);
+				write_c0_entrylo1(0);
+				write_c0_entryhi(CKSEG0);
+				if(idx < 0)
+					continue;
+				tlb_write_indexed();
+			}
+			write_c0_entryhi(oldpid);
+		} else {
+			drop_mmu_context(mm, cpu);
+		}
+		local_irq_restore(flags);
+	}
+}
+
+void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+	unsigned long flags;
+	int size;
+
+	size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+	size = (size + 1) >> 1;
+
+	local_irq_save(flags);
+	if (size <= NTLB_ENTRIES_HALF) {
+		int pid = read_c0_entryhi();
+
+		start &= (PAGE_MASK << 1);
+		end += ((PAGE_SIZE << 1) - 1);
+		end &= (PAGE_MASK << 1);
+
+		while (start < end) {
+			int idx;
+
+			write_c0_entryhi(start);
+			start += (PAGE_SIZE << 1);
+			tlb_probe();
+			idx = read_c0_index();
+			write_c0_entrylo0(0);
+			write_c0_entrylo1(0);
+			write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT+1)));
+			if (idx < 0)
+				continue;
+			tlb_write_indexed();
+		}
+		write_c0_entryhi(pid);
+	} else {
+		local_flush_tlb_all();
+	}
+	local_irq_restore(flags);
+}
+
+void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+	if (cpu_context(smp_processor_id(), vma->vm_mm) != 0) {
+		unsigned long flags;
+		int oldpid, newpid, idx;
+
+		newpid = (cpu_context(smp_processor_id(), vma->vm_mm) &
+			  ASID_MASK);
+		page &= (PAGE_MASK << 1);
+		local_irq_save(flags);
+		oldpid = (read_c0_entryhi() & ASID_MASK);
+		write_c0_entryhi(page | newpid);
+		tlb_probe();
+		idx = read_c0_index();
+		write_c0_entrylo0(0);
+		write_c0_entrylo1(0);
+		write_c0_entryhi(CKSEG0);
+		if (idx < 0)
+			goto finish;
+		tlb_write_indexed();
+
+	finish:
+		write_c0_entryhi(oldpid);
+		local_irq_restore(flags);
+	}
+}
+
+/*
+ * This one is only used for pages with the global bit set so we don't care
+ * much about the ASID.
+ */
+void local_flush_tlb_one(unsigned long page)
+{
+	unsigned long flags;
+	int oldpid, idx;
+
+	local_irq_save(flags);
+	page &= (PAGE_MASK << 1);
+	oldpid = read_c0_entryhi() & 0xff;
+	write_c0_entryhi(page);
+	tlb_probe();
+	idx = read_c0_index();
+	write_c0_entrylo0(0);
+	write_c0_entrylo1(0);
+	if (idx >= 0) {
+		/* Make sure all entries differ. */
+		write_c0_entryhi(CKSEG0+(idx<<(PAGE_SHIFT+1)));
+		tlb_write_indexed();
+	}
+	write_c0_entryhi(oldpid);
+
+	local_irq_restore(flags);
+}
+
+/* XXX Simplify this.  On the R10000 writing a TLB entry for an virtual
+   address that already exists will overwrite the old entry and not result
+   in TLB malfunction or TLB shutdown.  */
+void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
+{
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int idx, pid;
+
+	/*
+	 * Handle debugger faulting in for debugee.
+	 */
+	if (current->active_mm != vma->vm_mm)
+		return;
+
+	pid = read_c0_entryhi() & ASID_MASK;
+
+	if ((pid != (cpu_context(smp_processor_id(), vma->vm_mm) & ASID_MASK))
+	    || (cpu_context(smp_processor_id(), vma->vm_mm) == 0)) {
+		printk(KERN_WARNING
+		       "%s: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n",
+		       __FUNCTION__, (int) (cpu_context(smp_processor_id(),
+		       vma->vm_mm) & ASID_MASK), pid);
+	}
+
+	local_irq_save(flags);
+	address &= (PAGE_MASK << 1);
+	write_c0_entryhi(address | (pid));
+	pgdp = pgd_offset(vma->vm_mm, address);
+	tlb_probe();
+	pmdp = pmd_offset(pgdp, address);
+	idx = read_c0_index();
+	ptep = pte_offset_map(pmdp, address);
+	write_c0_entrylo0(pte_val(*ptep++) >> 6);
+	write_c0_entrylo1(pte_val(*ptep) >> 6);
+	write_c0_entryhi(address | pid);
+	if (idx < 0) {
+		tlb_write_random();
+	} else {
+		tlb_write_indexed();
+	}
+	write_c0_entryhi(pid);
+	local_irq_restore(flags);
+}
+
+void __init tlb_init(void)
+{
+	/*
+	 * You should never change this register:
+	 *   - On R4600 1.7 the tlbp never hits for pages smaller than
+	 *     the value in the c0_pagemask register.
+	 *   - The entire mm handling assumes the c0_pagemask register to
+	 *     be set for 4kb pages.
+	 */
+	write_c0_pagemask(PM_4K);
+	write_c0_wired(0);
+	write_c0_framemask(0);
+
+        /* From this point on the ARC firmware is dead.  */
+	local_flush_tlb_all();
+
+	/* Did I tell you that ARC SUCKS?  */
+
+	build_tlb_refill_handler();
+}
diff --git a/arch/mips/mm/tlb-r3k.c b/arch/mips/mm/tlb-r3k.c
new file mode 100644
index 0000000..7948e9a
--- /dev/null
+++ b/arch/mips/mm/tlb-r3k.c
@@ -0,0 +1,289 @@
+/*
+ * r2300.c: R2000 and R3000 specific mmu/cache code.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ *
+ * with a lot of changes to make this thing work for R3000s
+ * Tx39XX R4k style caches added. HK
+ * Copyright (C) 1998, 1999, 2000 Harald Koerfgen
+ * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
+ * Copyright (C) 2002  Ralf Baechle
+ * Copyright (C) 2002  Maciej W. Rozycki
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/mmu_context.h>
+#include <asm/system.h>
+#include <asm/isadep.h>
+#include <asm/io.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+
+#undef DEBUG_TLB
+
+extern void build_tlb_refill_handler(void);
+
+/* CP0 hazard avoidance. */
+#define BARRIER				\
+	__asm__ __volatile__(		\
+		".set	push\n\t"	\
+		".set	noreorder\n\t"	\
+		"nop\n\t"		\
+		".set	pop\n\t")
+
+int r3k_have_wired_reg;		/* should be in cpu_data? */
+
+/* TLB operations. */
+void local_flush_tlb_all(void)
+{
+	unsigned long flags;
+	unsigned long old_ctx;
+	int entry;
+
+#ifdef DEBUG_TLB
+	printk("[tlball]");
+#endif
+
+	local_irq_save(flags);
+	old_ctx = read_c0_entryhi() & ASID_MASK;
+	write_c0_entrylo0(0);
+	entry = r3k_have_wired_reg ? read_c0_wired() : 8;
+	for (; entry < current_cpu_data.tlbsize; entry++) {
+		write_c0_index(entry << 8);
+		write_c0_entryhi((entry | 0x80000) << 12);
+		BARRIER;
+		tlb_write_indexed();
+	}
+	write_c0_entryhi(old_ctx);
+	local_irq_restore(flags);
+}
+
+void local_flush_tlb_mm(struct mm_struct *mm)
+{
+	int cpu = smp_processor_id();
+
+	if (cpu_context(cpu, mm) != 0) {
+#ifdef DEBUG_TLB
+		printk("[tlbmm<%lu>]", (unsigned long)cpu_context(cpu, mm));
+#endif
+		drop_mmu_context(mm, cpu);
+	}
+}
+
+void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
+			   unsigned long end)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	int cpu = smp_processor_id();
+
+	if (cpu_context(cpu, mm) != 0) {
+		unsigned long flags;
+		int size;
+
+#ifdef DEBUG_TLB
+		printk("[tlbrange<%lu,0x%08lx,0x%08lx>]",
+			cpu_context(cpu, mm) & ASID_MASK, start, end);
+#endif
+		local_irq_save(flags);
+		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+		if (size <= current_cpu_data.tlbsize) {
+			int oldpid = read_c0_entryhi() & ASID_MASK;
+			int newpid = cpu_context(cpu, mm) & ASID_MASK;
+
+			start &= PAGE_MASK;
+			end += PAGE_SIZE - 1;
+			end &= PAGE_MASK;
+			while (start < end) {
+				int idx;
+
+				write_c0_entryhi(start | newpid);
+				start += PAGE_SIZE;	/* BARRIER */
+				tlb_probe();
+				idx = read_c0_index();
+				write_c0_entrylo0(0);
+				write_c0_entryhi(KSEG0);
+				if (idx < 0)		/* BARRIER */
+					continue;
+				tlb_write_indexed();
+			}
+			write_c0_entryhi(oldpid);
+		} else {
+			drop_mmu_context(mm, cpu);
+		}
+		local_irq_restore(flags);
+	}
+}
+
+void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+	unsigned long flags;
+	int size;
+
+#ifdef DEBUG_TLB
+	printk("[tlbrange<%lu,0x%08lx,0x%08lx>]", start, end);
+#endif
+	local_irq_save(flags);
+	size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+	if (size <= current_cpu_data.tlbsize) {
+		int pid = read_c0_entryhi();
+
+		start &= PAGE_MASK;
+		end += PAGE_SIZE - 1;
+		end &= PAGE_MASK;
+
+		while (start < end) {
+			int idx;
+
+			write_c0_entryhi(start);
+			start += PAGE_SIZE;		/* BARRIER */
+			tlb_probe();
+			idx = read_c0_index();
+			write_c0_entrylo0(0);
+			write_c0_entryhi(KSEG0);
+			if (idx < 0)			/* BARRIER */
+				continue;
+			tlb_write_indexed();
+		}
+		write_c0_entryhi(pid);
+	} else {
+		local_flush_tlb_all();
+	}
+	local_irq_restore(flags);
+}
+
+void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+	int cpu = smp_processor_id();
+
+	if (!vma || cpu_context(cpu, vma->vm_mm) != 0) {
+		unsigned long flags;
+		int oldpid, newpid, idx;
+
+#ifdef DEBUG_TLB
+		printk("[tlbpage<%lu,0x%08lx>]", cpu_context(cpu, vma->vm_mm), page);
+#endif
+		newpid = cpu_context(cpu, vma->vm_mm) & ASID_MASK;
+		page &= PAGE_MASK;
+		local_irq_save(flags);
+		oldpid = read_c0_entryhi() & ASID_MASK;
+		write_c0_entryhi(page | newpid);
+		BARRIER;
+		tlb_probe();
+		idx = read_c0_index();
+		write_c0_entrylo0(0);
+		write_c0_entryhi(KSEG0);
+		if (idx < 0)				/* BARRIER */
+			goto finish;
+		tlb_write_indexed();
+
+finish:
+		write_c0_entryhi(oldpid);
+		local_irq_restore(flags);
+	}
+}
+
+void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
+{
+	unsigned long flags;
+	int idx, pid;
+
+	/*
+	 * Handle debugger faulting in for debugee.
+	 */
+	if (current->active_mm != vma->vm_mm)
+		return;
+
+	pid = read_c0_entryhi() & ASID_MASK;
+
+#ifdef DEBUG_TLB
+	if ((pid != (cpu_context(cpu, vma->vm_mm) & ASID_MASK)) || (cpu_context(cpu, vma->vm_mm) == 0)) {
+		printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%lu tlbpid=%d\n",
+		       (cpu_context(cpu, vma->vm_mm)), pid);
+	}
+#endif
+
+	local_irq_save(flags);
+	address &= PAGE_MASK;
+	write_c0_entryhi(address | pid);
+	BARRIER;
+	tlb_probe();
+	idx = read_c0_index();
+	write_c0_entrylo0(pte_val(pte));
+	write_c0_entryhi(address | pid);
+	if (idx < 0) {					/* BARRIER */
+		tlb_write_random();
+	} else {
+		tlb_write_indexed();
+	}
+	write_c0_entryhi(pid);
+	local_irq_restore(flags);
+}
+
+void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
+			    unsigned long entryhi, unsigned long pagemask)
+{
+	unsigned long flags;
+	unsigned long old_ctx;
+	static unsigned long wired = 0;
+
+	if (r3k_have_wired_reg) {			/* TX39XX */
+		unsigned long old_pagemask;
+		unsigned long w;
+
+#ifdef DEBUG_TLB
+		printk("[tlbwired<entry lo0 %8x, hi %8x\n, pagemask %8x>]\n",
+		       entrylo0, entryhi, pagemask);
+#endif
+
+		local_irq_save(flags);
+		/* Save old context and create impossible VPN2 value */
+		old_ctx = read_c0_entryhi() & ASID_MASK;
+		old_pagemask = read_c0_pagemask();
+		w = read_c0_wired();
+		write_c0_wired(w + 1);
+		if (read_c0_wired() != w + 1) {
+			printk("[tlbwired] No WIRED reg?\n");
+			return;
+		}
+		write_c0_index(w << 8);
+		write_c0_pagemask(pagemask);
+		write_c0_entryhi(entryhi);
+		write_c0_entrylo0(entrylo0);
+		BARRIER;
+		tlb_write_indexed();
+
+		write_c0_entryhi(old_ctx);
+		write_c0_pagemask(old_pagemask);
+		local_flush_tlb_all();
+		local_irq_restore(flags);
+
+	} else if (wired < 8) {
+#ifdef DEBUG_TLB
+		printk("[tlbwired<entry lo0 %8x, hi %8x\n>]\n",
+		       entrylo0, entryhi);
+#endif
+
+		local_irq_save(flags);
+		old_ctx = read_c0_entryhi() & ASID_MASK;
+		write_c0_entrylo0(entrylo0);
+		write_c0_entryhi(entryhi);
+		write_c0_index(wired);
+		wired++;				/* BARRIER */
+		tlb_write_indexed();
+		write_c0_entryhi(old_ctx);
+		local_flush_tlb_all();
+		local_irq_restore(flags);
+	}
+}
+
+void __init tlb_init(void)
+{
+	local_flush_tlb_all();
+
+	build_tlb_refill_handler();
+}
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
new file mode 100644
index 0000000..59d38bc
--- /dev/null
+++ b/arch/mips/mm/tlb-r4k.c
@@ -0,0 +1,419 @@
+/*
+ * 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) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2002 MIPS Technologies, Inc.  All rights reserved.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+
+extern void build_tlb_refill_handler(void);
+
+/* CP0 hazard avoidance. */
+#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
+				     "nop; nop; nop; nop; nop; nop;\n\t" \
+				     ".set reorder\n\t")
+
+void local_flush_tlb_all(void)
+{
+	unsigned long flags;
+	unsigned long old_ctx;
+	int entry;
+
+	local_irq_save(flags);
+	/* Save old context and create impossible VPN2 value */
+	old_ctx = read_c0_entryhi();
+	write_c0_entrylo0(0);
+	write_c0_entrylo1(0);
+
+	entry = read_c0_wired();
+
+	/* Blast 'em all away. */
+	while (entry < current_cpu_data.tlbsize) {
+		/*
+		 * Make sure all entries differ.  If they're not different
+		 * MIPS32 will take revenge ...
+		 */
+		write_c0_entryhi(CKSEG0 + (entry << (PAGE_SHIFT + 1)));
+		write_c0_index(entry);
+		mtc0_tlbw_hazard();
+		tlb_write_indexed();
+		entry++;
+	}
+	tlbw_use_hazard();
+	write_c0_entryhi(old_ctx);
+	local_irq_restore(flags);
+}
+
+void local_flush_tlb_mm(struct mm_struct *mm)
+{
+	int cpu = smp_processor_id();
+
+	if (cpu_context(cpu, mm) != 0)
+		drop_mmu_context(mm,cpu);
+}
+
+void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
+	unsigned long end)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	int cpu = smp_processor_id();
+
+	if (cpu_context(cpu, mm) != 0) {
+		unsigned long flags;
+		int size;
+
+		local_irq_save(flags);
+		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+		size = (size + 1) >> 1;
+		if (size <= current_cpu_data.tlbsize/2) {
+			int oldpid = read_c0_entryhi();
+			int newpid = cpu_asid(cpu, mm);
+
+			start &= (PAGE_MASK << 1);
+			end += ((PAGE_SIZE << 1) - 1);
+			end &= (PAGE_MASK << 1);
+			while (start < end) {
+				int idx;
+
+				write_c0_entryhi(start | newpid);
+				start += (PAGE_SIZE << 1);
+				mtc0_tlbw_hazard();
+				tlb_probe();
+				BARRIER;
+				idx = read_c0_index();
+				write_c0_entrylo0(0);
+				write_c0_entrylo1(0);
+				if (idx < 0)
+					continue;
+				/* Make sure all entries differ. */
+				write_c0_entryhi(CKSEG0 +
+				                 (idx << (PAGE_SHIFT + 1)));
+				mtc0_tlbw_hazard();
+				tlb_write_indexed();
+			}
+			tlbw_use_hazard();
+			write_c0_entryhi(oldpid);
+		} else {
+			drop_mmu_context(mm, cpu);
+		}
+		local_irq_restore(flags);
+	}
+}
+
+void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+	unsigned long flags;
+	int size;
+
+	local_irq_save(flags);
+	size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+	size = (size + 1) >> 1;
+	if (size <= current_cpu_data.tlbsize / 2) {
+		int pid = read_c0_entryhi();
+
+		start &= (PAGE_MASK << 1);
+		end += ((PAGE_SIZE << 1) - 1);
+		end &= (PAGE_MASK << 1);
+
+		while (start < end) {
+			int idx;
+
+			write_c0_entryhi(start);
+			start += (PAGE_SIZE << 1);
+			mtc0_tlbw_hazard();
+			tlb_probe();
+			BARRIER;
+			idx = read_c0_index();
+			write_c0_entrylo0(0);
+			write_c0_entrylo1(0);
+			if (idx < 0)
+				continue;
+			/* Make sure all entries differ. */
+			write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1)));
+			mtc0_tlbw_hazard();
+			tlb_write_indexed();
+		}
+		tlbw_use_hazard();
+		write_c0_entryhi(pid);
+	} else {
+		local_flush_tlb_all();
+	}
+	local_irq_restore(flags);
+}
+
+void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+	int cpu = smp_processor_id();
+
+	if (cpu_context(cpu, vma->vm_mm) != 0) {
+		unsigned long flags;
+		int oldpid, newpid, idx;
+
+		newpid = cpu_asid(cpu, vma->vm_mm);
+		page &= (PAGE_MASK << 1);
+		local_irq_save(flags);
+		oldpid = read_c0_entryhi();
+		write_c0_entryhi(page | newpid);
+		mtc0_tlbw_hazard();
+		tlb_probe();
+		BARRIER;
+		idx = read_c0_index();
+		write_c0_entrylo0(0);
+		write_c0_entrylo1(0);
+		if (idx < 0)
+			goto finish;
+		/* Make sure all entries differ. */
+		write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1)));
+		mtc0_tlbw_hazard();
+		tlb_write_indexed();
+		tlbw_use_hazard();
+
+	finish:
+		write_c0_entryhi(oldpid);
+		local_irq_restore(flags);
+	}
+}
+
+/*
+ * This one is only used for pages with the global bit set so we don't care
+ * much about the ASID.
+ */
+void local_flush_tlb_one(unsigned long page)
+{
+	unsigned long flags;
+	int oldpid, idx;
+
+	local_irq_save(flags);
+	page &= (PAGE_MASK << 1);
+	oldpid = read_c0_entryhi();
+	write_c0_entryhi(page);
+	mtc0_tlbw_hazard();
+	tlb_probe();
+	BARRIER;
+	idx = read_c0_index();
+	write_c0_entrylo0(0);
+	write_c0_entrylo1(0);
+	if (idx >= 0) {
+		/* Make sure all entries differ. */
+		write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1)));
+		mtc0_tlbw_hazard();
+		tlb_write_indexed();
+		tlbw_use_hazard();
+	}
+	write_c0_entryhi(oldpid);
+
+	local_irq_restore(flags);
+}
+
+/*
+ * We will need multiple versions of update_mmu_cache(), one that just
+ * updates the TLB with the new pte(s), and another which also checks
+ * for the R4k "end of page" hardware bug and does the needy.
+ */
+void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
+{
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int idx, pid;
+
+	/*
+	 * Handle debugger faulting in for debugee.
+	 */
+	if (current->active_mm != vma->vm_mm)
+		return;
+
+	pid = read_c0_entryhi() & ASID_MASK;
+
+	local_irq_save(flags);
+	address &= (PAGE_MASK << 1);
+	write_c0_entryhi(address | pid);
+	pgdp = pgd_offset(vma->vm_mm, address);
+	mtc0_tlbw_hazard();
+	tlb_probe();
+	BARRIER;
+	pmdp = pmd_offset(pgdp, address);
+	idx = read_c0_index();
+	ptep = pte_offset_map(pmdp, address);
+
+ #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+ 	write_c0_entrylo0(ptep->pte_high);
+ 	ptep++;
+ 	write_c0_entrylo1(ptep->pte_high);
+#else
+  	write_c0_entrylo0(pte_val(*ptep++) >> 6);
+  	write_c0_entrylo1(pte_val(*ptep) >> 6);
+#endif
+	write_c0_entryhi(address | pid);
+	mtc0_tlbw_hazard();
+	if (idx < 0)
+		tlb_write_random();
+	else
+		tlb_write_indexed();
+	tlbw_use_hazard();
+	write_c0_entryhi(pid);
+	local_irq_restore(flags);
+}
+
+#if 0
+static void r4k_update_mmu_cache_hwbug(struct vm_area_struct * vma,
+				       unsigned long address, pte_t pte)
+{
+	unsigned long flags;
+	unsigned int asid;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int idx;
+
+	local_irq_save(flags);
+	address &= (PAGE_MASK << 1);
+	asid = read_c0_entryhi() & ASID_MASK;
+	write_c0_entryhi(address | asid);
+	pgdp = pgd_offset(vma->vm_mm, address);
+	mtc0_tlbw_hazard();
+	tlb_probe();
+	BARRIER;
+	pmdp = pmd_offset(pgdp, address);
+	idx = read_c0_index();
+	ptep = pte_offset_map(pmdp, address);
+	write_c0_entrylo0(pte_val(*ptep++) >> 6);
+	write_c0_entrylo1(pte_val(*ptep) >> 6);
+	mtc0_tlbw_hazard();
+	if (idx < 0)
+		tlb_write_random();
+	else
+		tlb_write_indexed();
+	tlbw_use_hazard();
+	local_irq_restore(flags);
+}
+#endif
+
+void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
+	unsigned long entryhi, unsigned long pagemask)
+{
+	unsigned long flags;
+	unsigned long wired;
+	unsigned long old_pagemask;
+	unsigned long old_ctx;
+
+	local_irq_save(flags);
+	/* Save old context and create impossible VPN2 value */
+	old_ctx = read_c0_entryhi();
+	old_pagemask = read_c0_pagemask();
+	wired = read_c0_wired();
+	write_c0_wired(wired + 1);
+	write_c0_index(wired);
+	BARRIER;
+	write_c0_pagemask(pagemask);
+	write_c0_entryhi(entryhi);
+	write_c0_entrylo0(entrylo0);
+	write_c0_entrylo1(entrylo1);
+	mtc0_tlbw_hazard();
+	tlb_write_indexed();
+	tlbw_use_hazard();
+
+	write_c0_entryhi(old_ctx);
+	BARRIER;
+	write_c0_pagemask(old_pagemask);
+	local_flush_tlb_all();
+	local_irq_restore(flags);
+}
+
+/*
+ * Used for loading TLB entries before trap_init() has started, when we
+ * don't actually want to add a wired entry which remains throughout the
+ * lifetime of the system
+ */
+
+static int temp_tlb_entry __initdata;
+
+__init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
+			       unsigned long entryhi, unsigned long pagemask)
+{
+	int ret = 0;
+	unsigned long flags;
+	unsigned long wired;
+	unsigned long old_pagemask;
+	unsigned long old_ctx;
+
+	local_irq_save(flags);
+	/* Save old context and create impossible VPN2 value */
+	old_ctx = read_c0_entryhi();
+	old_pagemask = read_c0_pagemask();
+	wired = read_c0_wired();
+	if (--temp_tlb_entry < wired) {
+		printk(KERN_WARNING "No TLB space left for add_temporary_entry\n");
+		ret = -ENOSPC;
+		goto out;
+	}
+
+	write_c0_index(temp_tlb_entry);
+	write_c0_pagemask(pagemask);
+	write_c0_entryhi(entryhi);
+	write_c0_entrylo0(entrylo0);
+	write_c0_entrylo1(entrylo1);
+	mtc0_tlbw_hazard();
+	tlb_write_indexed();
+	tlbw_use_hazard();
+
+	write_c0_entryhi(old_ctx);
+	write_c0_pagemask(old_pagemask);
+out:
+	local_irq_restore(flags);
+	return ret;
+}
+
+static void __init probe_tlb(unsigned long config)
+{
+	struct cpuinfo_mips *c = &current_cpu_data;
+	unsigned int reg;
+
+	/*
+	 * If this isn't a MIPS32 / MIPS64 compliant CPU.  Config 1 register
+	 * is not supported, we assume R4k style.  Cpu probing already figured
+	 * out the number of tlb entries.
+	 */
+	if ((c->processor_id  & 0xff0000) == PRID_COMP_LEGACY)
+		return;
+
+	reg = read_c0_config1();
+	if (!((config >> 7) & 3))
+		panic("No TLB present");
+
+	c->tlbsize = ((reg >> 25) & 0x3f) + 1;
+}
+
+void __init tlb_init(void)
+{
+	unsigned int config = read_c0_config();
+
+	/*
+	 * You should never change this register:
+	 *   - On R4600 1.7 the tlbp never hits for pages smaller than
+	 *     the value in the c0_pagemask register.
+	 *   - The entire mm handling assumes the c0_pagemask register to
+	 *     be set for 4kb pages.
+	 */
+	probe_tlb(config);
+	write_c0_pagemask(PM_DEFAULT_MASK);
+	write_c0_wired(0);
+	temp_tlb_entry = current_cpu_data.tlbsize - 1;
+	local_flush_tlb_all();
+
+	build_tlb_refill_handler();
+}
diff --git a/arch/mips/mm/tlb-r8k.c b/arch/mips/mm/tlb-r8k.c
new file mode 100644
index 0000000..1bfb091
--- /dev/null
+++ b/arch/mips/mm/tlb-r8k.c
@@ -0,0 +1,250 @@
+/*
+ * 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) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2002 MIPS Technologies, Inc.  All rights reserved.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+
+extern void build_tlb_refill_handler(void);
+
+#define TFP_TLB_SIZE		384
+#define TFP_TLB_SET_SHIFT	7
+
+/* CP0 hazard avoidance. */
+#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
+				     "nop; nop; nop; nop; nop; nop;\n\t" \
+				     ".set reorder\n\t")
+
+void local_flush_tlb_all(void)
+{
+	unsigned long flags;
+	unsigned long old_ctx;
+	int entry;
+
+	local_irq_save(flags);
+	/* Save old context and create impossible VPN2 value */
+	old_ctx = read_c0_entryhi();
+	write_c0_entrylo(0);
+
+	for (entry = 0; entry < TFP_TLB_SIZE; entry++) {
+		write_c0_tlbset(entry >> TFP_TLB_SET_SHIFT);
+		write_c0_vaddr(entry << PAGE_SHIFT);
+		write_c0_entryhi(CKSEG0 + (entry << (PAGE_SHIFT + 1)));
+		mtc0_tlbw_hazard();
+		tlb_write();
+	}
+	tlbw_use_hazard();
+	write_c0_entryhi(old_ctx);
+	local_irq_restore(flags);
+}
+
+void local_flush_tlb_mm(struct mm_struct *mm)
+{
+	int cpu = smp_processor_id();
+
+	if (cpu_context(cpu, mm) != 0)
+		drop_mmu_context(mm,cpu);
+}
+
+void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
+	unsigned long end)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	int cpu = smp_processor_id();
+	unsigned long flags;
+	int oldpid, newpid, size;
+
+	if (!cpu_context(cpu, mm))
+		return;
+
+	size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+	size = (size + 1) >> 1;
+
+	local_irq_save(flags);
+
+	if (size > TFP_TLB_SIZE / 2) {
+		drop_mmu_context(mm, cpu);
+		goto out_restore;
+	}
+
+	oldpid = read_c0_entryhi();
+	newpid = cpu_asid(cpu, mm);
+
+	write_c0_entrylo(0);
+
+	start &= PAGE_MASK;
+	end += (PAGE_SIZE - 1);
+	end &= PAGE_MASK;
+	while (start < end) {
+		signed long idx;
+
+		write_c0_vaddr(start);
+		write_c0_entryhi(start);
+		start += PAGE_SIZE;
+		tlb_probe();
+		idx = read_c0_tlbset();
+		if (idx < 0)
+			continue;
+
+		write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1)));
+		tlb_write();
+	}
+	write_c0_entryhi(oldpid);
+
+out_restore:
+	local_irq_restore(flags);
+}
+
+/* Usable for KV1 addresses only! */
+void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+	unsigned long flags;
+	int size;
+
+	size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+	size = (size + 1) >> 1;
+
+	if (size > TFP_TLB_SIZE / 2) {
+		local_flush_tlb_all();
+		return;
+	}
+
+	local_irq_save(flags);
+
+	write_c0_entrylo(0);
+
+	start &= PAGE_MASK;
+	end += (PAGE_SIZE - 1);
+	end &= PAGE_MASK;
+	while (start < end) {
+		signed long idx;
+
+		write_c0_vaddr(start);
+		write_c0_entryhi(start);
+		start += PAGE_SIZE;
+		tlb_probe();
+		idx = read_c0_tlbset();
+		if (idx < 0)
+			continue;
+
+		write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1)));
+		tlb_write();
+	}
+
+	local_irq_restore(flags);
+}
+
+void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+	int cpu = smp_processor_id();
+	unsigned long flags;
+	int oldpid, newpid;
+	signed long idx;
+
+	if (!cpu_context(cpu, vma->vm_mm))
+		return;
+
+	newpid = cpu_asid(cpu, vma->vm_mm);
+	page &= PAGE_MASK;
+	local_irq_save(flags);
+	oldpid = read_c0_entryhi();
+	write_c0_vaddr(page);
+	write_c0_entryhi(newpid);
+	tlb_probe();
+	idx = read_c0_tlbset();
+	if (idx < 0)
+		goto finish;
+
+	write_c0_entrylo(0);
+	write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1)));
+	tlb_write();
+
+finish:
+	write_c0_entryhi(oldpid);
+	local_irq_restore(flags);
+}
+
+/*
+ * We will need multiple versions of update_mmu_cache(), one that just
+ * updates the TLB with the new pte(s), and another which also checks
+ * for the R4k "end of page" hardware bug and does the needy.
+ */
+void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
+{
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int pid;
+
+	/*
+	 * Handle debugger faulting in for debugee.
+	 */
+	if (current->active_mm != vma->vm_mm)
+		return;
+
+	pid = read_c0_entryhi() & ASID_MASK;
+
+	local_irq_save(flags);
+	address &= PAGE_MASK;
+	write_c0_vaddr(address);
+	write_c0_entryhi(pid);
+	pgdp = pgd_offset(vma->vm_mm, address);
+	pmdp = pmd_offset(pgdp, address);
+	ptep = pte_offset_map(pmdp, address);
+	tlb_probe();
+
+	write_c0_entrylo(pte_val(*ptep++) >> 6);
+	tlb_write();
+
+	write_c0_entryhi(pid);
+	local_irq_restore(flags);
+}
+
+static void __init probe_tlb(unsigned long config)
+{
+	struct cpuinfo_mips *c = &current_cpu_data;
+
+	c->tlbsize = 3 * 128;		/* 3 sets each 128 entries */
+}
+
+void __init tlb_init(void)
+{
+	unsigned int config = read_c0_config();
+	unsigned long status;
+
+	probe_tlb(config);
+
+	status = read_c0_status();
+	status &= ~(ST0_UPS | ST0_KPS);
+#ifdef CONFIG_PAGE_SIZE_4KB
+	status |= (TFP_PAGESIZE_4K << 32) | (TFP_PAGESIZE_4K << 36);
+#elif defined(CONFIG_PAGE_SIZE_8KB)
+	status |= (TFP_PAGESIZE_8K << 32) | (TFP_PAGESIZE_8K << 36);
+#elif defined(CONFIG_PAGE_SIZE_16KB)
+	status |= (TFP_PAGESIZE_16K << 32) | (TFP_PAGESIZE_16K << 36);
+#elif defined(CONFIG_PAGE_SIZE_64KB)
+	status |= (TFP_PAGESIZE_64K << 32) | (TFP_PAGESIZE_64K << 36);
+#endif
+	write_c0_status(status);
+
+	write_c0_wired(0);
+
+	local_flush_tlb_all();
+
+	build_tlb_refill_handler();
+}
diff --git a/arch/mips/mm/tlb-sb1.c b/arch/mips/mm/tlb-sb1.c
new file mode 100644
index 0000000..6256caf
--- /dev/null
+++ b/arch/mips/mm/tlb-sb1.c
@@ -0,0 +1,376 @@
+/*
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+#include <linux/init.h>
+#include <asm/mmu_context.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+
+extern void build_tlb_refill_handler(void);
+
+#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
+
+/* Dump the current entry* and pagemask registers */
+static inline void dump_cur_tlb_regs(void)
+{
+	unsigned int entryhihi, entryhilo, entrylo0hi, entrylo0lo, entrylo1hi;
+	unsigned int entrylo1lo, pagemask;
+
+	__asm__ __volatile__ (
+		".set push             \n"
+		".set noreorder        \n"
+		".set mips64           \n"
+		".set noat             \n"
+		"     tlbr             \n"
+		"     dmfc0  $1, $10   \n"
+		"     dsrl32 %0, $1, 0 \n"
+		"     sll    %1, $1, 0 \n"
+		"     dmfc0  $1, $2    \n"
+		"     dsrl32 %2, $1, 0 \n"
+		"     sll    %3, $1, 0 \n"
+		"     dmfc0  $1, $3    \n"
+		"     dsrl32 %4, $1, 0 \n"
+		"     sll    %5, $1, 0 \n"
+		"     mfc0   %6, $5    \n"
+		".set pop              \n"
+		: "=r" (entryhihi), "=r" (entryhilo),
+		  "=r" (entrylo0hi), "=r" (entrylo0lo),
+		  "=r" (entrylo1hi), "=r" (entrylo1lo),
+		  "=r" (pagemask));
+
+	printk("%08X%08X %08X%08X %08X%08X %08X",
+	       entryhihi, entryhilo,
+	       entrylo0hi, entrylo0lo,
+	       entrylo1hi, entrylo1lo,
+	       pagemask);
+}
+
+void sb1_dump_tlb(void)
+{
+	unsigned long old_ctx;
+	unsigned long flags;
+	int entry;
+	local_irq_save(flags);
+	old_ctx = read_c0_entryhi();
+	printk("Current TLB registers state:\n"
+	       "      EntryHi       EntryLo0          EntryLo1     PageMask  Index\n"
+	       "--------------------------------------------------------------------\n");
+	dump_cur_tlb_regs();
+	printk(" %08X\n", read_c0_index());
+	printk("\n\nFull TLB Dump:\n"
+	       "Idx      EntryHi       EntryLo0          EntryLo1     PageMask\n"
+	       "--------------------------------------------------------------\n");
+	for (entry = 0; entry < current_cpu_data.tlbsize; entry++) {
+		write_c0_index(entry);
+		printk("\n%02i ", entry);
+		dump_cur_tlb_regs();
+	}
+	printk("\n");
+	write_c0_entryhi(old_ctx);
+	local_irq_restore(flags);
+}
+
+void local_flush_tlb_all(void)
+{
+	unsigned long flags;
+	unsigned long old_ctx;
+	int entry;
+
+	local_irq_save(flags);
+	/* Save old context and create impossible VPN2 value */
+	old_ctx = read_c0_entryhi() & ASID_MASK;
+	write_c0_entrylo0(0);
+	write_c0_entrylo1(0);
+
+	entry = read_c0_wired();
+	while (entry < current_cpu_data.tlbsize) {
+		write_c0_entryhi(UNIQUE_ENTRYHI(entry));
+		write_c0_index(entry);
+		tlb_write_indexed();
+		entry++;
+	}
+	write_c0_entryhi(old_ctx);
+	local_irq_restore(flags);
+}
+
+
+/*
+ * Use a bogus region of memory (starting at 0) to sanitize the TLB's.
+ * Use increments of the maximum page size (16MB), and check for duplicate
+ * entries before doing a given write.  Then, when we're safe from collisions
+ * with the firmware, go back and give all the entries invalid addresses with
+ * the normal flush routine.  Wired entries will be killed as well!
+ */
+static void __init sb1_sanitize_tlb(void)
+{
+	int entry;
+	long addr = 0;
+
+	long inc = 1<<24;  /* 16MB */
+	/* Save old context and create impossible VPN2 value */
+	write_c0_entrylo0(0);
+	write_c0_entrylo1(0);
+	for (entry = 0; entry < current_cpu_data.tlbsize; entry++) {
+		do {
+			addr += inc;
+			write_c0_entryhi(addr);
+			tlb_probe();
+		} while ((int)(read_c0_index()) >= 0);
+		write_c0_index(entry);
+		tlb_write_indexed();
+	}
+	/* Now that we know we're safe from collisions, we can safely flush
+	   the TLB with the "normal" routine. */
+	local_flush_tlb_all();
+}
+
+void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
+	unsigned long end)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long flags;
+	int cpu;
+
+	local_irq_save(flags);
+	cpu = smp_processor_id();
+	if (cpu_context(cpu, mm) != 0) {
+		int size;
+		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+		size = (size + 1) >> 1;
+		if (size <= (current_cpu_data.tlbsize/2)) {
+			int oldpid = read_c0_entryhi() & ASID_MASK;
+			int newpid = cpu_asid(cpu, mm);
+
+			start &= (PAGE_MASK << 1);
+			end += ((PAGE_SIZE << 1) - 1);
+			end &= (PAGE_MASK << 1);
+			while (start < end) {
+				int idx;
+
+				write_c0_entryhi(start | newpid);
+				start += (PAGE_SIZE << 1);
+				tlb_probe();
+				idx = read_c0_index();
+				write_c0_entrylo0(0);
+				write_c0_entrylo1(0);
+				write_c0_entryhi(UNIQUE_ENTRYHI(idx));
+				if (idx < 0)
+					continue;
+				tlb_write_indexed();
+			}
+			write_c0_entryhi(oldpid);
+		} else {
+			drop_mmu_context(mm, cpu);
+		}
+	}
+	local_irq_restore(flags);
+}
+
+void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+	unsigned long flags;
+	int size;
+
+	size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+	size = (size + 1) >> 1;
+
+	local_irq_save(flags);
+	if (size <= (current_cpu_data.tlbsize/2)) {
+		int pid = read_c0_entryhi();
+
+		start &= (PAGE_MASK << 1);
+		end += ((PAGE_SIZE << 1) - 1);
+		end &= (PAGE_MASK << 1);
+
+		while (start < end) {
+			int idx;
+
+			write_c0_entryhi(start);
+			start += (PAGE_SIZE << 1);
+			tlb_probe();
+			idx = read_c0_index();
+			write_c0_entrylo0(0);
+			write_c0_entrylo1(0);
+			write_c0_entryhi(UNIQUE_ENTRYHI(idx));
+			if (idx < 0)
+				continue;
+			tlb_write_indexed();
+		}
+		write_c0_entryhi(pid);
+	} else {
+		local_flush_tlb_all();
+	}
+	local_irq_restore(flags);
+}
+
+void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+	unsigned long flags;
+	int cpu = smp_processor_id();
+
+	local_irq_save(flags);
+	if (cpu_context(cpu, vma->vm_mm) != 0) {
+		int oldpid, newpid, idx;
+		newpid = cpu_asid(cpu, vma->vm_mm);
+		page &= (PAGE_MASK << 1);
+		oldpid = read_c0_entryhi() & ASID_MASK;
+		write_c0_entryhi(page | newpid);
+		tlb_probe();
+		idx = read_c0_index();
+		write_c0_entrylo0(0);
+		write_c0_entrylo1(0);
+		if (idx < 0)
+			goto finish;
+		/* Make sure all entries differ. */
+		write_c0_entryhi(UNIQUE_ENTRYHI(idx));
+		tlb_write_indexed();
+	finish:
+		write_c0_entryhi(oldpid);
+	}
+	local_irq_restore(flags);
+}
+
+/*
+ * Remove one kernel space TLB entry.  This entry is assumed to be marked
+ * global so we don't do the ASID thing.
+ */
+void local_flush_tlb_one(unsigned long page)
+{
+	unsigned long flags;
+	int oldpid, idx;
+
+	page &= (PAGE_MASK << 1);
+	oldpid = read_c0_entryhi() & ASID_MASK;
+
+	local_irq_save(flags);
+	write_c0_entryhi(page);
+	tlb_probe();
+	idx = read_c0_index();
+	if (idx >= 0) {
+		/* Make sure all entries differ. */
+		write_c0_entryhi(UNIQUE_ENTRYHI(idx));
+		write_c0_entrylo0(0);
+		write_c0_entrylo1(0);
+		tlb_write_indexed();
+	}
+
+	write_c0_entryhi(oldpid);
+	local_irq_restore(flags);
+}
+
+/* All entries common to a mm share an asid.  To effectively flush
+   these entries, we just bump the asid. */
+void local_flush_tlb_mm(struct mm_struct *mm)
+{
+	int cpu;
+
+	preempt_disable();
+
+	cpu = smp_processor_id();
+
+	if (cpu_context(cpu, mm) != 0) {
+		drop_mmu_context(mm, cpu);
+	}
+
+	preempt_enable();
+}
+
+/* Stolen from mips32 routines */
+
+void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
+{
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int idx, pid;
+
+	/*
+	 * Handle debugger faulting in for debugee.
+	 */
+	if (current->active_mm != vma->vm_mm)
+		return;
+
+	local_irq_save(flags);
+
+	pid = read_c0_entryhi() & ASID_MASK;
+	address &= (PAGE_MASK << 1);
+	write_c0_entryhi(address | (pid));
+	pgdp = pgd_offset(vma->vm_mm, address);
+	tlb_probe();
+	pmdp = pmd_offset(pgdp, address);
+	idx = read_c0_index();
+	ptep = pte_offset_map(pmdp, address);
+	write_c0_entrylo0(pte_val(*ptep++) >> 6);
+	write_c0_entrylo1(pte_val(*ptep) >> 6);
+	if (idx < 0) {
+		tlb_write_random();
+	} else {
+		tlb_write_indexed();
+	}
+	local_irq_restore(flags);
+}
+
+void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
+	unsigned long entryhi, unsigned long pagemask)
+{
+	unsigned long flags;
+	unsigned long wired;
+	unsigned long old_pagemask;
+	unsigned long old_ctx;
+
+	local_irq_save(flags);
+	old_ctx = read_c0_entryhi() & 0xff;
+	old_pagemask = read_c0_pagemask();
+	wired = read_c0_wired();
+	write_c0_wired(wired + 1);
+	write_c0_index(wired);
+
+	write_c0_pagemask(pagemask);
+	write_c0_entryhi(entryhi);
+	write_c0_entrylo0(entrylo0);
+	write_c0_entrylo1(entrylo1);
+	tlb_write_indexed();
+
+	write_c0_entryhi(old_ctx);
+	write_c0_pagemask(old_pagemask);
+
+	local_flush_tlb_all();
+	local_irq_restore(flags);
+}
+
+/*
+ * This is called from loadmmu.c.  We have to set up all the
+ * memory management function pointers, as well as initialize
+ * the caches and tlbs
+ */
+void tlb_init(void)
+{
+	write_c0_pagemask(PM_DEFAULT_MASK);
+	write_c0_wired(0);
+
+	/*
+	 * We don't know what state the firmware left the TLB's in, so this is
+	 * the ultra-conservative way to flush the TLB's and avoid machine
+	 * check exceptions due to duplicate TLB entries
+	 */
+	sb1_sanitize_tlb();
+
+	build_tlb_refill_handler();
+}
diff --git a/arch/mips/mm/tlbex-fault.S b/arch/mips/mm/tlbex-fault.S
new file mode 100644
index 0000000..9e7f417
--- /dev/null
+++ b/arch/mips/mm/tlbex-fault.S
@@ -0,0 +1,28 @@
+/*
+ * 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) 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+	.macro tlb_do_page_fault, write
+	NESTED(tlb_do_page_fault_\write, PT_SIZE, sp)
+	SAVE_ALL
+	MFC0	a2, CP0_BADVADDR
+	KMODE
+	move	a0, sp
+	REG_S	a2, PT_BVADDR(sp)
+	li	a1, \write
+	jal	do_page_fault
+	j	ret_from_exception
+	END(tlb_do_page_fault_\write)
+	.endm
+
+	tlb_do_page_fault 0
+	tlb_do_page_fault 1
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
new file mode 100644
index 0000000..87e229f
--- /dev/null
+++ b/arch/mips/mm/tlbex.c
@@ -0,0 +1,1815 @@
+/*
+ * 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.
+ *
+ * Synthesize TLB refill handlers at runtime.
+ *
+ * Copyright (C) 2004,2005 by Thiemo Seufer
+ */
+
+#include <stdarg.h>
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/init.h>
+
+#include <asm/pgtable.h>
+#include <asm/cacheflush.h>
+#include <asm/mmu_context.h>
+#include <asm/inst.h>
+#include <asm/elf.h>
+#include <asm/smp.h>
+#include <asm/war.h>
+
+/* #define DEBUG_TLB */
+
+static __init int __attribute__((unused)) r45k_bvahwbug(void)
+{
+	/* XXX: We should probe for the presence of this bug, but we don't. */
+	return 0;
+}
+
+static __init int __attribute__((unused)) r4k_250MHZhwbug(void)
+{
+	/* XXX: We should probe for the presence of this bug, but we don't. */
+	return 0;
+}
+
+static __init int __attribute__((unused)) bcm1250_m3_war(void)
+{
+	return BCM1250_M3_WAR;
+}
+
+static __init int __attribute__((unused)) r10000_llsc_war(void)
+{
+	return R10000_LLSC_WAR;
+}
+
+/*
+ * A little micro-assembler, intended for TLB refill handler
+ * synthesizing. It is intentionally kept simple, does only support
+ * a subset of instructions, and does not try to hide pipeline effects
+ * like branch delay slots.
+ */
+
+enum fields
+{
+	RS = 0x001,
+	RT = 0x002,
+	RD = 0x004,
+	RE = 0x008,
+	SIMM = 0x010,
+	UIMM = 0x020,
+	BIMM = 0x040,
+	JIMM = 0x080,
+	FUNC = 0x100,
+};
+
+#define OP_MASK		0x2f
+#define OP_SH		26
+#define RS_MASK		0x1f
+#define RS_SH		21
+#define RT_MASK		0x1f
+#define RT_SH		16
+#define RD_MASK		0x1f
+#define RD_SH		11
+#define RE_MASK		0x1f
+#define RE_SH		6
+#define IMM_MASK	0xffff
+#define IMM_SH		0
+#define JIMM_MASK	0x3ffffff
+#define JIMM_SH		0
+#define FUNC_MASK	0x2f
+#define FUNC_SH		0
+
+enum opcode {
+	insn_invalid,
+	insn_addu, insn_addiu, insn_and, insn_andi, insn_beq,
+	insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl,
+	insn_bne, insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0,
+	insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32,
+	insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld,
+	insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, insn_mtc0,
+	insn_ori, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll,
+	insn_sra, insn_srl, insn_subu, insn_sw, insn_tlbp, insn_tlbwi,
+	insn_tlbwr, insn_xor, insn_xori
+};
+
+struct insn {
+	enum opcode opcode;
+	u32 match;
+	enum fields fields;
+};
+
+/* This macro sets the non-variable bits of an instruction. */
+#define M(a, b, c, d, e, f)					\
+	((a) << OP_SH						\
+	 | (b) << RS_SH						\
+	 | (c) << RT_SH						\
+	 | (d) << RD_SH						\
+	 | (e) << RE_SH						\
+	 | (f) << FUNC_SH)
+
+static __initdata struct insn insn_table[] = {
+	{ insn_addiu, M(addiu_op,0,0,0,0,0), RS | RT | SIMM },
+	{ insn_addu, M(spec_op,0,0,0,0,addu_op), RS | RT | RD },
+	{ insn_and, M(spec_op,0,0,0,0,and_op), RS | RT | RD },
+	{ insn_andi, M(andi_op,0,0,0,0,0), RS | RT | UIMM },
+	{ insn_beq, M(beq_op,0,0,0,0,0), RS | RT | BIMM },
+	{ insn_beql, M(beql_op,0,0,0,0,0), RS | RT | BIMM },
+	{ insn_bgez, M(bcond_op,0,bgez_op,0,0,0), RS | BIMM },
+	{ insn_bgezl, M(bcond_op,0,bgezl_op,0,0,0), RS | BIMM },
+	{ insn_bltz, M(bcond_op,0,bltz_op,0,0,0), RS | BIMM },
+	{ insn_bltzl, M(bcond_op,0,bltzl_op,0,0,0), RS | BIMM },
+	{ insn_bne, M(bne_op,0,0,0,0,0), RS | RT | BIMM },
+	{ insn_daddiu, M(daddiu_op,0,0,0,0,0), RS | RT | SIMM },
+	{ insn_daddu, M(spec_op,0,0,0,0,daddu_op), RS | RT | RD },
+	{ insn_dmfc0, M(cop0_op,dmfc_op,0,0,0,0), RT | RD },
+	{ insn_dmtc0, M(cop0_op,dmtc_op,0,0,0,0), RT | RD },
+	{ insn_dsll, M(spec_op,0,0,0,0,dsll_op), RT | RD | RE },
+	{ insn_dsll32, M(spec_op,0,0,0,0,dsll32_op), RT | RD | RE },
+	{ insn_dsra, M(spec_op,0,0,0,0,dsra_op), RT | RD | RE },
+	{ insn_dsrl, M(spec_op,0,0,0,0,dsrl_op), RT | RD | RE },
+	{ insn_dsrl32, M(spec_op,0,0,0,0,dsrl32_op), RT | RD | RE },
+	{ insn_dsubu, M(spec_op,0,0,0,0,dsubu_op), RS | RT | RD },
+	{ insn_eret, M(cop0_op,cop_op,0,0,0,eret_op), 0 },
+	{ insn_j, M(j_op,0,0,0,0,0), JIMM },
+	{ insn_jal, M(jal_op,0,0,0,0,0), JIMM },
+	{ insn_jr, M(spec_op,0,0,0,0,jr_op), RS },
+	{ insn_ld, M(ld_op,0,0,0,0,0), RS | RT | SIMM },
+	{ insn_ll, M(ll_op,0,0,0,0,0), RS | RT | SIMM },
+	{ insn_lld, M(lld_op,0,0,0,0,0), RS | RT | SIMM },
+	{ insn_lui, M(lui_op,0,0,0,0,0), RT | SIMM },
+	{ insn_lw, M(lw_op,0,0,0,0,0), RS | RT | SIMM },
+	{ insn_mfc0, M(cop0_op,mfc_op,0,0,0,0), RT | RD },
+	{ insn_mtc0, M(cop0_op,mtc_op,0,0,0,0), RT | RD },
+	{ insn_ori, M(ori_op,0,0,0,0,0), RS | RT | UIMM },
+	{ insn_rfe, M(cop0_op,cop_op,0,0,0,rfe_op), 0 },
+	{ insn_sc, M(sc_op,0,0,0,0,0), RS | RT | SIMM },
+	{ insn_scd, M(scd_op,0,0,0,0,0), RS | RT | SIMM },
+	{ insn_sd, M(sd_op,0,0,0,0,0), RS | RT | SIMM },
+	{ insn_sll, M(spec_op,0,0,0,0,sll_op), RT | RD | RE },
+	{ insn_sra, M(spec_op,0,0,0,0,sra_op), RT | RD | RE },
+	{ insn_srl, M(spec_op,0,0,0,0,srl_op), RT | RD | RE },
+	{ insn_subu, M(spec_op,0,0,0,0,subu_op), RS | RT | RD },
+	{ insn_sw, M(sw_op,0,0,0,0,0), RS | RT | SIMM },
+	{ insn_tlbp, M(cop0_op,cop_op,0,0,0,tlbp_op), 0 },
+	{ insn_tlbwi, M(cop0_op,cop_op,0,0,0,tlbwi_op), 0 },
+	{ insn_tlbwr, M(cop0_op,cop_op,0,0,0,tlbwr_op), 0 },
+	{ insn_xor, M(spec_op,0,0,0,0,xor_op), RS | RT | RD },
+	{ insn_xori, M(xori_op,0,0,0,0,0), RS | RT | UIMM },
+	{ insn_invalid, 0, 0 }
+};
+
+#undef M
+
+static __init u32 build_rs(u32 arg)
+{
+	if (arg & ~RS_MASK)
+		printk(KERN_WARNING "TLB synthesizer field overflow\n");
+
+	return (arg & RS_MASK) << RS_SH;
+}
+
+static __init u32 build_rt(u32 arg)
+{
+	if (arg & ~RT_MASK)
+		printk(KERN_WARNING "TLB synthesizer field overflow\n");
+
+	return (arg & RT_MASK) << RT_SH;
+}
+
+static __init u32 build_rd(u32 arg)
+{
+	if (arg & ~RD_MASK)
+		printk(KERN_WARNING "TLB synthesizer field overflow\n");
+
+	return (arg & RD_MASK) << RD_SH;
+}
+
+static __init u32 build_re(u32 arg)
+{
+	if (arg & ~RE_MASK)
+		printk(KERN_WARNING "TLB synthesizer field overflow\n");
+
+	return (arg & RE_MASK) << RE_SH;
+}
+
+static __init u32 build_simm(s32 arg)
+{
+	if (arg > 0x7fff || arg < -0x8000)
+		printk(KERN_WARNING "TLB synthesizer field overflow\n");
+
+	return arg & 0xffff;
+}
+
+static __init u32 build_uimm(u32 arg)
+{
+	if (arg & ~IMM_MASK)
+		printk(KERN_WARNING "TLB synthesizer field overflow\n");
+
+	return arg & IMM_MASK;
+}
+
+static __init u32 build_bimm(s32 arg)
+{
+	if (arg > 0x1ffff || arg < -0x20000)
+		printk(KERN_WARNING "TLB synthesizer field overflow\n");
+
+	if (arg & 0x3)
+		printk(KERN_WARNING "Invalid TLB synthesizer branch target\n");
+
+	return ((arg < 0) ? (1 << 15) : 0) | ((arg >> 2) & 0x7fff);
+}
+
+static __init u32 build_jimm(u32 arg)
+{
+	if (arg & ~((JIMM_MASK) << 2))
+		printk(KERN_WARNING "TLB synthesizer field overflow\n");
+
+	return (arg >> 2) & JIMM_MASK;
+}
+
+static __init u32 build_func(u32 arg)
+{
+	if (arg & ~FUNC_MASK)
+		printk(KERN_WARNING "TLB synthesizer field overflow\n");
+
+	return arg & FUNC_MASK;
+}
+
+/*
+ * The order of opcode arguments is implicitly left to right,
+ * starting with RS and ending with FUNC or IMM.
+ */
+static void __init build_insn(u32 **buf, enum opcode opc, ...)
+{
+	struct insn *ip = NULL;
+	unsigned int i;
+	va_list ap;
+	u32 op;
+
+	for (i = 0; insn_table[i].opcode != insn_invalid; i++)
+		if (insn_table[i].opcode == opc) {
+			ip = &insn_table[i];
+			break;
+		}
+
+	if (!ip)
+		panic("Unsupported TLB synthesizer instruction %d", opc);
+
+	op = ip->match;
+	va_start(ap, opc);
+	if (ip->fields & RS) op |= build_rs(va_arg(ap, u32));
+	if (ip->fields & RT) op |= build_rt(va_arg(ap, u32));
+	if (ip->fields & RD) op |= build_rd(va_arg(ap, u32));
+	if (ip->fields & RE) op |= build_re(va_arg(ap, u32));
+	if (ip->fields & SIMM) op |= build_simm(va_arg(ap, s32));
+	if (ip->fields & UIMM) op |= build_uimm(va_arg(ap, u32));
+	if (ip->fields & BIMM) op |= build_bimm(va_arg(ap, s32));
+	if (ip->fields & JIMM) op |= build_jimm(va_arg(ap, u32));
+	if (ip->fields & FUNC) op |= build_func(va_arg(ap, u32));
+	va_end(ap);
+
+	**buf = op;
+	(*buf)++;
+}
+
+#define I_u1u2u3(op)						\
+	static inline void i##op(u32 **buf, unsigned int a,	\
+	 	unsigned int b, unsigned int c)			\
+	{							\
+		build_insn(buf, insn##op, a, b, c);		\
+	}
+
+#define I_u2u1u3(op)						\
+	static inline void i##op(u32 **buf, unsigned int a,	\
+	 	unsigned int b, unsigned int c)			\
+	{							\
+		build_insn(buf, insn##op, b, a, c);		\
+	}
+
+#define I_u3u1u2(op)						\
+	static inline void i##op(u32 **buf, unsigned int a,	\
+	 	unsigned int b, unsigned int c)			\
+	{							\
+		build_insn(buf, insn##op, b, c, a);		\
+	}
+
+#define I_u1u2s3(op)						\
+	static inline void i##op(u32 **buf, unsigned int a,	\
+	 	unsigned int b, signed int c)			\
+	{							\
+		build_insn(buf, insn##op, a, b, c);		\
+	}
+
+#define I_u2s3u1(op)						\
+	static inline void i##op(u32 **buf, unsigned int a,	\
+	 	signed int b, unsigned int c)			\
+	{							\
+		build_insn(buf, insn##op, c, a, b);		\
+	}
+
+#define I_u2u1s3(op)						\
+	static inline void i##op(u32 **buf, unsigned int a,	\
+	 	unsigned int b, signed int c)			\
+	{							\
+		build_insn(buf, insn##op, b, a, c);		\
+	}
+
+#define I_u1u2(op)						\
+	static inline void i##op(u32 **buf, unsigned int a,	\
+	 	unsigned int b)					\
+	{							\
+		build_insn(buf, insn##op, a, b);		\
+	}
+
+#define I_u1s2(op)						\
+	static inline void i##op(u32 **buf, unsigned int a,	\
+	 	signed int b)					\
+	{							\
+		build_insn(buf, insn##op, a, b);		\
+	}
+
+#define I_u1(op)						\
+	static inline void i##op(u32 **buf, unsigned int a)	\
+	{							\
+		build_insn(buf, insn##op, a);			\
+	}
+
+#define I_0(op)							\
+	static inline void i##op(u32 **buf)			\
+	{							\
+		build_insn(buf, insn##op);			\
+	}
+
+I_u2u1s3(_addiu);
+I_u3u1u2(_addu);
+I_u2u1u3(_andi);
+I_u3u1u2(_and);
+I_u1u2s3(_beq);
+I_u1u2s3(_beql);
+I_u1s2(_bgez);
+I_u1s2(_bgezl);
+I_u1s2(_bltz);
+I_u1s2(_bltzl);
+I_u1u2s3(_bne);
+I_u1u2(_dmfc0);
+I_u1u2(_dmtc0);
+I_u2u1s3(_daddiu);
+I_u3u1u2(_daddu);
+I_u2u1u3(_dsll);
+I_u2u1u3(_dsll32);
+I_u2u1u3(_dsra);
+I_u2u1u3(_dsrl);
+I_u2u1u3(_dsrl32);
+I_u3u1u2(_dsubu);
+I_0(_eret);
+I_u1(_j);
+I_u1(_jal);
+I_u1(_jr);
+I_u2s3u1(_ld);
+I_u2s3u1(_ll);
+I_u2s3u1(_lld);
+I_u1s2(_lui);
+I_u2s3u1(_lw);
+I_u1u2(_mfc0);
+I_u1u2(_mtc0);
+I_u2u1u3(_ori);
+I_0(_rfe);
+I_u2s3u1(_sc);
+I_u2s3u1(_scd);
+I_u2s3u1(_sd);
+I_u2u1u3(_sll);
+I_u2u1u3(_sra);
+I_u2u1u3(_srl);
+I_u3u1u2(_subu);
+I_u2s3u1(_sw);
+I_0(_tlbp);
+I_0(_tlbwi);
+I_0(_tlbwr);
+I_u3u1u2(_xor)
+I_u2u1u3(_xori);
+
+/*
+ * handling labels
+ */
+
+enum label_id {
+	label_invalid,
+	label_second_part,
+	label_leave,
+	label_vmalloc,
+	label_vmalloc_done,
+	label_tlbw_hazard,
+	label_split,
+	label_nopage_tlbl,
+	label_nopage_tlbs,
+	label_nopage_tlbm,
+	label_smp_pgtable_change,
+	label_r3000_write_probe_fail,
+	label_r3000_write_probe_ok
+};
+
+struct label {
+	u32 *addr;
+	enum label_id lab;
+};
+
+static __init void build_label(struct label **lab, u32 *addr,
+			       enum label_id l)
+{
+	(*lab)->addr = addr;
+	(*lab)->lab = l;
+	(*lab)++;
+}
+
+#define L_LA(lb)						\
+	static inline void l##lb(struct label **lab, u32 *addr) \
+	{							\
+		build_label(lab, addr, label##lb);		\
+	}
+
+L_LA(_second_part)
+L_LA(_leave)
+L_LA(_vmalloc)
+L_LA(_vmalloc_done)
+L_LA(_tlbw_hazard)
+L_LA(_split)
+L_LA(_nopage_tlbl)
+L_LA(_nopage_tlbs)
+L_LA(_nopage_tlbm)
+L_LA(_smp_pgtable_change)
+L_LA(_r3000_write_probe_fail)
+L_LA(_r3000_write_probe_ok)
+
+/* convenience macros for instructions */
+#ifdef CONFIG_MIPS64
+# define i_LW(buf, rs, rt, off) i_ld(buf, rs, rt, off)
+# define i_SW(buf, rs, rt, off) i_sd(buf, rs, rt, off)
+# define i_SLL(buf, rs, rt, sh) i_dsll(buf, rs, rt, sh)
+# define i_SRA(buf, rs, rt, sh) i_dsra(buf, rs, rt, sh)
+# define i_SRL(buf, rs, rt, sh) i_dsrl(buf, rs, rt, sh)
+# define i_MFC0(buf, rt, rd) i_dmfc0(buf, rt, rd)
+# define i_MTC0(buf, rt, rd) i_dmtc0(buf, rt, rd)
+# define i_ADDIU(buf, rs, rt, val) i_daddiu(buf, rs, rt, val)
+# define i_ADDU(buf, rs, rt, rd) i_daddu(buf, rs, rt, rd)
+# define i_SUBU(buf, rs, rt, rd) i_dsubu(buf, rs, rt, rd)
+# define i_LL(buf, rs, rt, off) i_lld(buf, rs, rt, off)
+# define i_SC(buf, rs, rt, off) i_scd(buf, rs, rt, off)
+#else
+# define i_LW(buf, rs, rt, off) i_lw(buf, rs, rt, off)
+# define i_SW(buf, rs, rt, off) i_sw(buf, rs, rt, off)
+# define i_SLL(buf, rs, rt, sh) i_sll(buf, rs, rt, sh)
+# define i_SRA(buf, rs, rt, sh) i_sra(buf, rs, rt, sh)
+# define i_SRL(buf, rs, rt, sh) i_srl(buf, rs, rt, sh)
+# define i_MFC0(buf, rt, rd) i_mfc0(buf, rt, rd)
+# define i_MTC0(buf, rt, rd) i_mtc0(buf, rt, rd)
+# define i_ADDIU(buf, rs, rt, val) i_addiu(buf, rs, rt, val)
+# define i_ADDU(buf, rs, rt, rd) i_addu(buf, rs, rt, rd)
+# define i_SUBU(buf, rs, rt, rd) i_subu(buf, rs, rt, rd)
+# define i_LL(buf, rs, rt, off) i_ll(buf, rs, rt, off)
+# define i_SC(buf, rs, rt, off) i_sc(buf, rs, rt, off)
+#endif
+
+#define i_b(buf, off) i_beq(buf, 0, 0, off)
+#define i_beqz(buf, rs, off) i_beq(buf, rs, 0, off)
+#define i_beqzl(buf, rs, off) i_beql(buf, rs, 0, off)
+#define i_bnez(buf, rs, off) i_bne(buf, rs, 0, off)
+#define i_bnezl(buf, rs, off) i_bnel(buf, rs, 0, off)
+#define i_move(buf, a, b) i_ADDU(buf, a, 0, b)
+#define i_nop(buf) i_sll(buf, 0, 0, 0)
+#define i_ssnop(buf) i_sll(buf, 0, 0, 1)
+#define i_ehb(buf) i_sll(buf, 0, 0, 3)
+
+#ifdef CONFIG_MIPS64
+static __init int __attribute__((unused)) in_compat_space_p(long addr)
+{
+	/* Is this address in 32bit compat space? */
+	return (((addr) & 0xffffffff00000000) == 0xffffffff00000000);
+}
+
+static __init int __attribute__((unused)) rel_highest(long val)
+{
+	return ((((val + 0x800080008000L) >> 48) & 0xffff) ^ 0x8000) - 0x8000;
+}
+
+static __init int __attribute__((unused)) rel_higher(long val)
+{
+	return ((((val + 0x80008000L) >> 32) & 0xffff) ^ 0x8000) - 0x8000;
+}
+#endif
+
+static __init int rel_hi(long val)
+{
+	return ((((val + 0x8000L) >> 16) & 0xffff) ^ 0x8000) - 0x8000;
+}
+
+static __init int rel_lo(long val)
+{
+	return ((val & 0xffff) ^ 0x8000) - 0x8000;
+}
+
+static __init void i_LA_mostly(u32 **buf, unsigned int rs, long addr)
+{
+#if CONFIG_MIPS64
+	if (!in_compat_space_p(addr)) {
+		i_lui(buf, rs, rel_highest(addr));
+		if (rel_higher(addr))
+			i_daddiu(buf, rs, rs, rel_higher(addr));
+		if (rel_hi(addr)) {
+			i_dsll(buf, rs, rs, 16);
+			i_daddiu(buf, rs, rs, rel_hi(addr));
+			i_dsll(buf, rs, rs, 16);
+		} else
+			i_dsll32(buf, rs, rs, 0);
+	} else
+#endif
+		i_lui(buf, rs, rel_hi(addr));
+}
+
+static __init void __attribute__((unused)) i_LA(u32 **buf, unsigned int rs,
+						long addr)
+{
+	i_LA_mostly(buf, rs, addr);
+	if (rel_lo(addr))
+		i_ADDIU(buf, rs, rs, rel_lo(addr));
+}
+
+/*
+ * handle relocations
+ */
+
+struct reloc {
+	u32 *addr;
+	unsigned int type;
+	enum label_id lab;
+};
+
+static __init void r_mips_pc16(struct reloc **rel, u32 *addr,
+			       enum label_id l)
+{
+	(*rel)->addr = addr;
+	(*rel)->type = R_MIPS_PC16;
+	(*rel)->lab = l;
+	(*rel)++;
+}
+
+static inline void __resolve_relocs(struct reloc *rel, struct label *lab)
+{
+	long laddr = (long)lab->addr;
+	long raddr = (long)rel->addr;
+
+	switch (rel->type) {
+	case R_MIPS_PC16:
+		*rel->addr |= build_bimm(laddr - (raddr + 4));
+		break;
+
+	default:
+		panic("Unsupported TLB synthesizer relocation %d",
+		      rel->type);
+	}
+}
+
+static __init void resolve_relocs(struct reloc *rel, struct label *lab)
+{
+	struct label *l;
+
+	for (; rel->lab != label_invalid; rel++)
+		for (l = lab; l->lab != label_invalid; l++)
+			if (rel->lab == l->lab)
+				__resolve_relocs(rel, l);
+}
+
+static __init void move_relocs(struct reloc *rel, u32 *first, u32 *end,
+			       long off)
+{
+	for (; rel->lab != label_invalid; rel++)
+		if (rel->addr >= first && rel->addr < end)
+			rel->addr += off;
+}
+
+static __init void move_labels(struct label *lab, u32 *first, u32 *end,
+			       long off)
+{
+	for (; lab->lab != label_invalid; lab++)
+		if (lab->addr >= first && lab->addr < end)
+			lab->addr += off;
+}
+
+static __init void copy_handler(struct reloc *rel, struct label *lab,
+				u32 *first, u32 *end, u32 *target)
+{
+	long off = (long)(target - first);
+
+	memcpy(target, first, (end - first) * sizeof(u32));
+
+	move_relocs(rel, first, end, off);
+	move_labels(lab, first, end, off);
+}
+
+static __init int __attribute__((unused)) insn_has_bdelay(struct reloc *rel,
+							  u32 *addr)
+{
+	for (; rel->lab != label_invalid; rel++) {
+		if (rel->addr == addr
+		    && (rel->type == R_MIPS_PC16
+			|| rel->type == R_MIPS_26))
+			return 1;
+	}
+
+	return 0;
+}
+
+/* convenience functions for labeled branches */
+static void __attribute__((unused)) il_bltz(u32 **p, struct reloc **r,
+					    unsigned int reg, enum label_id l)
+{
+	r_mips_pc16(r, *p, l);
+	i_bltz(p, reg, 0);
+}
+
+static void __attribute__((unused)) il_b(u32 **p, struct reloc **r,
+					 enum label_id l)
+{
+	r_mips_pc16(r, *p, l);
+	i_b(p, 0);
+}
+
+static void il_beqz(u32 **p, struct reloc **r, unsigned int reg,
+		    enum label_id l)
+{
+	r_mips_pc16(r, *p, l);
+	i_beqz(p, reg, 0);
+}
+
+static void __attribute__((unused))
+il_beqzl(u32 **p, struct reloc **r, unsigned int reg, enum label_id l)
+{
+	r_mips_pc16(r, *p, l);
+	i_beqzl(p, reg, 0);
+}
+
+static void il_bnez(u32 **p, struct reloc **r, unsigned int reg,
+		    enum label_id l)
+{
+	r_mips_pc16(r, *p, l);
+	i_bnez(p, reg, 0);
+}
+
+static void il_bgezl(u32 **p, struct reloc **r, unsigned int reg,
+		     enum label_id l)
+{
+	r_mips_pc16(r, *p, l);
+	i_bgezl(p, reg, 0);
+}
+
+/* The only general purpose registers allowed in TLB handlers. */
+#define K0		26
+#define K1		27
+
+/* Some CP0 registers */
+#define C0_INDEX	0
+#define C0_ENTRYLO0	2
+#define C0_ENTRYLO1	3
+#define C0_CONTEXT	4
+#define C0_BADVADDR	8
+#define C0_ENTRYHI	10
+#define C0_EPC		14
+#define C0_XCONTEXT	20
+
+#ifdef CONFIG_MIPS64
+# define GET_CONTEXT(buf, reg) i_MFC0(buf, reg, C0_XCONTEXT)
+#else
+# define GET_CONTEXT(buf, reg) i_MFC0(buf, reg, C0_CONTEXT)
+#endif
+
+/* The worst case length of the handler is around 18 instructions for
+ * R3000-style TLBs and up to 63 instructions for R4000-style TLBs.
+ * Maximum space available is 32 instructions for R3000 and 64
+ * instructions for R4000.
+ *
+ * We deliberately chose a buffer size of 128, so we won't scribble
+ * over anything important on overflow before we panic.
+ */
+static __initdata u32 tlb_handler[128];
+
+/* simply assume worst case size for labels and relocs */
+static __initdata struct label labels[128];
+static __initdata struct reloc relocs[128];
+
+/*
+ * The R3000 TLB handler is simple.
+ */
+static void __init build_r3000_tlb_refill_handler(void)
+{
+	long pgdc = (long)pgd_current;
+	u32 *p;
+
+	memset(tlb_handler, 0, sizeof(tlb_handler));
+	p = tlb_handler;
+
+	i_mfc0(&p, K0, C0_BADVADDR);
+	i_lui(&p, K1, rel_hi(pgdc)); /* cp0 delay */
+	i_lw(&p, K1, rel_lo(pgdc), K1);
+	i_srl(&p, K0, K0, 22); /* load delay */
+	i_sll(&p, K0, K0, 2);
+	i_addu(&p, K1, K1, K0);
+	i_mfc0(&p, K0, C0_CONTEXT);
+	i_lw(&p, K1, 0, K1); /* cp0 delay */
+	i_andi(&p, K0, K0, 0xffc); /* load delay */
+	i_addu(&p, K1, K1, K0);
+	i_lw(&p, K0, 0, K1);
+	i_nop(&p); /* load delay */
+	i_mtc0(&p, K0, C0_ENTRYLO0);
+	i_mfc0(&p, K1, C0_EPC); /* cp0 delay */
+	i_tlbwr(&p); /* cp0 delay */
+	i_jr(&p, K1);
+	i_rfe(&p); /* branch delay */
+
+	if (p > tlb_handler + 32)
+		panic("TLB refill handler space exceeded");
+
+	printk("Synthesized TLB handler (%u instructions).\n",
+	       (unsigned int)(p - tlb_handler));
+#ifdef DEBUG_TLB
+	{
+		int i;
+
+		for (i = 0; i < (p - tlb_handler); i++)
+			printk("%08x\n", tlb_handler[i]);
+	}
+#endif
+
+	memcpy((void *)CAC_BASE, tlb_handler, 0x80);
+	flush_icache_range(CAC_BASE, CAC_BASE + 0x80);
+}
+
+/*
+ * The R4000 TLB handler is much more complicated. We have two
+ * consecutive handler areas with 32 instructions space each.
+ * Since they aren't used at the same time, we can overflow in the
+ * other one.To keep things simple, we first assume linear space,
+ * then we relocate it to the final handler layout as needed.
+ */
+static __initdata u32 final_handler[64];
+
+/*
+ * Hazards
+ *
+ * From the IDT errata for the QED RM5230 (Nevada), processor revision 1.0:
+ * 2. A timing hazard exists for the TLBP instruction.
+ *
+ *      stalling_instruction
+ *      TLBP
+ *
+ * The JTLB is being read for the TLBP throughout the stall generated by the
+ * previous instruction. This is not really correct as the stalling instruction
+ * can modify the address used to access the JTLB.  The failure symptom is that
+ * the TLBP instruction will use an address created for the stalling instruction
+ * and not the address held in C0_ENHI and thus report the wrong results.
+ *
+ * The software work-around is to not allow the instruction preceding the TLBP
+ * to stall - make it an NOP or some other instruction guaranteed not to stall.
+ *
+ * Errata 2 will not be fixed.  This errata is also on the R5000.
+ *
+ * As if we MIPS hackers wouldn't know how to nop pipelines happy ...
+ */
+static __init void __attribute__((unused)) build_tlb_probe_entry(u32 **p)
+{
+	switch (current_cpu_data.cputype) {
+	case CPU_R5000:
+	case CPU_R5000A:
+	case CPU_NEVADA:
+		i_nop(p);
+		i_tlbp(p);
+		break;
+
+	default:
+		i_tlbp(p);
+		break;
+	}
+}
+
+/*
+ * Write random or indexed TLB entry, and care about the hazards from
+ * the preceeding mtc0 and for the following eret.
+ */
+enum tlb_write_entry { tlb_random, tlb_indexed };
+
+static __init void build_tlb_write_entry(u32 **p, struct label **l,
+					 struct reloc **r,
+					 enum tlb_write_entry wmode)
+{
+	void(*tlbw)(u32 **) = NULL;
+
+	switch (wmode) {
+	case tlb_random: tlbw = i_tlbwr; break;
+	case tlb_indexed: tlbw = i_tlbwi; break;
+	}
+
+	switch (current_cpu_data.cputype) {
+	case CPU_R4000PC:
+	case CPU_R4000SC:
+	case CPU_R4000MC:
+	case CPU_R4400PC:
+	case CPU_R4400SC:
+	case CPU_R4400MC:
+		/*
+		 * This branch uses up a mtc0 hazard nop slot and saves
+		 * two nops after the tlbw instruction.
+		 */
+		il_bgezl(p, r, 0, label_tlbw_hazard);
+		tlbw(p);
+		l_tlbw_hazard(l, *p);
+		i_nop(p);
+		break;
+
+	case CPU_R4600:
+	case CPU_R4700:
+	case CPU_R5000:
+	case CPU_R5000A:
+	case CPU_5KC:
+	case CPU_TX49XX:
+	case CPU_AU1000:
+	case CPU_AU1100:
+	case CPU_AU1500:
+	case CPU_AU1550:
+		i_nop(p);
+		tlbw(p);
+		break;
+
+	case CPU_R10000:
+	case CPU_R12000:
+	case CPU_4KC:
+	case CPU_SB1:
+	case CPU_4KSC:
+	case CPU_20KC:
+	case CPU_25KF:
+		tlbw(p);
+		break;
+
+	case CPU_NEVADA:
+		i_nop(p); /* QED specifies 2 nops hazard */
+		/*
+		 * This branch uses up a mtc0 hazard nop slot and saves
+		 * a nop after the tlbw instruction.
+		 */
+		il_bgezl(p, r, 0, label_tlbw_hazard);
+		tlbw(p);
+		l_tlbw_hazard(l, *p);
+		break;
+
+	case CPU_RM7000:
+		i_nop(p);
+		i_nop(p);
+		i_nop(p);
+		i_nop(p);
+		tlbw(p);
+		break;
+
+	case CPU_4KEC:
+	case CPU_24K:
+		i_ehb(p);
+		tlbw(p);
+		break;
+
+	case CPU_RM9000:
+		/*
+		 * When the JTLB is updated by tlbwi or tlbwr, a subsequent
+		 * use of the JTLB for instructions should not occur for 4
+		 * cpu cycles and use for data translations should not occur
+		 * for 3 cpu cycles.
+		 */
+		i_ssnop(p);
+		i_ssnop(p);
+		i_ssnop(p);
+		i_ssnop(p);
+		tlbw(p);
+		i_ssnop(p);
+		i_ssnop(p);
+		i_ssnop(p);
+		i_ssnop(p);
+		break;
+
+	case CPU_VR4111:
+	case CPU_VR4121:
+	case CPU_VR4122:
+	case CPU_VR4181:
+	case CPU_VR4181A:
+		i_nop(p);
+		i_nop(p);
+		tlbw(p);
+		i_nop(p);
+		i_nop(p);
+		break;
+
+	case CPU_VR4131:
+	case CPU_VR4133:
+		i_nop(p);
+		i_nop(p);
+		tlbw(p);
+		break;
+
+	default:
+		panic("No TLB refill handler yet (CPU type: %d)",
+		      current_cpu_data.cputype);
+		break;
+	}
+}
+
+#ifdef CONFIG_MIPS64
+/*
+ * TMP and PTR are scratch.
+ * TMP will be clobbered, PTR will hold the pmd entry.
+ */
+static __init void
+build_get_pmde64(u32 **p, struct label **l, struct reloc **r,
+		 unsigned int tmp, unsigned int ptr)
+{
+	long pgdc = (long)pgd_current;
+
+	/*
+	 * The vmalloc handling is not in the hotpath.
+	 */
+	i_dmfc0(p, tmp, C0_BADVADDR);
+	il_bltz(p, r, tmp, label_vmalloc);
+	/* No i_nop needed here, since the next insn doesn't touch TMP. */
+
+#ifdef CONFIG_SMP
+	/*
+	 * 64 bit SMP has the lower part of &pgd_current[smp_processor_id()]
+	 * stored in CONTEXT.
+	 */
+	if (in_compat_space_p(pgdc)) {
+		i_dmfc0(p, ptr, C0_CONTEXT);
+		i_dsra(p, ptr, ptr, 23);
+		i_ld(p, ptr, 0, ptr);
+	} else {
+#ifdef CONFIG_BUILD_ELF64
+		i_dmfc0(p, ptr, C0_CONTEXT);
+		i_dsrl(p, ptr, ptr, 23);
+		i_dsll(p, ptr, ptr, 3);
+		i_LA_mostly(p, tmp, pgdc);
+		i_daddu(p, ptr, ptr, tmp);
+		i_dmfc0(p, tmp, C0_BADVADDR);
+		i_ld(p, ptr, rel_lo(pgdc), ptr);
+#else
+		i_dmfc0(p, ptr, C0_CONTEXT);
+		i_lui(p, tmp, rel_highest(pgdc));
+		i_dsll(p, ptr, ptr, 9);
+		i_daddiu(p, tmp, tmp, rel_higher(pgdc));
+		i_dsrl32(p, ptr, ptr, 0);
+		i_and(p, ptr, ptr, tmp);
+		i_dmfc0(p, tmp, C0_BADVADDR);
+		i_ld(p, ptr, 0, ptr);
+#endif
+	}
+#else
+	i_LA_mostly(p, ptr, pgdc);
+	i_ld(p, ptr, rel_lo(pgdc), ptr);
+#endif
+
+	l_vmalloc_done(l, *p);
+	i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3); /* get pgd offset in bytes */
+	i_andi(p, tmp, tmp, (PTRS_PER_PGD - 1)<<3);
+	i_daddu(p, ptr, ptr, tmp); /* add in pgd offset */
+	i_dmfc0(p, tmp, C0_BADVADDR); /* get faulting address */
+	i_ld(p, ptr, 0, ptr); /* get pmd pointer */
+	i_dsrl(p, tmp, tmp, PMD_SHIFT-3); /* get pmd offset in bytes */
+	i_andi(p, tmp, tmp, (PTRS_PER_PMD - 1)<<3);
+	i_daddu(p, ptr, ptr, tmp); /* add in pmd offset */
+}
+
+/*
+ * BVADDR is the faulting address, PTR is scratch.
+ * PTR will hold the pgd for vmalloc.
+ */
+static __init void
+build_get_pgd_vmalloc64(u32 **p, struct label **l, struct reloc **r,
+			unsigned int bvaddr, unsigned int ptr)
+{
+	long swpd = (long)swapper_pg_dir;
+
+	l_vmalloc(l, *p);
+	i_LA(p, ptr, VMALLOC_START);
+	i_dsubu(p, bvaddr, bvaddr, ptr);
+
+	if (in_compat_space_p(swpd) && !rel_lo(swpd)) {
+		il_b(p, r, label_vmalloc_done);
+		i_lui(p, ptr, rel_hi(swpd));
+	} else {
+		i_LA_mostly(p, ptr, swpd);
+		il_b(p, r, label_vmalloc_done);
+		i_daddiu(p, ptr, ptr, rel_lo(swpd));
+	}
+}
+
+#else /* !CONFIG_MIPS64 */
+
+/*
+ * TMP and PTR are scratch.
+ * TMP will be clobbered, PTR will hold the pgd entry.
+ */
+static __init void __attribute__((unused))
+build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
+{
+	long pgdc = (long)pgd_current;
+
+	/* 32 bit SMP has smp_processor_id() stored in CONTEXT. */
+#ifdef CONFIG_SMP
+	i_mfc0(p, ptr, C0_CONTEXT);
+	i_LA_mostly(p, tmp, pgdc);
+	i_srl(p, ptr, ptr, 23);
+	i_sll(p, ptr, ptr, 2);
+	i_addu(p, ptr, tmp, ptr);
+#else
+	i_LA_mostly(p, ptr, pgdc);
+#endif
+	i_mfc0(p, tmp, C0_BADVADDR); /* get faulting address */
+	i_lw(p, ptr, rel_lo(pgdc), ptr);
+	i_srl(p, tmp, tmp, PGDIR_SHIFT); /* get pgd only bits */
+	i_sll(p, tmp, tmp, PGD_T_LOG2);
+	i_addu(p, ptr, ptr, tmp); /* add in pgd offset */
+}
+
+#endif /* !CONFIG_MIPS64 */
+
+static __init void build_adjust_context(u32 **p, unsigned int ctx)
+{
+	unsigned int shift = 4 - (PTE_T_LOG2 + 1);
+	unsigned int mask = (PTRS_PER_PTE / 2 - 1) << (PTE_T_LOG2 + 1);
+
+	switch (current_cpu_data.cputype) {
+	case CPU_VR41XX:
+	case CPU_VR4111:
+	case CPU_VR4121:
+	case CPU_VR4122:
+	case CPU_VR4131:
+	case CPU_VR4181:
+	case CPU_VR4181A:
+	case CPU_VR4133:
+		shift += 2;
+		break;
+
+	default:
+		break;
+	}
+
+	if (shift)
+		i_SRL(p, ctx, ctx, shift);
+	i_andi(p, ctx, ctx, mask);
+}
+
+static __init void build_get_ptep(u32 **p, unsigned int tmp, unsigned int ptr)
+{
+	/*
+	 * Bug workaround for the Nevada. It seems as if under certain
+	 * circumstances the move from cp0_context might produce a
+	 * bogus result when the mfc0 instruction and its consumer are
+	 * in a different cacheline or a load instruction, probably any
+	 * memory reference, is between them.
+	 */
+	switch (current_cpu_data.cputype) {
+	case CPU_NEVADA:
+		i_LW(p, ptr, 0, ptr);
+		GET_CONTEXT(p, tmp); /* get context reg */
+		break;
+
+	default:
+		GET_CONTEXT(p, tmp); /* get context reg */
+		i_LW(p, ptr, 0, ptr);
+		break;
+	}
+
+	build_adjust_context(p, tmp);
+	i_ADDU(p, ptr, ptr, tmp); /* add in offset */
+}
+
+static __init void build_update_entries(u32 **p, unsigned int tmp,
+					unsigned int ptep)
+{
+	/*
+	 * 64bit address support (36bit on a 32bit CPU) in a 32bit
+	 * Kernel is a special case. Only a few CPUs use it.
+	 */
+#ifdef CONFIG_64BIT_PHYS_ADDR
+	if (cpu_has_64bits) {
+		i_ld(p, tmp, 0, ptep); /* get even pte */
+		i_ld(p, ptep, sizeof(pte_t), ptep); /* get odd pte */
+		i_dsrl(p, tmp, tmp, 6); /* convert to entrylo0 */
+		i_mtc0(p, tmp, C0_ENTRYLO0); /* load it */
+		i_dsrl(p, ptep, ptep, 6); /* convert to entrylo1 */
+		i_mtc0(p, ptep, C0_ENTRYLO1); /* load it */
+	} else {
+		int pte_off_even = sizeof(pte_t) / 2;
+		int pte_off_odd = pte_off_even + sizeof(pte_t);
+
+		/* The pte entries are pre-shifted */
+		i_lw(p, tmp, pte_off_even, ptep); /* get even pte */
+		i_mtc0(p, tmp, C0_ENTRYLO0); /* load it */
+		i_lw(p, ptep, pte_off_odd, ptep); /* get odd pte */
+		i_mtc0(p, ptep, C0_ENTRYLO1); /* load it */
+	}
+#else
+	i_LW(p, tmp, 0, ptep); /* get even pte */
+	i_LW(p, ptep, sizeof(pte_t), ptep); /* get odd pte */
+	if (r45k_bvahwbug())
+		build_tlb_probe_entry(p);
+	i_SRL(p, tmp, tmp, 6); /* convert to entrylo0 */
+	if (r4k_250MHZhwbug())
+		i_mtc0(p, 0, C0_ENTRYLO0);
+	i_mtc0(p, tmp, C0_ENTRYLO0); /* load it */
+	i_SRL(p, ptep, ptep, 6); /* convert to entrylo1 */
+	if (r45k_bvahwbug())
+		i_mfc0(p, tmp, C0_INDEX);
+	if (r4k_250MHZhwbug())
+		i_mtc0(p, 0, C0_ENTRYLO1);
+	i_mtc0(p, ptep, C0_ENTRYLO1); /* load it */
+#endif
+}
+
+static void __init build_r4000_tlb_refill_handler(void)
+{
+	u32 *p = tlb_handler;
+	struct label *l = labels;
+	struct reloc *r = relocs;
+	u32 *f;
+	unsigned int final_len;
+
+	memset(tlb_handler, 0, sizeof(tlb_handler));
+	memset(labels, 0, sizeof(labels));
+	memset(relocs, 0, sizeof(relocs));
+	memset(final_handler, 0, sizeof(final_handler));
+
+	/*
+	 * create the plain linear handler
+	 */
+	if (bcm1250_m3_war()) {
+		i_MFC0(&p, K0, C0_BADVADDR);
+		i_MFC0(&p, K1, C0_ENTRYHI);
+		i_xor(&p, K0, K0, K1);
+		i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
+		il_bnez(&p, &r, K0, label_leave);
+		/* No need for i_nop */
+	}
+
+#ifdef CONFIG_MIPS64
+	build_get_pmde64(&p, &l, &r, K0, K1); /* get pmd in K1 */
+#else
+	build_get_pgde32(&p, K0, K1); /* get pgd in K1 */
+#endif
+
+	build_get_ptep(&p, K0, K1);
+	build_update_entries(&p, K0, K1);
+	build_tlb_write_entry(&p, &l, &r, tlb_random);
+	l_leave(&l, p);
+	i_eret(&p); /* return from trap */
+
+#ifdef CONFIG_MIPS64
+	build_get_pgd_vmalloc64(&p, &l, &r, K0, K1);
+#endif
+
+	/*
+	 * Overflow check: For the 64bit handler, we need at least one
+	 * free instruction slot for the wrap-around branch. In worst
+	 * case, if the intended insertion point is a delay slot, we
+	 * need three, with the the second nop'ed and the third being
+	 * unused.
+	 */
+#ifdef CONFIG_MIPS32
+	if ((p - tlb_handler) > 64)
+		panic("TLB refill handler space exceeded");
+#else
+	if (((p - tlb_handler) > 63)
+	    || (((p - tlb_handler) > 61)
+		&& insn_has_bdelay(relocs, tlb_handler + 29)))
+		panic("TLB refill handler space exceeded");
+#endif
+
+	/*
+	 * Now fold the handler in the TLB refill handler space.
+	 */
+#ifdef CONFIG_MIPS32
+	f = final_handler;
+	/* Simplest case, just copy the handler. */
+	copy_handler(relocs, labels, tlb_handler, p, f);
+	final_len = p - tlb_handler;
+#else /* CONFIG_MIPS64 */
+	f = final_handler + 32;
+	if ((p - tlb_handler) <= 32) {
+		/* Just copy the handler. */
+		copy_handler(relocs, labels, tlb_handler, p, f);
+		final_len = p - tlb_handler;
+	} else {
+		u32 *split = tlb_handler + 30;
+
+		/*
+		 * Find the split point.
+		 */
+		if (insn_has_bdelay(relocs, split - 1))
+			split--;
+
+		/* Copy first part of the handler. */
+		copy_handler(relocs, labels, tlb_handler, split, f);
+		f += split - tlb_handler;
+
+		/* Insert branch. */
+		l_split(&l, final_handler);
+		il_b(&f, &r, label_split);
+		if (insn_has_bdelay(relocs, split))
+			i_nop(&f);
+		else {
+			copy_handler(relocs, labels, split, split + 1, f);
+			move_labels(labels, f, f + 1, -1);
+			f++;
+			split++;
+		}
+
+		/* Copy the rest of the handler. */
+		copy_handler(relocs, labels, split, p, final_handler);
+		final_len = (f - (final_handler + 32)) + (p - split);
+	}
+#endif /* CONFIG_MIPS64 */
+
+	resolve_relocs(relocs, labels);
+	printk("Synthesized TLB refill handler (%u instructions).\n",
+	       final_len);
+
+#ifdef DEBUG_TLB
+	{
+		int i;
+
+		for (i = 0; i < 64; i++)
+			printk("%08x\n", final_handler[i]);
+	}
+#endif
+
+	memcpy((void *)CAC_BASE, final_handler, 0x100);
+	flush_icache_range(CAC_BASE, CAC_BASE + 0x100);
+}
+
+/*
+ * TLB load/store/modify handlers.
+ *
+ * Only the fastpath gets synthesized at runtime, the slowpath for
+ * do_page_fault remains normal asm.
+ */
+extern void tlb_do_page_fault_0(void);
+extern void tlb_do_page_fault_1(void);
+
+#define __tlb_handler_align \
+	__attribute__((__aligned__(1 << CONFIG_MIPS_L1_CACHE_SHIFT)))
+
+/*
+ * 128 instructions for the fastpath handler is generous and should
+ * never be exceeded.
+ */
+#define FASTPATH_SIZE 128
+
+u32 __tlb_handler_align handle_tlbl[FASTPATH_SIZE];
+u32 __tlb_handler_align handle_tlbs[FASTPATH_SIZE];
+u32 __tlb_handler_align handle_tlbm[FASTPATH_SIZE];
+
+static void __init
+iPTE_LW(u32 **p, struct label **l, unsigned int pte, int offset,
+	unsigned int ptr)
+{
+#ifdef CONFIG_SMP
+# ifdef CONFIG_64BIT_PHYS_ADDR
+	if (cpu_has_64bits)
+		i_lld(p, pte, offset, ptr);
+	else
+# endif
+		i_LL(p, pte, offset, ptr);
+#else
+# ifdef CONFIG_64BIT_PHYS_ADDR
+	if (cpu_has_64bits)
+		i_ld(p, pte, offset, ptr);
+	else
+# endif
+		i_LW(p, pte, offset, ptr);
+#endif
+}
+
+static void __init
+iPTE_SW(u32 **p, struct reloc **r, unsigned int pte, int offset,
+	unsigned int ptr)
+{
+#ifdef CONFIG_SMP
+# ifdef CONFIG_64BIT_PHYS_ADDR
+	if (cpu_has_64bits)
+		i_scd(p, pte, offset, ptr);
+	else
+# endif
+		i_SC(p, pte, offset, ptr);
+
+	if (r10000_llsc_war())
+		il_beqzl(p, r, pte, label_smp_pgtable_change);
+	else
+		il_beqz(p, r, pte, label_smp_pgtable_change);
+
+# ifdef CONFIG_64BIT_PHYS_ADDR
+	if (!cpu_has_64bits) {
+		/* no i_nop needed */
+		i_ll(p, pte, sizeof(pte_t) / 2, ptr);
+		i_ori(p, pte, pte, _PAGE_VALID);
+		i_sc(p, pte, sizeof(pte_t) / 2, ptr);
+		il_beqz(p, r, pte, label_smp_pgtable_change);
+		/* no i_nop needed */
+		i_lw(p, pte, 0, ptr);
+	} else
+		i_nop(p);
+# else
+	i_nop(p);
+# endif
+#else
+# ifdef CONFIG_64BIT_PHYS_ADDR
+	if (cpu_has_64bits)
+		i_sd(p, pte, offset, ptr);
+	else
+# endif
+		i_SW(p, pte, offset, ptr);
+
+# ifdef CONFIG_64BIT_PHYS_ADDR
+	if (!cpu_has_64bits) {
+		i_lw(p, pte, sizeof(pte_t) / 2, ptr);
+		i_ori(p, pte, pte, _PAGE_VALID);
+		i_sw(p, pte, sizeof(pte_t) / 2, ptr);
+		i_lw(p, pte, 0, ptr);
+	}
+# endif
+#endif
+}
+
+/*
+ * Check if PTE is present, if not then jump to LABEL. PTR points to
+ * the page table where this PTE is located, PTE will be re-loaded
+ * with it's original value.
+ */
+static void __init
+build_pte_present(u32 **p, struct label **l, struct reloc **r,
+		  unsigned int pte, unsigned int ptr, enum label_id lid)
+{
+	i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
+	i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
+	il_bnez(p, r, pte, lid);
+	iPTE_LW(p, l, pte, 0, ptr);
+}
+
+/* Make PTE valid, store result in PTR. */
+static void __init
+build_make_valid(u32 **p, struct reloc **r, unsigned int pte,
+		 unsigned int ptr)
+{
+	i_ori(p, pte, pte, _PAGE_VALID | _PAGE_ACCESSED);
+	iPTE_SW(p, r, pte, 0, ptr);
+}
+
+/*
+ * Check if PTE can be written to, if not branch to LABEL. Regardless
+ * restore PTE with value from PTR when done.
+ */
+static void __init
+build_pte_writable(u32 **p, struct label **l, struct reloc **r,
+		   unsigned int pte, unsigned int ptr, enum label_id lid)
+{
+	i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
+	i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
+	il_bnez(p, r, pte, lid);
+	iPTE_LW(p, l, pte, 0, ptr);
+}
+
+/* Make PTE writable, update software status bits as well, then store
+ * at PTR.
+ */
+static void __init
+build_make_write(u32 **p, struct reloc **r, unsigned int pte,
+		 unsigned int ptr)
+{
+	i_ori(p, pte, pte,
+	      _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY);
+	iPTE_SW(p, r, pte, 0, ptr);
+}
+
+/*
+ * Check if PTE can be modified, if not branch to LABEL. Regardless
+ * restore PTE with value from PTR when done.
+ */
+static void __init
+build_pte_modifiable(u32 **p, struct label **l, struct reloc **r,
+		     unsigned int pte, unsigned int ptr, enum label_id lid)
+{
+	i_andi(p, pte, pte, _PAGE_WRITE);
+	il_beqz(p, r, pte, lid);
+	iPTE_LW(p, l, pte, 0, ptr);
+}
+
+/*
+ * R3000 style TLB load/store/modify handlers.
+ */
+
+/* This places the pte in the page table at PTR into ENTRYLO0. */
+static void __init
+build_r3000_pte_reload(u32 **p, unsigned int ptr)
+{
+	i_lw(p, ptr, 0, ptr);
+	i_nop(p); /* load delay */
+	i_mtc0(p, ptr, C0_ENTRYLO0);
+	i_nop(p); /* cp0 delay */
+}
+
+/*
+ * The index register may have the probe fail bit set,
+ * because we would trap on access kseg2, i.e. without refill.
+ */
+static void __init
+build_r3000_tlb_write(u32 **p, struct label **l, struct reloc **r,
+		      unsigned int tmp)
+{
+	i_mfc0(p, tmp, C0_INDEX);
+	i_nop(p); /* cp0 delay */
+	il_bltz(p, r, tmp, label_r3000_write_probe_fail);
+	i_nop(p); /* branch delay */
+	i_tlbwi(p);
+	il_b(p, r, label_r3000_write_probe_ok);
+	i_nop(p); /* branch delay */
+	l_r3000_write_probe_fail(l, *p);
+	i_tlbwr(p);
+	l_r3000_write_probe_ok(l, *p);
+}
+
+static void __init
+build_r3000_tlbchange_handler_head(u32 **p, unsigned int pte,
+				   unsigned int ptr)
+{
+	long pgdc = (long)pgd_current;
+
+	i_mfc0(p, pte, C0_BADVADDR);
+	i_lui(p, ptr, rel_hi(pgdc)); /* cp0 delay */
+	i_lw(p, ptr, rel_lo(pgdc), ptr);
+	i_srl(p, pte, pte, 22); /* load delay */
+	i_sll(p, pte, pte, 2);
+	i_addu(p, ptr, ptr, pte);
+	i_mfc0(p, pte, C0_CONTEXT);
+	i_lw(p, ptr, 0, ptr); /* cp0 delay */
+	i_andi(p, pte, pte, 0xffc); /* load delay */
+	i_addu(p, ptr, ptr, pte);
+	i_lw(p, pte, 0, ptr);
+	i_nop(p); /* load delay */
+	i_tlbp(p);
+}
+
+static void __init
+build_r3000_tlbchange_handler_tail(u32 **p, unsigned int tmp)
+{
+	i_mfc0(p, tmp, C0_EPC);
+	i_nop(p); /* cp0 delay */
+	i_jr(p, tmp);
+	i_rfe(p); /* branch delay */
+}
+
+static void __init build_r3000_tlb_load_handler(void)
+{
+	u32 *p = handle_tlbl;
+	struct label *l = labels;
+	struct reloc *r = relocs;
+
+	memset(handle_tlbl, 0, sizeof(handle_tlbl));
+	memset(labels, 0, sizeof(labels));
+	memset(relocs, 0, sizeof(relocs));
+
+	build_r3000_tlbchange_handler_head(&p, K0, K1);
+	build_pte_present(&p, &l, &r, K0, K1, label_nopage_tlbl);
+	build_make_valid(&p, &r, K0, K1);
+	build_r3000_pte_reload(&p, K1);
+	build_r3000_tlb_write(&p, &l, &r, K0);
+	build_r3000_tlbchange_handler_tail(&p, K0);
+
+	l_nopage_tlbl(&l, p);
+	i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
+	i_nop(&p);
+
+	if ((p - handle_tlbl) > FASTPATH_SIZE)
+		panic("TLB load handler fastpath space exceeded");
+
+	resolve_relocs(relocs, labels);
+	printk("Synthesized TLB load handler fastpath (%u instructions).\n",
+	       (unsigned int)(p - handle_tlbl));
+
+#ifdef DEBUG_TLB
+	{
+		int i;
+
+		for (i = 0; i < FASTPATH_SIZE; i++)
+			printk("%08x\n", handle_tlbl[i]);
+	}
+#endif
+
+	flush_icache_range((unsigned long)handle_tlbl,
+			   (unsigned long)handle_tlbl + FASTPATH_SIZE * sizeof(u32));
+}
+
+static void __init build_r3000_tlb_store_handler(void)
+{
+	u32 *p = handle_tlbs;
+	struct label *l = labels;
+	struct reloc *r = relocs;
+
+	memset(handle_tlbs, 0, sizeof(handle_tlbs));
+	memset(labels, 0, sizeof(labels));
+	memset(relocs, 0, sizeof(relocs));
+
+	build_r3000_tlbchange_handler_head(&p, K0, K1);
+	build_pte_writable(&p, &l, &r, K0, K1, label_nopage_tlbs);
+	build_make_write(&p, &r, K0, K1);
+	build_r3000_pte_reload(&p, K1);
+	build_r3000_tlb_write(&p, &l, &r, K0);
+	build_r3000_tlbchange_handler_tail(&p, K0);
+
+	l_nopage_tlbs(&l, p);
+	i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
+	i_nop(&p);
+
+	if ((p - handle_tlbs) > FASTPATH_SIZE)
+		panic("TLB store handler fastpath space exceeded");
+
+	resolve_relocs(relocs, labels);
+	printk("Synthesized TLB store handler fastpath (%u instructions).\n",
+	       (unsigned int)(p - handle_tlbs));
+
+#ifdef DEBUG_TLB
+	{
+		int i;
+
+		for (i = 0; i < FASTPATH_SIZE; i++)
+			printk("%08x\n", handle_tlbs[i]);
+	}
+#endif
+
+	flush_icache_range((unsigned long)handle_tlbs,
+			   (unsigned long)handle_tlbs + FASTPATH_SIZE * sizeof(u32));
+}
+
+static void __init build_r3000_tlb_modify_handler(void)
+{
+	u32 *p = handle_tlbm;
+	struct label *l = labels;
+	struct reloc *r = relocs;
+
+	memset(handle_tlbm, 0, sizeof(handle_tlbm));
+	memset(labels, 0, sizeof(labels));
+	memset(relocs, 0, sizeof(relocs));
+
+	build_r3000_tlbchange_handler_head(&p, K0, K1);
+	build_pte_modifiable(&p, &l, &r, K0, K1, label_nopage_tlbm);
+	build_make_write(&p, &r, K0, K1);
+	build_r3000_pte_reload(&p, K1);
+	i_tlbwi(&p);
+	build_r3000_tlbchange_handler_tail(&p, K0);
+
+	l_nopage_tlbm(&l, p);
+	i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
+	i_nop(&p);
+
+	if ((p - handle_tlbm) > FASTPATH_SIZE)
+		panic("TLB modify handler fastpath space exceeded");
+
+	resolve_relocs(relocs, labels);
+	printk("Synthesized TLB modify handler fastpath (%u instructions).\n",
+	       (unsigned int)(p - handle_tlbm));
+
+#ifdef DEBUG_TLB
+	{
+		int i;
+
+		for (i = 0; i < FASTPATH_SIZE; i++)
+			printk("%08x\n", handle_tlbm[i]);
+	}
+#endif
+
+	flush_icache_range((unsigned long)handle_tlbm,
+			   (unsigned long)handle_tlbm + FASTPATH_SIZE * sizeof(u32));
+}
+
+/*
+ * R4000 style TLB load/store/modify handlers.
+ */
+static void __init
+build_r4000_tlbchange_handler_head(u32 **p, struct label **l,
+				   struct reloc **r, unsigned int pte,
+				   unsigned int ptr)
+{
+#ifdef CONFIG_MIPS64
+	build_get_pmde64(p, l, r, pte, ptr); /* get pmd in ptr */
+#else
+	build_get_pgde32(p, pte, ptr); /* get pgd in ptr */
+#endif
+
+	i_MFC0(p, pte, C0_BADVADDR);
+	i_LW(p, ptr, 0, ptr);
+	i_SRL(p, pte, pte, PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2);
+	i_andi(p, pte, pte, (PTRS_PER_PTE - 1) << PTE_T_LOG2);
+	i_ADDU(p, ptr, ptr, pte);
+
+#ifdef CONFIG_SMP
+	l_smp_pgtable_change(l, *p);
+# endif
+	iPTE_LW(p, l, pte, 0, ptr); /* get even pte */
+	build_tlb_probe_entry(p);
+}
+
+static void __init
+build_r4000_tlbchange_handler_tail(u32 **p, struct label **l,
+				   struct reloc **r, unsigned int tmp,
+				   unsigned int ptr)
+{
+	i_ori(p, ptr, ptr, sizeof(pte_t));
+	i_xori(p, ptr, ptr, sizeof(pte_t));
+	build_update_entries(p, tmp, ptr);
+	build_tlb_write_entry(p, l, r, tlb_indexed);
+	l_leave(l, *p);
+	i_eret(p); /* return from trap */
+
+#ifdef CONFIG_MIPS64
+	build_get_pgd_vmalloc64(p, l, r, tmp, ptr);
+#endif
+}
+
+static void __init build_r4000_tlb_load_handler(void)
+{
+	u32 *p = handle_tlbl;
+	struct label *l = labels;
+	struct reloc *r = relocs;
+
+	memset(handle_tlbl, 0, sizeof(handle_tlbl));
+	memset(labels, 0, sizeof(labels));
+	memset(relocs, 0, sizeof(relocs));
+
+	if (bcm1250_m3_war()) {
+		i_MFC0(&p, K0, C0_BADVADDR);
+		i_MFC0(&p, K1, C0_ENTRYHI);
+		i_xor(&p, K0, K0, K1);
+		i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
+		il_bnez(&p, &r, K0, label_leave);
+		/* No need for i_nop */
+	}
+
+	build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
+	build_pte_present(&p, &l, &r, K0, K1, label_nopage_tlbl);
+	build_make_valid(&p, &r, K0, K1);
+	build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
+
+	l_nopage_tlbl(&l, p);
+	i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
+	i_nop(&p);
+
+	if ((p - handle_tlbl) > FASTPATH_SIZE)
+		panic("TLB load handler fastpath space exceeded");
+
+	resolve_relocs(relocs, labels);
+	printk("Synthesized TLB load handler fastpath (%u instructions).\n",
+	       (unsigned int)(p - handle_tlbl));
+
+#ifdef DEBUG_TLB
+	{
+		int i;
+
+		for (i = 0; i < FASTPATH_SIZE; i++)
+			printk("%08x\n", handle_tlbl[i]);
+	}
+#endif
+
+	flush_icache_range((unsigned long)handle_tlbl,
+			   (unsigned long)handle_tlbl + FASTPATH_SIZE * sizeof(u32));
+}
+
+static void __init build_r4000_tlb_store_handler(void)
+{
+	u32 *p = handle_tlbs;
+	struct label *l = labels;
+	struct reloc *r = relocs;
+
+	memset(handle_tlbs, 0, sizeof(handle_tlbs));
+	memset(labels, 0, sizeof(labels));
+	memset(relocs, 0, sizeof(relocs));
+
+	build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
+	build_pte_writable(&p, &l, &r, K0, K1, label_nopage_tlbs);
+	build_make_write(&p, &r, K0, K1);
+	build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
+
+	l_nopage_tlbs(&l, p);
+	i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
+	i_nop(&p);
+
+	if ((p - handle_tlbs) > FASTPATH_SIZE)
+		panic("TLB store handler fastpath space exceeded");
+
+	resolve_relocs(relocs, labels);
+	printk("Synthesized TLB store handler fastpath (%u instructions).\n",
+	       (unsigned int)(p - handle_tlbs));
+
+#ifdef DEBUG_TLB
+	{
+		int i;
+
+		for (i = 0; i < FASTPATH_SIZE; i++)
+			printk("%08x\n", handle_tlbs[i]);
+	}
+#endif
+
+	flush_icache_range((unsigned long)handle_tlbs,
+			   (unsigned long)handle_tlbs + FASTPATH_SIZE * sizeof(u32));
+}
+
+static void __init build_r4000_tlb_modify_handler(void)
+{
+	u32 *p = handle_tlbm;
+	struct label *l = labels;
+	struct reloc *r = relocs;
+
+	memset(handle_tlbm, 0, sizeof(handle_tlbm));
+	memset(labels, 0, sizeof(labels));
+	memset(relocs, 0, sizeof(relocs));
+
+	build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
+	build_pte_modifiable(&p, &l, &r, K0, K1, label_nopage_tlbm);
+	/* Present and writable bits set, set accessed and dirty bits. */
+	build_make_write(&p, &r, K0, K1);
+	build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
+
+	l_nopage_tlbm(&l, p);
+	i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
+	i_nop(&p);
+
+	if ((p - handle_tlbm) > FASTPATH_SIZE)
+		panic("TLB modify handler fastpath space exceeded");
+
+	resolve_relocs(relocs, labels);
+	printk("Synthesized TLB modify handler fastpath (%u instructions).\n",
+	       (unsigned int)(p - handle_tlbm));
+
+#ifdef DEBUG_TLB
+	{
+		int i;
+
+		for (i = 0; i < FASTPATH_SIZE; i++)
+			printk("%08x\n", handle_tlbm[i]);
+	}
+#endif
+
+	flush_icache_range((unsigned long)handle_tlbm,
+			   (unsigned long)handle_tlbm + FASTPATH_SIZE * sizeof(u32));
+}
+
+void __init build_tlb_refill_handler(void)
+{
+	/*
+	 * The refill handler is generated per-CPU, multi-node systems
+	 * may have local storage for it. The other handlers are only
+	 * needed once.
+	 */
+	static int run_once = 0;
+
+	switch (current_cpu_data.cputype) {
+	case CPU_R2000:
+	case CPU_R3000:
+	case CPU_R3000A:
+	case CPU_R3081E:
+	case CPU_TX3912:
+	case CPU_TX3922:
+	case CPU_TX3927:
+		build_r3000_tlb_refill_handler();
+		if (!run_once) {
+			build_r3000_tlb_load_handler();
+			build_r3000_tlb_store_handler();
+			build_r3000_tlb_modify_handler();
+			run_once++;
+		}
+		break;
+
+	case CPU_R6000:
+	case CPU_R6000A:
+		panic("No R6000 TLB refill handler yet");
+		break;
+
+	case CPU_R8000:
+		panic("No R8000 TLB refill handler yet");
+		break;
+
+	default:
+		build_r4000_tlb_refill_handler();
+		if (!run_once) {
+			build_r4000_tlb_load_handler();
+			build_r4000_tlb_store_handler();
+			build_r4000_tlb_modify_handler();
+			run_once++;
+		}
+	}
+}
diff --git a/arch/mips/momentum/jaguar_atx/Makefile b/arch/mips/momentum/jaguar_atx/Makefile
new file mode 100644
index 0000000..20bbd3e
--- /dev/null
+++ b/arch/mips/momentum/jaguar_atx/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for Momentum Computer's Jaguar-ATX board.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+obj-y += int-handler.o irq.o prom.o reset.o setup.o
+
+obj-$(CONFIG_SERIAL_8250_CONSOLE) += ja-console.o
+obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o
diff --git a/arch/mips/momentum/jaguar_atx/dbg_io.c b/arch/mips/momentum/jaguar_atx/dbg_io.c
new file mode 100644
index 0000000..542eac8
--- /dev/null
+++ b/arch/mips/momentum/jaguar_atx/dbg_io.c
@@ -0,0 +1,126 @@
+#include <linux/config.h>
+
+#if defined(CONFIG_REMOTE_DEBUG)
+
+#include <asm/serial.h> /* For the serial port location and base baud */
+
+/* --- CONFIG --- */
+
+typedef unsigned char uint8;
+typedef unsigned int uint32;
+
+/* --- END OF CONFIG --- */
+
+#define         UART16550_BAUD_2400             2400
+#define         UART16550_BAUD_4800             4800
+#define         UART16550_BAUD_9600             9600
+#define         UART16550_BAUD_19200            19200
+#define         UART16550_BAUD_38400            38400
+#define         UART16550_BAUD_57600            57600
+#define         UART16550_BAUD_115200           115200
+
+#define         UART16550_PARITY_NONE           0
+#define         UART16550_PARITY_ODD            0x08
+#define         UART16550_PARITY_EVEN           0x18
+#define         UART16550_PARITY_MARK           0x28
+#define         UART16550_PARITY_SPACE          0x38
+
+#define         UART16550_DATA_5BIT             0x0
+#define         UART16550_DATA_6BIT             0x1
+#define         UART16550_DATA_7BIT             0x2
+#define         UART16550_DATA_8BIT             0x3
+
+#define         UART16550_STOP_1BIT             0x0
+#define         UART16550_STOP_2BIT             0x4
+
+/* ----------------------------------------------------- */
+
+/* === CONFIG === */
+
+/* [jsun] we use the second serial port for kdb */
+#define         BASE                    OCELOT_SERIAL1_BASE
+#define         MAX_BAUD                OCELOT_BASE_BAUD
+
+/* === END OF CONFIG === */
+
+#define         REG_OFFSET              4
+
+/* register offset */
+#define         OFS_RCV_BUFFER          0
+#define         OFS_TRANS_HOLD          0
+#define         OFS_SEND_BUFFER         0
+#define         OFS_INTR_ENABLE         (1*REG_OFFSET)
+#define         OFS_INTR_ID             (2*REG_OFFSET)
+#define         OFS_DATA_FORMAT         (3*REG_OFFSET)
+#define         OFS_LINE_CONTROL        (3*REG_OFFSET)
+#define         OFS_MODEM_CONTROL       (4*REG_OFFSET)
+#define         OFS_RS232_OUTPUT        (4*REG_OFFSET)
+#define         OFS_LINE_STATUS         (5*REG_OFFSET)
+#define         OFS_MODEM_STATUS        (6*REG_OFFSET)
+#define         OFS_RS232_INPUT         (6*REG_OFFSET)
+#define         OFS_SCRATCH_PAD         (7*REG_OFFSET)
+
+#define         OFS_DIVISOR_LSB         (0*REG_OFFSET)
+#define         OFS_DIVISOR_MSB         (1*REG_OFFSET)
+
+
+/* memory-mapped read/write of the port */
+#define         UART16550_READ(y)    (*((volatile uint8*)(BASE + y)))
+#define         UART16550_WRITE(y, z)  ((*((volatile uint8*)(BASE + y))) = z)
+
+void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
+{
+	/* disable interrupts */
+	UART16550_WRITE(OFS_INTR_ENABLE, 0);
+
+	/* set up buad rate */
+	{
+		uint32 divisor;
+
+		/* set DIAB bit */
+		UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
+
+		/* set divisor */
+		divisor = MAX_BAUD / baud;
+		UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
+		UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
+
+		/* clear DIAB bit */
+		UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
+	}
+
+	/* set data format */
+	UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
+}
+
+static int remoteDebugInitialized = 0;
+
+uint8 getDebugChar(void)
+{
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(UART16550_BAUD_38400,
+			  UART16550_DATA_8BIT,
+			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+	}
+
+	while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
+	return UART16550_READ(OFS_RCV_BUFFER);
+}
+
+
+int putDebugChar(uint8 byte)
+{
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(UART16550_BAUD_38400,
+			  UART16550_DATA_8BIT,
+			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+	}
+
+	while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
+	UART16550_WRITE(OFS_SEND_BUFFER, byte);
+	return 1;
+}
+
+#endif
diff --git a/arch/mips/momentum/jaguar_atx/int-handler.S b/arch/mips/momentum/jaguar_atx/int-handler.S
new file mode 100644
index 0000000..43fd5a5
--- /dev/null
+++ b/arch/mips/momentum/jaguar_atx/int-handler.S
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2002 Momentum Computer Inc.
+ * Author: Matthew Dharm <mdharm@momenco.com>
+ *
+ * Based on work:
+ *   Copyright 2001 MontaVista Software Inc.
+ *   Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * First-level interrupt dispatcher for Jaguar-ATX board.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/*
+ * First level interrupt dispatcher for Ocelot-CS board
+ */
+		.align	5
+		NESTED(jaguar_handle_int, PT_SIZE, sp)
+		SAVE_ALL
+		CLI
+		.set	at
+		mfc0	t0, CP0_CAUSE  
+		mfc0	t2, CP0_STATUS
+
+		and	t0, t2
+        
+		andi	t1, t0, STATUSF_IP0	/* sw0 software interrupt */
+		bnez	t1, ll_sw0_irq
+		andi	t1, t0, STATUSF_IP1	/* sw1 software interrupt */
+		bnez	t1, ll_sw1_irq
+		andi	t1, t0, STATUSF_IP2	/* int0 hardware line */
+		bnez	t1, ll_pcixa_irq
+		andi	t1, t0, STATUSF_IP3	/* int1 hardware line */
+		bnez	t1, ll_pcixb_irq
+		andi	t1, t0, STATUSF_IP4	/* int2 hardware line */
+		bnez	t1, ll_pcia_irq
+		andi	t1, t0, STATUSF_IP5	/* int3 hardware line */
+		bnez	t1, ll_pcib_irq
+		andi	t1, t0, STATUSF_IP6	/* int4 hardware line */
+		bnez	t1, ll_uart_irq
+		andi	t1, t0, STATUSF_IP7	/* cpu timer */
+		bnez	t1, ll_cputimer_irq
+
+		nop
+		nop
+
+		/* now look at extended interrupts */
+		mfc0	t0, CP0_CAUSE
+		cfc0	t1, CP0_S1_INTCONTROL
+
+		/* shift the mask 8 bits left to line up the bits */
+		sll	t2, t1, 8
+
+		and	t0, t2
+		srl	t0, t0, 16
+
+		andi	t1, t0, STATUSF_IP8	/* int6 hardware line */
+		bnez	t1, ll_mv64340_decode_irq
+
+		nop
+		nop
+
+		.set	reorder
+
+		/* wrong alarm or masked ... */
+		j	spurious_interrupt
+		nop
+		END(jaguar_handle_int)
+
+		.align	5
+ll_sw0_irq:
+		li	a0, 0
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+ll_sw1_irq:
+		li	a0, 1
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+ll_pcixa_irq:
+		li	a0, 2
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_pcixb_irq:
+		li	a0, 3
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_pcia_irq:
+		li	a0, 4
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+	
+ll_pcib_irq:
+		li	a0, 5
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+	
+ll_uart_irq:
+		li	a0, 6
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+	
+ll_cputimer_irq:
+		li	a0, 7
+		move	a1, sp
+		jal	ll_timer_interrupt
+		j	ret_from_irq
+	
+ll_mv64340_decode_irq:
+		move	a0, sp
+		jal	ll_mv64340_irq
+		j	ret_from_irq
diff --git a/arch/mips/momentum/jaguar_atx/irq.c b/arch/mips/momentum/jaguar_atx/irq.c
new file mode 100644
index 0000000..15588f9
--- /dev/null
+++ b/arch/mips/momentum/jaguar_atx/irq.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2002 Momentum Computer, Inc.
+ * Author: Matthew Dharm, mdharm@momenco.com
+ *
+ * Based on work by:
+ *   Copyright (C) 2000 RidgeRun, Inc.
+ *   Author: RidgeRun, Inc.
+ *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ *   Copyright 2001 MontaVista Software Inc.
+ *   Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ *   Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/signal.h>
+#include <linux/types.h>
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+
+extern asmlinkage void jaguar_handle_int(void);
+
+static struct irqaction cascade_mv64340 = {
+	no_action, SA_INTERRUPT, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL
+};
+
+void __init arch_init_irq(void)
+{
+	/*
+	 * Clear all of the interrupts while we change the able around a bit.
+	 * int-handler is not on bootstrap
+	 */
+	clear_c0_status(ST0_IM);
+
+	/* Sets the first-level interrupt dispatcher. */
+	set_except_vector(0, jaguar_handle_int);
+	mips_cpu_irq_init(0);
+	rm7k_cpu_irq_init(8);
+
+	/* set up the cascading interrupts */
+	setup_irq(8, &cascade_mv64340);
+
+	mv64340_irq_init(16);
+
+	set_c0_status(ST0_IM);
+}
diff --git a/arch/mips/momentum/jaguar_atx/ja-console.c b/arch/mips/momentum/jaguar_atx/ja-console.c
new file mode 100644
index 0000000..da6e1ed
--- /dev/null
+++ b/arch/mips/momentum/jaguar_atx/ja-console.c
@@ -0,0 +1,106 @@
+/*
+ * 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) 2001, 2002, 2004 Ralf Baechle
+ */
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/kdev_t.h>
+#include <linux/major.h>
+#include <linux/termios.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <asm/serial.h>
+
+/* SUPERIO uart register map */
+struct ja_uartregs {
+	union {
+		volatile u8	pad0[3];
+		volatile u8	rbr;	/* read only, DLAB == 0 */
+		volatile u8	pad1[3];
+		volatile u8	thr;	/* write only, DLAB == 0 */
+		volatile u8	pad2[3];
+		volatile u8	dll;	/* DLAB == 1 */
+	} u1;
+	union {
+		volatile u8	pad0[3];
+		volatile u8	ier;	/* DLAB == 0 */
+		volatile u8	pad1[3];
+		volatile u8	dlm;	/* DLAB == 1 */
+	} u2;
+	union {
+		volatile u8	pad0[3];
+		volatile u8	iir;	/* read only */
+		volatile u8	pad1[3];
+		volatile u8	fcr;	/* write only */
+	} u3;
+	volatile u8	pad0[3];
+	volatile u8	iu_lcr;
+	volatile u8	pad1[3];
+	volatile u8	iu_mcr;
+	volatile u8	pad2[3];
+	volatile u8	iu_lsr;
+	volatile u8	pad3[3];
+	volatile u8	iu_msr;
+	volatile u8	pad4[3];
+	volatile u8	iu_scr;
+} ja_uregs_t;
+
+#define iu_rbr u1.rbr
+#define iu_thr u1.thr
+#define iu_dll u1.dll
+#define iu_ier u2.ier
+#define iu_dlm u2.dlm
+#define iu_iir u3.iir
+#define iu_fcr u3.fcr
+
+extern unsigned long uart_base;
+
+static inline struct ja_uartregs *console_uart(void)
+{
+	return (struct ja_uartregs *) (uart_base + 0x23UL);
+}
+
+void prom_putchar(char c)
+{
+	struct ja_uartregs *uart = console_uart();
+
+	while ((uart->iu_lsr & 0x20) == 0);
+	uart->iu_thr = c;
+}
+
+char __init prom_getchar(void)
+{
+	return 0;
+}
+
+static void inline ja_console_probe(void)
+{
+	struct uart_port up;
+
+	/*
+	 * Register to interrupt zero because we share the interrupt with
+	 * the serial driver which we don't properly support yet.
+	 */
+	memset(&up, 0, sizeof(up));
+	up.membase	= (unsigned char *) uart_base + 0x23UL;
+	up.irq		= JAGUAR_ATX_SERIAL1_IRQ;
+	up.uartclk	= JAGUAR_ATX_UART_CLK;
+	up.regshift	= 2;
+	up.iotype	= UPIO_MEM;
+	up.flags	= ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+	up.line		= 0;
+
+	if (early_serial_setup(&up))
+		printk(KERN_ERR "Early serial init of port 0 failed\n");
+}
+
+__init void ja_setup_console(void)
+{
+	ja_console_probe();
+}
diff --git a/arch/mips/momentum/jaguar_atx/jaguar_atx_fpga.h b/arch/mips/momentum/jaguar_atx/jaguar_atx_fpga.h
new file mode 100644
index 0000000..6978654
--- /dev/null
+++ b/arch/mips/momentum/jaguar_atx/jaguar_atx_fpga.h
@@ -0,0 +1,52 @@
+/*
+ * Jaguar-ATX Board Register Definitions
+ *
+ * (C) 2002 Momentum Computer Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __JAGUAR_ATX_FPGA_H__
+#define __JAGUAR_ATX_FPGA_H__
+
+#define JAGUAR_ATX_REG_BOARDREV		0x0
+#define JAGUAR_ATX_REG_FPGA_REV		0x1
+#define JAGUAR_ATX_REG_FPGA_TYPE	0x2
+#define JAGUAR_ATX_REG_RESET_STATUS	0x3
+#define JAGUAR_ATX_REG_BOARD_STATUS	0x4
+#define JAGUAR_ATX_REG_RESERVED1	0x5
+#define JAGUAR_ATX_REG_SET		0x6
+#define JAGUAR_ATX_REG_CLR		0x7
+#define JAGUAR_ATX_REG_EEPROM_MODE	0x9
+#define JAGUAR_ATX_REG_RESERVED2	0xa
+#define JAGUAR_ATX_REG_RESERVED3	0xb
+#define JAGUAR_ATX_REG_RESERVED4	0xc
+#define JAGUAR_ATX_REG_PHY_INTSTAT	0xd
+#define JAGUAR_ATX_REG_RESERVED5	0xe
+#define JAGUAR_ATX_REG_RESERVED6	0xf
+
+#define JAGUAR_ATX_CS0_ADDR		0xfc000000L
+
+extern unsigned long ja_fpga_base;
+
+#define JAGUAR_FPGA_WRITE(x,y) writeb(x, ja_fpga_base + JAGUAR_ATX_REG_##y)
+#define JAGUAR_FPGA_READ(x) readb(ja_fpga_base + JAGUAR_ATX_REG_##x)
+
+#endif
diff --git a/arch/mips/momentum/jaguar_atx/prom.c b/arch/mips/momentum/jaguar_atx/prom.c
new file mode 100644
index 0000000..fa5982a
--- /dev/null
+++ b/arch/mips/momentum/jaguar_atx/prom.c
@@ -0,0 +1,266 @@
+/*
+ * Copyright 2002 Momentum Computer Inc.
+ * Author: Matthew Dharm <mdharm@momenco.com>
+ *
+ * Louis Hamilton, Red Hat, Inc.
+ * hamilton@redhat.com  [MIPS64 modifications]
+ *
+ * Based on Ocelot Linux port, which is
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Added changes for SMP - Manish Lachwani (lachwani@pmc-sierra.com)
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/mv64340.h>
+#include <asm/pmon.h>
+
+#include "jaguar_atx_fpga.h"
+
+extern void ja_setup_console(void);
+
+struct callvectors *debug_vectors;
+
+extern unsigned long cpu_clock;
+
+const char *get_system_type(void)
+{
+	return "Momentum Jaguar-ATX";
+}
+
+#ifdef CONFIG_MV643XX_ETH
+extern unsigned char prom_mac_addr_base[6];
+
+static void burn_clocks(void)
+{
+	int i;
+
+	/* this loop should burn at least 1us -- this should be plenty */
+	for (i = 0; i < 0x10000; i++)
+		;
+}
+
+static u8 exchange_bit(u8 val, u8 cs)
+{
+	/* place the data */
+	JAGUAR_FPGA_WRITE((val << 2) | cs, EEPROM_MODE);
+	burn_clocks();
+
+	/* turn the clock on */
+	JAGUAR_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE);
+	burn_clocks();
+
+	/* turn the clock off and read-strobe */
+	JAGUAR_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE);
+	
+	/* return the data */
+	return ((JAGUAR_FPGA_READ(EEPROM_MODE) >> 3) & 0x1);
+}
+
+void get_mac(char dest[6])
+{
+	u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+	int i,j;
+
+	for (i = 0; i < 12; i++)
+		exchange_bit(read_opcode[i], 1);
+
+	for (j = 0; j < 6; j++) {
+		dest[j] = 0;
+		for (i = 0; i < 8; i++) {
+			dest[j] <<= 1;
+			dest[j] |= exchange_bit(0, 1);
+		}
+	}
+
+	/* turn off CS */
+	exchange_bit(0,0);
+}
+#endif
+
+#ifdef CONFIG_MIPS64
+
+unsigned long signext(unsigned long addr)
+{
+	addr &= 0xffffffff;
+	return (unsigned long)((int)addr);
+}
+
+void *get_arg(unsigned long args, int arc)
+{
+	unsigned long ul;
+	unsigned char *puc, uc;
+
+	args += (arc * 4);
+	ul = (unsigned long)signext(args);
+	puc = (unsigned char *)ul;
+	if (puc == 0)
+		return (void *)0;
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+	uc = *puc++;
+	l = (unsigned long)uc;
+	uc = *puc++;
+	ul |= (((unsigned long)uc) << 8);
+	uc = *puc++;
+	ul |= (((unsigned long)uc) << 16);
+	uc = *puc++;
+	ul |= (((unsigned long)uc) << 24);
+#else
+	uc = *puc++;
+	ul = ((unsigned long)uc) << 24;
+	uc = *puc++;
+	ul |= (((unsigned long)uc) << 16);
+	uc = *puc++;
+	ul |= (((unsigned long)uc) << 8);
+	uc = *puc++;
+	ul |= ((unsigned long)uc);
+#endif
+	ul = signext(ul);
+
+	return (void *)ul;
+}
+
+char *arg64(unsigned long addrin, int arg_index)
+{
+	unsigned long args;
+	char *p;
+
+	args = signext(addrin);
+	p = (char *)get_arg(args, arg_index);
+
+	return p;
+}
+#endif  /* CONFIG_MIPS64 */
+
+/* PMON passes arguments in C main() style */
+void __init prom_init(void)
+{
+	int argc = fw_arg0;
+	char **arg = (char **) fw_arg1;
+	char **env = (char **) fw_arg2;
+	struct callvectors *cv = (struct callvectors *) fw_arg3;
+	int i;
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+//	ja_setup_console();	/* The very first thing.  */
+#endif
+
+#ifdef CONFIG_MIPS64
+	char *ptr;
+
+	printk("Mips64 Jaguar-ATX\n");
+	/* save the PROM vectors for debugging use */
+	debug_vectors = (struct callvectors *)signext((unsigned long)cv);
+
+	/* arg[0] is "g", the rest is boot parameters */
+	arcs_cmdline[0] = '\0';
+
+	for (i = 1; i < argc; i++) {
+		ptr = (char *)arg64((unsigned long)arg, i);
+		if ((strlen(arcs_cmdline) + strlen(ptr) + 1) >=
+		    sizeof(arcs_cmdline))
+			break;
+		strcat(arcs_cmdline, ptr);
+		strcat(arcs_cmdline, " ");
+	}
+
+	i = 0;
+	while (1) {
+		ptr = (char *)arg64((unsigned long)env, i);
+		if (! ptr)
+			break;
+
+		if (strncmp("gtbase", ptr, strlen("gtbase")) == 0) {
+			marvell_base = simple_strtol(ptr + strlen("gtbase="),
+							NULL, 16);
+
+			if ((marvell_base & 0xffffffff00000000) == 0)
+				marvell_base |= 0xffffffff00000000;
+
+			printk("marvell_base set to 0x%016lx\n", marvell_base);
+		}
+		if (strncmp("cpuclock", ptr, strlen("cpuclock")) == 0) {
+			cpu_clock = simple_strtol(ptr + strlen("cpuclock="),
+							NULL, 10);
+			printk("cpu_clock set to %d\n", cpu_clock);
+		}
+		i++;
+	}
+	printk("arcs_cmdline: %s\n", arcs_cmdline);
+
+#else   /* CONFIG_MIPS64 */
+	/* save the PROM vectors for debugging use */
+	debug_vectors = cv;
+
+	/* arg[0] is "g", the rest is boot parameters */
+	arcs_cmdline[0] = '\0';
+	for (i = 1; i < argc; i++) {
+		if (strlen(arcs_cmdline) + strlen(arg[i] + 1)
+		    >= sizeof(arcs_cmdline))
+			break;
+		strcat(arcs_cmdline, arg[i]);
+		strcat(arcs_cmdline, " ");
+	}
+
+	while (*env) {
+		if (strncmp("gtbase", *env, strlen("gtbase")) == 0) {
+			marvell_base = simple_strtol(*env + strlen("gtbase="),
+							NULL, 16);
+		}
+		if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) {
+			cpu_clock = simple_strtol(*env + strlen("cpuclock="),
+							NULL, 10);
+		}
+		env++;
+	}
+#endif /* CONFIG_MIPS64 */
+	mips_machgroup = MACH_GROUP_MOMENCO;
+	mips_machtype = MACH_MOMENCO_JAGUAR_ATX;
+
+#ifdef CONFIG_MV643XX_ETH
+	/* get the base MAC address for on-board ethernet ports */
+	get_mac(prom_mac_addr_base);
+#endif
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
+{
+}
+
+int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp)
+{
+	/* Clear the semaphore */
+	*(volatile uint32_t *)(0xbb000a68) = 0x80000000;
+
+	return 1;
+}
+
+void prom_init_secondary(void)
+{
+        clear_c0_config(CONF_CM_CMASK);
+        set_c0_config(0x2);
+
+	clear_c0_status(ST0_IM);
+	set_c0_status(0x1ffff);
+}
+
+void prom_smp_finish(void)
+{
+}
diff --git a/arch/mips/momentum/jaguar_atx/reset.c b/arch/mips/momentum/jaguar_atx/reset.c
new file mode 100644
index 0000000..4803948
--- /dev/null
+++ b/arch/mips/momentum/jaguar_atx/reset.c
@@ -0,0 +1,57 @@
+/*
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Copyright (C) 1997, 2001 Ralf Baechle
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * Copyright (C) 2002 Momentum Computer Inc.
+ * Author: Matthew Dharm <mdharm@momenco.com>
+ *
+ * Louis Hamilton, Red Hat, Inc.
+ * hamilton@redhat.com  [MIPS64 modifications]
+ */
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <linux/delay.h>
+
+void momenco_jaguar_restart(char *command)
+{
+	/* base address of timekeeper portion of part */
+#ifdef CONFIG_MIPS64
+	void *nvram = (void*) 0xfffffffffc807000;
+#else
+	void *nvram = (void*) 0xfc807000;
+#endif
+ 	/* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */
+	writeb(0x84, nvram + 0xff7);
+
+	/* wait for the watchdog to go off */
+	mdelay(100+(1000/16));
+
+	/* if the watchdog fails for some reason, let people know */
+	printk(KERN_NOTICE "Watchdog reset failed\n");
+}
+
+void momenco_jaguar_halt(void)
+{
+	printk(KERN_NOTICE "\n** You can safely turn off the power\n");
+	while (1)
+		__asm__(".set\tmips3\n\t"
+	                "wait\n\t"
+			".set\tmips0");
+}
+
+void momenco_jaguar_power_off(void)
+{
+	momenco_jaguar_halt();
+}
diff --git a/arch/mips/momentum/jaguar_atx/setup.c b/arch/mips/momentum/jaguar_atx/setup.c
new file mode 100644
index 0000000..30462e7
--- /dev/null
+++ b/arch/mips/momentum/jaguar_atx/setup.c
@@ -0,0 +1,474 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ * Momentum Computer Jaguar-ATX board dependent boot routines
+ *
+ * Copyright (C) 1996, 1997, 2001, 2004  Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Copyright (C) 2001 Red Hat, Inc.
+ * Copyright (C) 2002 Momentum Computer
+ *
+ * Author: Matthew Dharm, Momentum Computer
+ *   mdharm@momenco.com
+ *
+ * Louis Hamilton, Red Hat, Inc.
+ *   hamilton@redhat.com  [MIPS64 modifications]
+ *
+ * Author: RidgeRun, Inc.
+ *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/bcd.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/swap.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/vmalloc.h>
+#include <asm/time.h>
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/reboot.h>
+#include <asm/tlbflush.h>
+#include <asm/mv64340.h>
+
+#include "jaguar_atx_fpga.h"
+
+extern unsigned long mv64340_sram_base;
+unsigned long cpu_clock;
+
+/* These functions are used for rebooting or halting the machine*/
+extern void momenco_jaguar_restart(char *command);
+extern void momenco_jaguar_halt(void);
+extern void momenco_jaguar_power_off(void);
+
+void momenco_time_init(void);
+
+static char reset_reason;
+
+static inline unsigned long ENTRYLO(unsigned long paddr)
+{
+	return ((paddr & PAGE_MASK) |
+	       (_PAGE_PRESENT | __READABLE | __WRITEABLE | _PAGE_GLOBAL |
+		_CACHE_UNCACHED)) >> 6;
+}
+
+void __init bus_error_init(void) { /* nothing */ }
+
+/*
+ * Load a few TLB entries for the MV64340 and perhiperals. The MV64340 is going
+ * to be hit on every IRQ anyway - there's absolutely no point in letting it be
+ * a random TLB entry, as it'll just cause needless churning of the TLB. And we
+ * use the other half for the serial port, which is just a PITA otherwise :)
+ *
+ *	Device			Physical	Virtual
+ *	MV64340 Internal Regs	0xf4000000	0xf4000000
+ *	Ocelot-C[S] PLD (CS0)	0xfc000000	0xfc000000
+ *	NVRAM (CS1)		0xfc800000	0xfc800000
+ *	UARTs (CS2)		0xfd000000	0xfd000000
+ *	Internal SRAM		0xfe000000	0xfe000000
+ *	M-Systems DOC (CS3)	0xff000000	0xff000000
+ */
+
+static __init void wire_stupidity_into_tlb(void)
+{
+#ifdef CONFIG_MIPS32
+	write_c0_wired(0);
+	local_flush_tlb_all();
+
+	/* marvell and extra space */
+	add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000),
+	                0xf4000000UL, PM_64K);
+	/* fpga, rtc, and uart */
+	add_wired_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfd000000),
+	                0xfc000000UL, PM_16M);
+//	/* m-sys and internal SRAM */
+//	add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000),
+//	                0xfe000000UL, PM_16M);
+
+	marvell_base = 0xf4000000;
+	//mv64340_sram_base = 0xfe000000;	/* Currently unused */
+#endif
+}
+
+unsigned long marvell_base	= 0xf4000000L;
+unsigned long ja_fpga_base	= JAGUAR_ATX_CS0_ADDR;
+unsigned long uart_base		= 0xfd000000L;
+static unsigned char *rtc_base	= (unsigned char*) 0xfc800000L;
+
+EXPORT_SYMBOL(marvell_base);
+
+static __init int per_cpu_mappings(void)
+{
+	marvell_base	= (unsigned long) ioremap(0xf4000000, 0x10000);
+	ja_fpga_base	= (unsigned long) ioremap(JAGUAR_ATX_CS0_ADDR,  0x1000);
+	uart_base	= (unsigned long) ioremap(0xfd000000UL, 0x1000);
+	rtc_base	= ioremap(0xfc000000UL, 0x8000);
+	// ioremap(0xfe000000,  32 << 20);
+	write_c0_wired(0);
+	local_flush_tlb_all();
+	ja_setup_console();
+
+	return 0;
+}
+arch_initcall(per_cpu_mappings);
+
+unsigned long m48t37y_get_time(void)
+{
+	unsigned int year, month, day, hour, min, sec;
+
+	/* stop the update */
+	rtc_base[0x7ff8] = 0x40;
+
+	year = BCD2BIN(rtc_base[0x7fff]);
+	year += BCD2BIN(rtc_base[0x7ff1]) * 100;
+
+	month = BCD2BIN(rtc_base[0x7ffe]);
+
+	day = BCD2BIN(rtc_base[0x7ffd]);
+
+	hour = BCD2BIN(rtc_base[0x7ffb]);
+	min = BCD2BIN(rtc_base[0x7ffa]);
+	sec = BCD2BIN(rtc_base[0x7ff9]);
+
+	/* start the update */
+	rtc_base[0x7ff8] = 0x00;
+
+	return mktime(year, month, day, hour, min, sec);
+}
+
+int m48t37y_set_time(unsigned long sec)
+{
+	struct rtc_time tm;
+
+	/* convert to a more useful format -- note months count from 0 */
+	to_tm(sec, &tm);
+	tm.tm_mon += 1;
+
+	/* enable writing */
+	rtc_base[0x7ff8] = 0x80;
+
+	/* year */
+	rtc_base[0x7fff] = BIN2BCD(tm.tm_year % 100);
+	rtc_base[0x7ff1] = BIN2BCD(tm.tm_year / 100);
+
+	/* month */
+	rtc_base[0x7ffe] = BIN2BCD(tm.tm_mon);
+
+	/* day */
+	rtc_base[0x7ffd] = BIN2BCD(tm.tm_mday);
+
+	/* hour/min/sec */
+	rtc_base[0x7ffb] = BIN2BCD(tm.tm_hour);
+	rtc_base[0x7ffa] = BIN2BCD(tm.tm_min);
+	rtc_base[0x7ff9] = BIN2BCD(tm.tm_sec);
+
+	/* day of week -- not really used, but let's keep it up-to-date */
+	rtc_base[0x7ffc] = BIN2BCD(tm.tm_wday + 1);
+
+	/* disable writing */
+	rtc_base[0x7ff8] = 0x00;
+
+	return 0;
+}
+
+void momenco_timer_setup(struct irqaction *irq)
+{
+	setup_irq(8, irq);
+}
+
+/*
+ * Ugly but the least of all evils.  TLB initialization did flush the TLB so
+ * We need to setup mappings again before we can touch the RTC.
+ */
+void momenco_time_init(void)
+{
+	wire_stupidity_into_tlb();
+
+	mips_hpt_frequency = cpu_clock / 2;
+	board_timer_setup = momenco_timer_setup;
+
+	rtc_get_time = m48t37y_get_time;
+	rtc_set_time = m48t37y_set_time;
+}
+
+static struct resource mv_pci_io_mem0_resource = {
+	.name	= "MV64340 PCI0 IO MEM",
+	.flags	= IORESOURCE_IO
+};
+
+static struct resource mv_pci_mem0_resource = {
+	.name	= "MV64340 PCI0 MEM",
+	.flags	= IORESOURCE_MEM
+};
+
+static struct mv_pci_controller mv_bus0_controller = {
+	.pcic = {
+		.pci_ops	= &mv_pci_ops,
+		.mem_resource	= &mv_pci_mem0_resource,
+		.io_resource	= &mv_pci_io_mem0_resource,
+	},
+	.config_addr	= MV64340_PCI_0_CONFIG_ADDR,
+	.config_vreg	= MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG,
+};
+
+static uint32_t mv_io_base, mv_io_size;
+
+static void ja_pci0_init(void)
+{
+	uint32_t mem0_base, mem0_size;
+	uint32_t io_base, io_size;
+
+	io_base = MV_READ(MV64340_PCI_0_IO_BASE_ADDR) << 16;
+	io_size = (MV_READ(MV64340_PCI_0_IO_SIZE) + 1) << 16;
+	mem0_base = MV_READ(MV64340_PCI_0_MEMORY0_BASE_ADDR) << 16;
+	mem0_size = (MV_READ(MV64340_PCI_0_MEMORY0_SIZE) + 1) << 16;
+
+	mv_pci_io_mem0_resource.start		= 0;
+	mv_pci_io_mem0_resource.end		= io_size - 1;
+	mv_pci_mem0_resource.start		= mem0_base;
+	mv_pci_mem0_resource.end		= mem0_base + mem0_size - 1;
+	mv_bus0_controller.pcic.mem_offset	= mem0_base;
+	mv_bus0_controller.pcic.io_offset	= 0;
+
+	ioport_resource.end		= io_size - 1;
+
+	register_pci_controller(&mv_bus0_controller.pcic);
+
+	mv_io_base = io_base;
+	mv_io_size = io_size;
+}
+
+static struct resource mv_pci_io_mem1_resource = {
+	.name	= "MV64340 PCI1 IO MEM",
+	.flags	= IORESOURCE_IO
+};
+
+static struct resource mv_pci_mem1_resource = {
+	.name	= "MV64340 PCI1 MEM",
+	.flags	= IORESOURCE_MEM
+};
+
+static struct mv_pci_controller mv_bus1_controller = {
+	.pcic = {
+		.pci_ops	= &mv_pci_ops,
+		.mem_resource	= &mv_pci_mem1_resource,
+		.io_resource	= &mv_pci_io_mem1_resource,
+	},
+	.config_addr	= MV64340_PCI_1_CONFIG_ADDR,
+	.config_vreg	= MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG,
+};
+
+static __init void ja_pci1_init(void)
+{
+	uint32_t mem0_base, mem0_size;
+	uint32_t io_base, io_size;
+
+	io_base = MV_READ(MV64340_PCI_1_IO_BASE_ADDR) << 16;
+	io_size = (MV_READ(MV64340_PCI_1_IO_SIZE) + 1) << 16;
+	mem0_base = MV_READ(MV64340_PCI_1_MEMORY0_BASE_ADDR) << 16;
+	mem0_size = (MV_READ(MV64340_PCI_1_MEMORY0_SIZE) + 1) << 16;
+
+	/*
+	 * Here we assume the I/O window of second bus to be contiguous with
+	 * the first.  A gap is no problem but would waste address space for
+	 * remapping the port space.
+	 */
+	mv_pci_io_mem1_resource.start		= mv_io_size;
+	mv_pci_io_mem1_resource.end		= mv_io_size + io_size - 1;
+	mv_pci_mem1_resource.start		= mem0_base;
+	mv_pci_mem1_resource.end		= mem0_base + mem0_size - 1;
+	mv_bus1_controller.pcic.mem_offset	= mem0_base;
+	mv_bus1_controller.pcic.io_offset	= 0;
+
+	ioport_resource.end		= io_base + io_size -mv_io_base - 1;
+
+	register_pci_controller(&mv_bus1_controller.pcic);
+
+	mv_io_size = io_base + io_size - mv_io_base;
+}
+
+static __init int __init ja_pci_init(void)
+{
+	unsigned long io_v_base;
+	uint32_t enable;
+
+	enable = ~MV_READ(MV64340_BASE_ADDR_ENABLE);
+
+	/*
+	 * We require at least one enabled I/O or PCI memory window or we
+	 * will ignore this PCI bus.  We ignore PCI windows 1, 2 and 3.
+	 */
+	if (enable & (0x01 <<  9) || enable & (0x01 << 10))
+		ja_pci0_init();
+
+	if (enable & (0x01 << 14) || enable & (0x01 << 15))
+		ja_pci1_init();
+
+	if (mv_io_size) {
+		io_v_base = (unsigned long) ioremap(mv_io_base, mv_io_size);
+		if (!io_v_base)
+			panic("Could not ioremap I/O port range");
+
+		set_io_port_base(io_v_base);
+	}
+
+	return 0;
+}
+
+arch_initcall(ja_pci_init);
+
+static int  __init momenco_jaguar_atx_setup(void)
+{
+	unsigned int tmpword;
+
+	board_time_init = momenco_time_init;
+
+	_machine_restart = momenco_jaguar_restart;
+	_machine_halt = momenco_jaguar_halt;
+	_machine_power_off = momenco_jaguar_power_off;
+
+	/*
+	 * initrd_start = (ulong)jaguar_initrd_start;
+	 * initrd_end = (ulong)jaguar_initrd_start + (ulong)jaguar_initrd_size;
+	 * initrd_below_start_ok = 1;
+	 */
+
+	wire_stupidity_into_tlb();
+
+	/*
+	 * shut down ethernet ports, just to be sure our memory doesn't get
+	 * corrupted by random ethernet traffic.
+	 */
+	MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8);
+	MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8);
+	MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(2), 0xff << 8);
+	MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8);
+	MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8);
+	MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(2), 0xff << 8);
+	while (MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff);
+	while (MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff);
+	while (MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(2)) & 0xff);
+	while (MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff);
+	while (MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff);
+	while (MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(2)) & 0xff);
+	MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0),
+	         MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1);
+	MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1),
+	         MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1);
+	MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(2),
+	         MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(2)) & ~1);
+
+	/* Turn off the Bit-Error LED */
+	JAGUAR_FPGA_WRITE(0x80, CLR);
+
+	tmpword = JAGUAR_FPGA_READ(BOARDREV);
+	if (tmpword < 26)
+		printk("Momentum Jaguar-ATX: Board Assembly Rev. %c\n",
+			'A'+tmpword);
+	else
+		printk("Momentum Jaguar-ATX: Board Assembly Revision #0x%x\n",
+			tmpword);
+
+	tmpword = JAGUAR_FPGA_READ(FPGA_REV);
+	printk("FPGA Rev: %d.%d\n", tmpword>>4, tmpword&15);
+	tmpword = JAGUAR_FPGA_READ(RESET_STATUS);
+	printk("Reset reason: 0x%x\n", tmpword);
+	switch (tmpword) {
+	case 0x1:
+		printk("  - Power-up reset\n");
+		break;
+	case 0x2:
+		printk("  - Push-button reset\n");
+		break;
+	case 0x8:
+		printk("  - Watchdog reset\n");
+		break;
+	case 0x10:
+		printk("  - JTAG reset\n");
+		break;
+	default:
+		printk("  - Unknown reset cause\n");
+	}
+	reset_reason = tmpword;
+	JAGUAR_FPGA_WRITE(0xff, RESET_STATUS);
+
+	tmpword = JAGUAR_FPGA_READ(BOARD_STATUS);
+	printk("Board Status register: 0x%02x\n", tmpword);
+	printk("  - User jumper: %s\n", (tmpword & 0x80)?"installed":"absent");
+	printk("  - Boot flash write jumper: %s\n", (tmpword&0x40)?"installed":"absent");
+
+	/* 256MiB of RM9000x2 DDR */
+//	add_memory_region(0x0, 0x100<<20, BOOT_MEM_RAM);
+
+	/* 128MiB of MV-64340 DDR */
+//	add_memory_region(0x100<<20, 0x80<<20, BOOT_MEM_RAM);
+
+	/* XXX Memory configuration should be picked up from PMON2k */
+#ifdef CONFIG_JAGUAR_DMALOW
+	printk("Jaguar ATX DMA-low mode set\n");
+	add_memory_region(0x00000000, 0x08000000, BOOT_MEM_RAM);
+	add_memory_region(0x08000000, 0x10000000, BOOT_MEM_RAM);
+#else
+	/* 128MiB of MV-64340 DDR RAM */
+	printk("Jaguar ATX DMA-low mode is not set\n");
+	add_memory_region(0x100<<20, 0x80<<20, BOOT_MEM_RAM);
+#endif
+
+#ifdef GEMDEBUG_TRACEBUFFER
+	{
+	  unsigned int tbControl;
+	  tbControl = 
+	    0 << 26 |  /* post trigger delay 0 */
+	    	    0x2 << 16 |		/* sequential trace mode */
+	    //	    0x0 << 16 |		/* non-sequential trace mode */
+	    //	    0xf << 4 |		/* watchpoints disabled */
+	    2 << 2 |		/* armed */
+	    2 ;			/* interrupt disabled  */
+	  printk ("setting     tbControl = %08lx\n", tbControl);
+	  write_32bit_cp0_set1_register($22, tbControl);
+	  __asm__ __volatile__(".set noreorder\n\t" \
+			       "nop; nop; nop; nop; nop; nop;\n\t" \
+			       "nop; nop; nop; nop; nop; nop;\n\t" \
+			       ".set reorder\n\t");
+
+	}
+#endif
+
+	return 0;
+}
+
+early_initcall(momenco_jaguar_atx_setup);
diff --git a/arch/mips/momentum/ocelot_3/Makefile b/arch/mips/momentum/ocelot_3/Makefile
new file mode 100644
index 0000000..aab8fd8
--- /dev/null
+++ b/arch/mips/momentum/ocelot_3/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for Momentum Computer's Ocelot-3 board.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+obj-y	 += int-handler.o irq.o prom.o reset.o setup.o
diff --git a/arch/mips/momentum/ocelot_3/int-handler.S b/arch/mips/momentum/ocelot_3/int-handler.S
new file mode 100644
index 0000000..4522f09
--- /dev/null
+++ b/arch/mips/momentum/ocelot_3/int-handler.S
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2002 Momentum Computer Inc.
+ * Author: Matthew Dharm <mdharm@momenco.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * Copyright 2004 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * Copyright (C) 2004 MontaVista Software Inc.
+ * Author: Manish Lachwani, mlachwani@mvista.com
+ *
+ * First-level interrupt dispatcher for Ocelot-3 board.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/*
+ * First level interrupt dispatcher for Ocelot-3 board
+ */
+		.align	5
+		NESTED(ocelot3_handle_int, PT_SIZE, sp)
+		SAVE_ALL
+		CLI
+		.set	at
+
+		mfc0	t0, CP0_CAUSE
+		mfc0	t2, CP0_STATUS
+
+		and	t0, t2
+
+		andi	t1, t0, STATUSF_IP0	/* sw0 software interrupt (IRQ0) */
+		bnez	t1, ll_sw0_irq
+
+		andi	t1, t0, STATUSF_IP1	/* sw1 software interrupt (IRQ1) */
+		bnez	t1, ll_sw1_irq
+
+		andi	t1, t0, STATUSF_IP2	/* int0 hardware line (IRQ2) */
+		bnez	t1, ll_pci0slot1_irq
+
+		andi	t1, t0, STATUSF_IP3	/* int1 hardware line (IRQ3) */
+		bnez	t1, ll_pci0slot2_irq
+
+		andi	t1, t0, STATUSF_IP4	/* int2 hardware line (IRQ4) */
+		bnez	t1, ll_pci1slot1_irq
+
+		andi	t1, t0, STATUSF_IP5	/* int3 hardware line (IRQ5) */
+		bnez	t1, ll_pci1slot2_irq
+
+		andi	t1, t0, STATUSF_IP6	/* int4 hardware line (IRQ6) */
+		bnez	t1, ll_uart_irq
+
+		andi	t1, t0, STATUSF_IP7	/* cpu timer (IRQ7) */
+		bnez	t1, ll_cputimer_irq
+
+                /* now look at extended interrupts */
+                mfc0    t0, CP0_CAUSE
+                cfc0    t1, CP0_S1_INTCONTROL
+
+                /* shift the mask 8 bits left to line up the bits */
+                sll     t2, t1, 8
+
+                and     t0, t2
+                srl     t0, t0, 16
+
+                andi    t1, t0, STATUSF_IP8     /* int6 hardware line (IRQ9) */
+                bnez    t1, ll_mv64340_decode_irq
+
+		.set	reorder
+
+		/* wrong alarm or masked ... */
+		j	spurious_interrupt
+		nop
+		END(ocelot3_handle_int)
+
+		.align	5
+ll_sw0_irq:
+		li	a0, 0		/* IRQ 1 */
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+ll_sw1_irq:
+		li	a0, 1		/* IRQ 2 */
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_pci0slot1_irq:
+		li	a0, 2		/* IRQ 3 */
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_pci0slot2_irq:
+		li	a0, 3		/* IRQ 4 */
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_pci1slot1_irq:
+		li	a0, 4		/* IRQ 5 */
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_pci1slot2_irq:
+		li	a0, 5		/* IRQ 6 */
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_uart_irq:
+		li	a0, 6		/* IRQ 7 */
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_cputimer_irq:
+		li	a0, 7		/* IRQ 8 */
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_mv64340_decode_irq:
+		move	a0, sp
+		jal	ll_mv64340_irq
+		j	ret_from_irq
+
diff --git a/arch/mips/momentum/ocelot_3/irq.c b/arch/mips/momentum/ocelot_3/irq.c
new file mode 100644
index 0000000..42464db
--- /dev/null
+++ b/arch/mips/momentum/ocelot_3/irq.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: RidgeRun, Inc.
+ *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org)
+ *
+ * Copyright 2004 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  Copyright (C) 2004 MontaVista Software Inc.
+ *  Author: Manish Lachwani, mlachwani@mvista.com
+ *
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <asm/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+extern asmlinkage void ocelot3_handle_int(void);
+
+static struct irqaction cascade_mv64340 = {
+	no_action, SA_INTERRUPT, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL
+};
+
+void __init arch_init_irq(void)
+{
+	/*
+	 * Clear all of the interrupts while we change the able around a bit.
+	 * int-handler is not on bootstrap
+	 */
+	clear_c0_status(ST0_IM | ST0_BEV);
+
+	/* Sets the first-level interrupt dispatcher. */
+	set_except_vector(0, ocelot3_handle_int);
+	mips_cpu_irq_init(0);
+	rm7k_cpu_irq_init(8);
+
+	/* set up the cascading interrupts */
+	setup_irq(8, &cascade_mv64340);		/* unmask intControl IM8, IRQ 9 */
+	mv64340_irq_init(16);
+
+	set_c0_status(ST0_IM); /* IE in the status register */
+
+}
diff --git a/arch/mips/momentum/ocelot_3/ocelot_3_fpga.h b/arch/mips/momentum/ocelot_3/ocelot_3_fpga.h
new file mode 100644
index 0000000..227e429
--- /dev/null
+++ b/arch/mips/momentum/ocelot_3/ocelot_3_fpga.h
@@ -0,0 +1,57 @@
+/*
+ * Ocelot-3 Board Register Definitions
+ *
+ * (C) 2002 Momentum Computer Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  Louis Hamilton, Red Hat, Inc.
+ *    hamilton@redhat.com  [MIPS64 modifications]
+ *
+ * Copyright (C) 2004 MontaVista Software Inc.
+ * Author: Manish Lachwani, mlachwani@mvista.com
+ */
+
+#ifndef __OCELOT_3_FPGA_H__
+#define __OCELOT_3_FPGA_H__
+
+#define OCELOT_3_REG_BOARDREV		0x0
+#define OCELOT_3_REG_FPGA_REV		0x1
+#define OCELOT_3_REG_FPGA_TYPE		0x2
+#define OCELOT_3_REG_RESET_STATUS	0x3
+#define OCELOT_3_REG_BOARD_STATUS	0x4
+#define OCELOT_3_REG_CPCI_ID		0x5
+#define OCELOT_3_REG_SET		0x6
+#define OCELOT_3_REG_CLR		0x7
+#define OCELOT_3_REG_EEPROM_MODE	0x9
+#define OCELOT_3_REG_INTMASK		0xa
+#define OCELOT_3_REG_INTSTAT		0xb
+#define OCELOT_3_REG_UART_INTMASK	0xc
+#define OCELOT_3_REG_UART_INTSTAT	0xd
+#define OCELOT_3_REG_INTSET		0xe
+#define OCELOT_3_REG_INTCLR		0xf
+
+extern unsigned long ocelot_fpga_base;
+
+#define OCELOT_FPGA_WRITE(x, y) writeb(x, ocelot_fpga_base + OCELOT_3_REG_##y)
+#define OCELOT_FPGA_READ(x) readb(ocelot_fpga_base + OCELOT_3_REG_##x)
+
+#endif
diff --git a/arch/mips/momentum/ocelot_3/prom.c b/arch/mips/momentum/ocelot_3/prom.c
new file mode 100644
index 0000000..89c17a0
--- /dev/null
+++ b/arch/mips/momentum/ocelot_3/prom.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2002 Momentum Computer Inc.
+ * Author: Matthew Dharm <mdharm@momenco.com>
+ *
+ * Louis Hamilton, Red Hat, Inc.
+ *   hamilton@redhat.com  [MIPS64 modifications]
+ *
+ * Copyright 2004 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * Based on Ocelot Linux port, which is
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Copyright (C) 2004 MontaVista Software Inc.
+ * Author: Manish Lachwani, mlachwani@mvista.com
+ *
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/mv643xx.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/pmon.h>
+#include "ocelot_3_fpga.h"
+
+struct callvectors* debug_vectors;
+extern unsigned long marvell_base;
+extern unsigned long cpu_clock;
+
+#ifdef CONFIG_MV643XX_ETH
+extern unsigned char prom_mac_addr_base[6];
+#endif
+
+const char *get_system_type(void)
+{
+	return "Momentum Ocelot-3";
+}
+
+#ifdef CONFIG_MV643XX_ETH
+void burn_clocks(void)
+{
+	int i;
+
+	/* this loop should burn at least 1us -- this should be plenty */
+	for (i = 0; i < 0x10000; i++)
+		;
+}
+
+u8 exchange_bit(u8 val, u8 cs)
+{
+	/* place the data */
+	OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE);
+	burn_clocks();
+
+	/* turn the clock on */
+	OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE);
+	burn_clocks();
+
+	/* turn the clock off and read-strobe */
+	OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE);
+
+	/* return the data */
+	return ((OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1);
+}
+
+void get_mac(char dest[6])
+{
+	u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+	int i,j;
+
+	for (i = 0; i < 12; i++)
+		exchange_bit(read_opcode[i], 1);
+
+	for (j = 0; j < 6; j++) {
+		dest[j] = 0;
+		for (i = 0; i < 8; i++) {
+			dest[j] <<= 1;
+			dest[j] |= exchange_bit(0, 1);
+		}
+	}
+
+	/* turn off CS */
+	exchange_bit(0,0);
+}
+#endif
+
+
+#ifdef CONFIG_MIPS64
+
+unsigned long signext(unsigned long addr)
+{
+	addr &= 0xffffffff;
+	return (unsigned long)((int)addr);
+}
+
+void *get_arg(unsigned long args, int arc)
+{
+	unsigned long ul;
+	unsigned char *puc, uc;
+
+	args += (arc * 4);
+	ul = (unsigned long)signext(args);
+	puc = (unsigned char *)ul;
+	if (puc == 0)
+		return (void *)0;
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+	uc = *puc++;
+	ul = (unsigned long)uc;
+	uc = *puc++;
+	ul |= (((unsigned long)uc) << 8);
+	uc = *puc++;
+	ul |= (((unsigned long)uc) << 16);
+	uc = *puc++;
+	ul |= (((unsigned long)uc) << 24);
+#else  /* CONFIG_CPU_LITTLE_ENDIAN */
+	uc = *puc++;
+	ul = ((unsigned long)uc) << 24;
+	uc = *puc++;
+	ul |= (((unsigned long)uc) << 16);
+	uc = *puc++;
+	ul |= (((unsigned long)uc) << 8);
+	uc = *puc++;
+	ul |= ((unsigned long)uc);
+#endif  /* CONFIG_CPU_LITTLE_ENDIAN */
+	ul = signext(ul);
+	return (void *)ul;
+}
+
+char *arg64(unsigned long addrin, int arg_index)
+{
+	unsigned long args;
+	char *p;
+
+	args = signext(addrin);
+	p = (char *)get_arg(args, arg_index);
+
+	return p;
+}
+#endif  /* CONFIG_MIPS64 */
+
+void __init prom_init(void)
+{
+	int argc = fw_arg0;
+	char **arg = (char **) fw_arg1;
+	char **env = (char **) fw_arg2;
+	struct callvectors *cv = (struct callvectors *) fw_arg3;
+	int i;
+
+#ifdef CONFIG_MIPS64
+	char *ptr;
+	printk("prom_init - MIPS64\n");
+
+	/* save the PROM vectors for debugging use */
+	debug_vectors = (struct callvectors *)signext((unsigned long)cv);
+
+	/* arg[0] is "g", the rest is boot parameters */
+	arcs_cmdline[0] = '\0';
+
+	for (i = 1; i < argc; i++) {
+		ptr = (char *)arg64((unsigned long)arg, i);
+		if ((strlen(arcs_cmdline) + strlen(ptr) + 1) >=
+		    sizeof(arcs_cmdline))
+			break;
+		strcat(arcs_cmdline, ptr);
+		strcat(arcs_cmdline, " ");
+	}
+	i = 0;
+
+	while (1) {
+		ptr = (char *)arg64((unsigned long)env, i);
+		if (! ptr)
+			break;
+
+		if (strncmp("gtbase", ptr, strlen("gtbase")) == 0) {
+			marvell_base = simple_strtol(ptr + strlen("gtbase="),
+							NULL, 16);
+
+			if ((marvell_base & 0xffffffff00000000) == 0)
+				marvell_base |= 0xffffffff00000000;
+
+			printk("marvell_base set to 0x%016lx\n", marvell_base);
+		}
+		if (strncmp("cpuclock", ptr, strlen("cpuclock")) == 0) {
+			cpu_clock = simple_strtol(ptr + strlen("cpuclock="),
+							NULL, 10);
+			printk("cpu_clock set to %d\n", cpu_clock);
+		}
+		i++;
+	}
+	printk("arcs_cmdline: %s\n", arcs_cmdline);
+
+#else   /* CONFIG_MIPS64 */
+
+	/* save the PROM vectors for debugging use */
+	debug_vectors = cv;
+
+	/* arg[0] is "g", the rest is boot parameters */
+	arcs_cmdline[0] = '\0';
+	for (i = 1; i < argc; i++) {
+		if (strlen(arcs_cmdline) + strlen(arg[i] + 1)
+		    >= sizeof(arcs_cmdline))
+			break;
+		strcat(arcs_cmdline, arg[i]);
+		strcat(arcs_cmdline, " ");
+	}
+
+	while (*env) {
+		if (strncmp("gtbase", *env, strlen("gtbase")) == 0) {
+			marvell_base = simple_strtol(*env + strlen("gtbase="),
+							NULL, 16);
+		}
+		if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) {
+			cpu_clock = simple_strtol(*env + strlen("cpuclock="),
+							NULL, 10);
+		}
+		env++;
+	}
+#endif /* CONFIG_MIPS64 */
+
+	mips_machgroup = MACH_GROUP_MOMENCO;
+	mips_machtype = MACH_MOMENCO_OCELOT_3;
+
+#ifdef CONFIG_MV643XX_ETH
+	/* get the base MAC address for on-board ethernet ports */
+	get_mac(prom_mac_addr_base);
+#endif
+
+#ifndef CONFIG_MIPS64
+	debug_vectors->printf("Booting Linux kernel...\n");
+#endif
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
+{
+}
diff --git a/arch/mips/momentum/ocelot_3/reset.c b/arch/mips/momentum/ocelot_3/reset.c
new file mode 100644
index 0000000..72b4423
--- /dev/null
+++ b/arch/mips/momentum/ocelot_3/reset.c
@@ -0,0 +1,59 @@
+/*
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Copyright (C) 1997, 01, 05 Ralf Baechle
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * Copyright (C) 2002 Momentum Computer Inc.
+ * Author: Matthew Dharm <mdharm@momenco.com>
+ *
+ * Louis Hamilton, Red Hat, Inc.
+ * hamilton@redhat.com  [MIPS64 modifications]
+ *
+ * Copyright 2004 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * Copyright (C) 2004 MontaVista Software Inc.
+ * Author: Manish Lachwani, mlachwani@mvista.com
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+
+void momenco_ocelot_restart(char *command)
+{
+	/* base address of timekeeper portion of part */
+	void *nvram = (void *) 0xfc807000L;
+
+ 	/* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */
+	writeb(0x84, nvram + 0xff7);
+
+	/* wait for the watchdog to go off */
+	mdelay(100+(1000/16));
+
+	/* if the watchdog fails for some reason, let people know */
+	printk(KERN_NOTICE "Watchdog reset failed\n");
+}
+
+void momenco_ocelot_halt(void)
+{
+	printk(KERN_NOTICE "\n** You can safely turn off the power\n");
+	while (1)
+		__asm__(".set\tmips3\n\t"
+	                "wait\n\t"
+			".set\tmips0");
+}
+
+void momenco_ocelot_power_off(void)
+{
+	momenco_ocelot_halt();
+}
diff --git a/arch/mips/momentum/ocelot_3/setup.c b/arch/mips/momentum/ocelot_3/setup.c
new file mode 100644
index 0000000..ce2efcb
--- /dev/null
+++ b/arch/mips/momentum/ocelot_3/setup.c
@@ -0,0 +1,398 @@
+/*
+ * setup.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Momentum Computer Ocelot-3 board dependent boot routines
+ *
+ * Copyright (C) 1996, 1997, 01, 05  Ralf Baechle
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Copyright (C) 2001 Red Hat, Inc.
+ * Copyright (C) 2002 Momentum Computer
+ *
+ * Author: Matthew Dharm, Momentum Computer
+ *   mdharm@momenco.com
+ *
+ * Louis Hamilton, Red Hat, Inc.
+ *   hamilton@redhat.com  [MIPS64 modifications]
+ *
+ * Author: RidgeRun, Inc.
+ *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * Copyright 2004 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * Copyright (C) 2004 MontaVista Software Inc.
+ * Author: Manish Lachwani, mlachwani@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mc146818rtc.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/timex.h>
+#include <linux/bootmem.h>
+#include <linux/mv643xx.h>
+#include <asm/time.h>
+#include <asm/page.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pci.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/reboot.h>
+#include <asm/mc146818rtc.h>
+#include <asm/tlbflush.h>
+#include "ocelot_3_fpga.h"
+
+/* Marvell Discovery Register Base */
+unsigned long marvell_base = (signed)0xf4000000;
+
+/* CPU clock */
+unsigned long cpu_clock;
+
+/* RTC/NVRAM */
+unsigned char* rtc_base = (unsigned char*)(signed)0xfc800000;
+
+/* FPGA Base */
+unsigned long ocelot_fpga_base = (signed)0xfc000000;
+
+/* Serial base */
+unsigned long uart_base = (signed)0xfd000000;
+
+/*
+ * Marvell Discovery SRAM. This is one place where Ethernet
+ * Tx and Rx descriptors can be placed to improve performance
+ */
+extern unsigned long mv64340_sram_base;
+
+/* These functions are used for rebooting or halting the machine*/
+extern void momenco_ocelot_restart(char *command);
+extern void momenco_ocelot_halt(void);
+extern void momenco_ocelot_power_off(void);
+
+void momenco_time_init(void);
+static char reset_reason;
+
+void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
+		     unsigned long entryhi, unsigned long pagemask);
+
+static inline unsigned long ENTRYLO(unsigned long paddr)
+{
+	return ((paddr & PAGE_MASK) |
+		(_PAGE_PRESENT | __READABLE | __WRITEABLE | _PAGE_GLOBAL |
+		_CACHE_UNCACHED)) >> 6;
+}
+
+void __init bus_error_init(void)
+{
+	/* nothing */
+}
+
+/*
+ * setup code for a handoff from a version 2 PMON 2000 PROM
+ */
+void setup_wired_tlb_entries(void)
+{
+	write_c0_wired(0);
+	local_flush_tlb_all();
+
+	/* marvell and extra space */
+	add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), (signed)0xf4000000, PM_64K);
+
+	/* fpga, rtc, and uart */
+	add_wired_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfd000000), (signed)0xfc000000, PM_16M);
+}
+
+#define CONV_BCD_TO_BIN(val)	(((val) & 0xf) + (((val) >> 4) * 10))
+#define CONV_BIN_TO_BCD(val)	(((val) % 10) + (((val) / 10) << 4))
+
+unsigned long m48t37y_get_time(void)
+{
+	unsigned int year, month, day, hour, min, sec;
+
+	/* stop the update */
+	rtc_base[0x7ff8] = 0x40;
+
+	year = CONV_BCD_TO_BIN(rtc_base[0x7fff]);
+	year += CONV_BCD_TO_BIN(rtc_base[0x7ff1]) * 100;
+
+	month = CONV_BCD_TO_BIN(rtc_base[0x7ffe]);
+
+	day = CONV_BCD_TO_BIN(rtc_base[0x7ffd]);
+
+	hour = CONV_BCD_TO_BIN(rtc_base[0x7ffb]);
+	min = CONV_BCD_TO_BIN(rtc_base[0x7ffa]);
+	sec = CONV_BCD_TO_BIN(rtc_base[0x7ff9]);
+
+	/* start the update */
+	rtc_base[0x7ff8] = 0x00;
+
+	return mktime(year, month, day, hour, min, sec);
+}
+
+int m48t37y_set_time(unsigned long sec)
+{
+	struct rtc_time tm;
+
+	/* convert to a more useful format -- note months count from 0 */
+	to_tm(sec, &tm);
+	tm.tm_mon += 1;
+
+	/* enable writing */
+	rtc_base[0x7ff8] = 0x80;
+
+	/* year */
+	rtc_base[0x7fff] = CONV_BIN_TO_BCD(tm.tm_year % 100);
+	rtc_base[0x7ff1] = CONV_BIN_TO_BCD(tm.tm_year / 100);
+
+	/* month */
+	rtc_base[0x7ffe] = CONV_BIN_TO_BCD(tm.tm_mon);
+
+	/* day */
+	rtc_base[0x7ffd] = CONV_BIN_TO_BCD(tm.tm_mday);
+
+	/* hour/min/sec */
+	rtc_base[0x7ffb] = CONV_BIN_TO_BCD(tm.tm_hour);
+	rtc_base[0x7ffa] = CONV_BIN_TO_BCD(tm.tm_min);
+	rtc_base[0x7ff9] = CONV_BIN_TO_BCD(tm.tm_sec);
+
+	/* day of week -- not really used, but let's keep it up-to-date */
+	rtc_base[0x7ffc] = CONV_BIN_TO_BCD(tm.tm_wday + 1);
+
+	/* disable writing */
+	rtc_base[0x7ff8] = 0x00;
+
+	return 0;
+}
+
+void momenco_timer_setup(struct irqaction *irq)
+{
+	setup_irq(7, irq);	/* Timer interrupt, unmask status IM7 */
+}
+
+void momenco_time_init(void)
+{
+	setup_wired_tlb_entries();
+
+	/*
+	 * Ocelot-3 board has been built with both
+	 * the Rm7900 and the Rm7065C
+	 */
+	mips_hpt_frequency = cpu_clock / 2;
+	board_timer_setup = momenco_timer_setup;
+
+	rtc_get_time = m48t37y_get_time;
+	rtc_set_time = m48t37y_set_time;
+}
+
+/*
+ * PCI Support for Ocelot-3
+ */
+
+/* Bus #0 IO and MEM space */
+#define	OCELOT_3_PCI_IO_0_START		0xe0000000
+#define	OCELOT_3_PCI_IO_0_SIZE		0x08000000
+#define	OCELOT_3_PCI_MEM_0_START	0xc0000000
+#define	OCELOT_3_PCI_MEM_0_SIZE		0x10000000
+
+/* Bus #1 IO and MEM space */
+#define	OCELOT_3_PCI_IO_1_START		0xe8000000
+#define	OCELOT_3_PCI_IO_1_SIZE		0x08000000
+#define	OCELOT_3_PCI_MEM_1_START	0xd0000000
+#define	OCELOT_3_PCI_MEM_1_SIZE		0x10000000
+
+static struct resource mv_pci_io_mem0_resource = {
+	.name	= "MV64340 PCI0 IO MEM",
+	.start	= OCELOT_3_PCI_IO_0_START,
+	.end	= OCELOT_3_PCI_IO_0_START + OCELOT_3_PCI_IO_0_SIZE - 1,
+	.flags  = IORESOURCE_IO,
+};
+
+static struct resource mv_pci_io_mem1_resource = {
+	.name	= "MV64340 PCI1 IO MEM",
+	.start	= OCELOT_3_PCI_IO_1_START,
+	.end	= OCELOT_3_PCI_IO_1_START + OCELOT_3_PCI_IO_1_SIZE - 1,
+	.flags	= IORESOURCE_IO,
+};
+
+static struct resource mv_pci_mem0_resource = {
+	.name	= "MV64340 PCI0 MEM",
+	.start	= OCELOT_3_PCI_MEM_0_START,
+	.end	= OCELOT_3_PCI_MEM_0_START + OCELOT_3_PCI_MEM_0_SIZE - 1,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct resource mv_pci_mem1_resource = {
+	.name	= "MV64340 PCI1 MEM",
+	.start	= OCELOT_3_PCI_MEM_1_START,
+	.end	= OCELOT_3_PCI_MEM_1_START + OCELOT_3_PCI_MEM_1_SIZE - 1,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct mv_pci_controller mv_bus0_controller = {
+	.pcic = {
+		 .pci_ops	= &mv_pci_ops,
+		 .mem_resource	= &mv_pci_mem0_resource,
+		 .io_resource	= &mv_pci_io_mem0_resource,
+	},
+	.config_addr	= MV64340_PCI_0_CONFIG_ADDR,
+	.config_vreg	= MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG,
+};
+
+static struct mv_pci_controller mv_bus1_controller = {
+	.pcic = {
+		 .pci_ops	= &mv_pci_ops,
+		 .mem_resource	= &mv_pci_mem1_resource,
+		 .io_resource	= &mv_pci_io_mem1_resource,
+	},
+	.config_addr	= MV64340_PCI_1_CONFIG_ADDR,
+	.config_vreg	= MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG,
+};
+
+static __init int __init ja_pci_init(void)
+{
+	uint32_t enable;
+	extern int pci_probe_only;
+
+	/* PMON will assign PCI resources */
+	pci_probe_only = 1;
+
+	enable = ~MV_READ(MV64340_BASE_ADDR_ENABLE);
+	/*
+	 * We require at least one enabled I/O or PCI memory window or we
+	 * will ignore this PCI bus.  We ignore PCI windows 1, 2 and 3.
+	 */
+	if (enable & (0x01 <<  9) || enable & (0x01 << 10))
+		register_pci_controller(&mv_bus0_controller.pcic);
+
+	if (enable & (0x01 << 14) || enable & (0x01 << 15))
+		register_pci_controller(&mv_bus1_controller.pcic);
+
+	ioport_resource.end = OCELOT_3_PCI_IO_0_START + OCELOT_3_PCI_IO_0_SIZE +
+					OCELOT_3_PCI_IO_1_SIZE - 1;
+
+	iomem_resource.end = OCELOT_3_PCI_MEM_0_START + OCELOT_3_PCI_MEM_0_SIZE +
+					OCELOT_3_PCI_MEM_1_SIZE - 1;
+
+	set_io_port_base(OCELOT_3_PCI_IO_0_START); /* mips_io_port_base */
+
+	return 0;
+}
+
+arch_initcall(ja_pci_init);
+
+static int __init momenco_ocelot_3_setup(void)
+{
+	unsigned int tmpword;
+
+	board_time_init = momenco_time_init;
+
+	_machine_restart = momenco_ocelot_restart;
+	_machine_halt = momenco_ocelot_halt;
+	_machine_power_off = momenco_ocelot_power_off;
+
+	/* Wired TLB entries */
+	setup_wired_tlb_entries();
+
+	/* shut down ethernet ports, just to be sure our memory doesn't get
+	 * corrupted by random ethernet traffic.
+	 */
+	MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8);
+	MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8);
+	MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8);
+	MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8);
+	do {}
+	  while (MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff);
+	do {}
+	  while (MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff);
+	do {}
+	  while (MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff);
+	do {}
+	  while (MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff);
+	MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0),
+		 MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1);
+	MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1),
+		 MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1);
+
+	/* Turn off the Bit-Error LED */
+	OCELOT_FPGA_WRITE(0x80, CLR);
+
+	tmpword = OCELOT_FPGA_READ(BOARDREV);
+	if (tmpword < 26)
+		printk("Momenco Ocelot-3: Board Assembly Rev. %c\n",
+			'A'+tmpword);
+	else
+		printk("Momenco Ocelot-3: Board Assembly Revision #0x%x\n",
+			tmpword);
+
+	tmpword = OCELOT_FPGA_READ(FPGA_REV);
+	printk("FPGA Rev: %d.%d\n", tmpword>>4, tmpword&15);
+	tmpword = OCELOT_FPGA_READ(RESET_STATUS);
+	printk("Reset reason: 0x%x\n", tmpword);
+	switch (tmpword) {
+		case 0x1:
+			printk("  - Power-up reset\n");
+			break;
+		case 0x2:
+			printk("  - Push-button reset\n");
+			break;
+		case 0x4:
+			printk("  - cPCI bus reset\n");
+			break;
+		case 0x8:
+			printk("  - Watchdog reset\n");
+			break;
+		case 0x10:
+			printk("  - Software reset\n");
+			break;
+		default:
+			printk("  - Unknown reset cause\n");
+	}
+	reset_reason = tmpword;
+	OCELOT_FPGA_WRITE(0xff, RESET_STATUS);
+
+	tmpword = OCELOT_FPGA_READ(CPCI_ID);
+	printk("cPCI ID register: 0x%02x\n", tmpword);
+	printk("  - Slot number: %d\n", tmpword & 0x1f);
+	printk("  - PCI bus present: %s\n", tmpword & 0x40 ? "yes" : "no");
+	printk("  - System Slot: %s\n", tmpword & 0x20 ? "yes" : "no");
+
+	tmpword = OCELOT_FPGA_READ(BOARD_STATUS);
+	printk("Board Status register: 0x%02x\n", tmpword);
+	printk("  - User jumper: %s\n", (tmpword & 0x80)?"installed":"absent");
+	printk("  - Boot flash write jumper: %s\n", (tmpword&0x40)?"installed":"absent");
+	printk("  - L3 cache size: %d MB\n", (1<<((tmpword&12) >> 2))&~1);
+
+	/* Support for 128 MB memory */
+	add_memory_region(0x0, 0x08000000, BOOT_MEM_RAM);
+
+	return 0;
+}
+
+early_initcall(momenco_ocelot_3_setup);
diff --git a/arch/mips/momentum/ocelot_c/Makefile b/arch/mips/momentum/ocelot_c/Makefile
new file mode 100644
index 0000000..9124077
--- /dev/null
+++ b/arch/mips/momentum/ocelot_c/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for Momentum Computer's Ocelot-C and -CS boards.
+#
+
+obj-y	 		+= cpci-irq.o int-handler.o irq.o prom.o reset.o \
+			   setup.o uart-irq.o
+
+obj-$(CONFIG_KGDB)	+= dbg_io.o
diff --git a/arch/mips/momentum/ocelot_c/cpci-irq.c b/arch/mips/momentum/ocelot_c/cpci-irq.c
new file mode 100644
index 0000000..dea48b3
--- /dev/null
+++ b/arch/mips/momentum/ocelot_c/cpci-irq.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2002 Momentum Computer
+ * Author: mdharm@momenco.com
+ *
+ * arch/mips/momentum/ocelot_c/cpci-irq.c
+ *     Interrupt routines for cpci.  Interrupt numbers are assigned from
+ *     CPCI_IRQ_BASE to CPCI_IRQ_BASE+8 (8 interrupt sources).
+ *
+ * Note that the high-level software will need to be careful about using
+ * these interrupts.  If this board is asserting a cPCI interrupt, it will
+ * also see the asserted interrupt.  Care must be taken to avoid an
+ * interrupt flood.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <asm/ptrace.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <asm/io.h>
+#include "ocelot_c_fpga.h"
+
+#define CPCI_IRQ_BASE	8
+
+static inline int ls1bit8(unsigned int x)
+{
+        int b = 7, s;
+
+        s =  4; if (((unsigned char)(x <<  4)) == 0) s = 0; b -= s; x <<= s;
+        s =  2; if (((unsigned char)(x <<  2)) == 0) s = 0; b -= s; x <<= s;
+        s =  1; if (((unsigned char)(x <<  1)) == 0) s = 0; b -= s;
+
+        return b;
+}
+
+/* mask off an interrupt -- 0 is enable, 1 is disable */
+static inline void mask_cpci_irq(unsigned int irq)
+{
+	uint32_t value;
+
+	value = OCELOT_FPGA_READ(INTMASK);
+	value |= 1 << (irq - CPCI_IRQ_BASE);
+	OCELOT_FPGA_WRITE(value, INTMASK);
+
+	/* read the value back to assure that it's really been written */
+	value = OCELOT_FPGA_READ(INTMASK);
+}
+
+/* unmask an interrupt -- 0 is enable, 1 is disable */
+static inline void unmask_cpci_irq(unsigned int irq)
+{
+	uint32_t value;
+
+	value = OCELOT_FPGA_READ(INTMASK);
+	value &= ~(1 << (irq - CPCI_IRQ_BASE));
+	OCELOT_FPGA_WRITE(value, INTMASK);
+
+	/* read the value back to assure that it's really been written */
+	value = OCELOT_FPGA_READ(INTMASK);
+}
+
+/*
+ * Enables the IRQ in the FPGA
+ */
+static void enable_cpci_irq(unsigned int irq)
+{
+	unmask_cpci_irq(irq);
+}
+
+/*
+ * Initialize the IRQ in the FPGA
+ */
+static unsigned int startup_cpci_irq(unsigned int irq)
+{
+	unmask_cpci_irq(irq);
+	return 0;
+}
+
+/*
+ * Disables the IRQ in the FPGA
+ */
+static void disable_cpci_irq(unsigned int irq)
+{
+	mask_cpci_irq(irq);
+}
+
+/*
+ * Masks and ACKs an IRQ
+ */
+static void mask_and_ack_cpci_irq(unsigned int irq)
+{
+	mask_cpci_irq(irq);
+}
+
+/*
+ * End IRQ processing
+ */
+static void end_cpci_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		unmask_cpci_irq(irq);
+}
+
+/*
+ * Interrupt handler for interrupts coming from the FPGA chip.
+ * It could be built in ethernet ports etc...
+ */
+void ll_cpci_irq(struct pt_regs *regs)
+{
+	unsigned int irq_src, irq_mask;
+
+	/* read the interrupt status registers */
+	irq_src = OCELOT_FPGA_READ(INTSTAT);
+	irq_mask = OCELOT_FPGA_READ(INTMASK);
+
+	/* mask for just the interrupts we want */
+	irq_src &= ~irq_mask;
+
+	do_IRQ(ls1bit8(irq_src) + CPCI_IRQ_BASE, regs);
+}
+
+#define shutdown_cpci_irq	disable_cpci_irq
+
+struct hw_interrupt_type cpci_irq_type = {
+	"CPCI/FPGA",
+	startup_cpci_irq,
+	shutdown_cpci_irq,
+	enable_cpci_irq,
+	disable_cpci_irq,
+	mask_and_ack_cpci_irq,
+	end_cpci_irq,
+	NULL
+};
+
+void cpci_irq_init(void)
+{
+	int i;
+
+	/* Reset irq handlers pointers to NULL */
+	for (i = CPCI_IRQ_BASE; i < (CPCI_IRQ_BASE + 8); i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = 0;
+		irq_desc[i].depth = 2;
+		irq_desc[i].handler = &cpci_irq_type;
+	}
+}
diff --git a/arch/mips/momentum/ocelot_c/dbg_io.c b/arch/mips/momentum/ocelot_c/dbg_io.c
new file mode 100644
index 0000000..8720bcc
--- /dev/null
+++ b/arch/mips/momentum/ocelot_c/dbg_io.c
@@ -0,0 +1,126 @@
+#include <linux/config.h>
+
+#ifdef CONFIG_KGDB
+
+#include <asm/serial.h> /* For the serial port location and base baud */
+
+/* --- CONFIG --- */
+
+typedef unsigned char uint8;
+typedef unsigned int uint32;
+
+/* --- END OF CONFIG --- */
+
+#define         UART16550_BAUD_2400             2400
+#define         UART16550_BAUD_4800             4800
+#define         UART16550_BAUD_9600             9600
+#define         UART16550_BAUD_19200            19200
+#define         UART16550_BAUD_38400            38400
+#define         UART16550_BAUD_57600            57600
+#define         UART16550_BAUD_115200           115200
+
+#define         UART16550_PARITY_NONE           0
+#define         UART16550_PARITY_ODD            0x08
+#define         UART16550_PARITY_EVEN           0x18
+#define         UART16550_PARITY_MARK           0x28
+#define         UART16550_PARITY_SPACE          0x38
+
+#define         UART16550_DATA_5BIT             0x0
+#define         UART16550_DATA_6BIT             0x1
+#define         UART16550_DATA_7BIT             0x2
+#define         UART16550_DATA_8BIT             0x3
+
+#define         UART16550_STOP_1BIT             0x0
+#define         UART16550_STOP_2BIT             0x4
+
+/* ----------------------------------------------------- */
+
+/* === CONFIG === */
+
+/* [jsun] we use the second serial port for kdb */
+#define         BASE                    OCELOT_SERIAL1_BASE
+#define         MAX_BAUD                OCELOT_BASE_BAUD
+
+/* === END OF CONFIG === */
+
+#define         REG_OFFSET              4
+
+/* register offset */
+#define         OFS_RCV_BUFFER          0
+#define         OFS_TRANS_HOLD          0
+#define         OFS_SEND_BUFFER         0
+#define         OFS_INTR_ENABLE         (1*REG_OFFSET)
+#define         OFS_INTR_ID             (2*REG_OFFSET)
+#define         OFS_DATA_FORMAT         (3*REG_OFFSET)
+#define         OFS_LINE_CONTROL        (3*REG_OFFSET)
+#define         OFS_MODEM_CONTROL       (4*REG_OFFSET)
+#define         OFS_RS232_OUTPUT        (4*REG_OFFSET)
+#define         OFS_LINE_STATUS         (5*REG_OFFSET)
+#define         OFS_MODEM_STATUS        (6*REG_OFFSET)
+#define         OFS_RS232_INPUT         (6*REG_OFFSET)
+#define         OFS_SCRATCH_PAD         (7*REG_OFFSET)
+
+#define         OFS_DIVISOR_LSB         (0*REG_OFFSET)
+#define         OFS_DIVISOR_MSB         (1*REG_OFFSET)
+
+
+/* memory-mapped read/write of the port */
+#define         UART16550_READ(y)    (*((volatile uint8*)(BASE + y)))
+#define         UART16550_WRITE(y, z)  ((*((volatile uint8*)(BASE + y))) = z)
+
+void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
+{
+	/* disable interrupts */
+	UART16550_WRITE(OFS_INTR_ENABLE, 0);
+
+	/* set up buad rate */
+	{
+		uint32 divisor;
+
+		/* set DIAB bit */
+		UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
+
+		/* set divisor */
+		divisor = MAX_BAUD / baud;
+		UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
+		UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
+
+		/* clear DIAB bit */
+		UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
+	}
+
+	/* set data format */
+	UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
+}
+
+static int remoteDebugInitialized = 0;
+
+uint8 getDebugChar(void)
+{
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(UART16550_BAUD_38400,
+			  UART16550_DATA_8BIT,
+			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+	}
+
+	while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
+	return UART16550_READ(OFS_RCV_BUFFER);
+}
+
+
+int putDebugChar(uint8 byte)
+{
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(UART16550_BAUD_38400,
+			  UART16550_DATA_8BIT,
+			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+	}
+
+	while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
+	UART16550_WRITE(OFS_SEND_BUFFER, byte);
+	return 1;
+}
+
+#endif
diff --git a/arch/mips/momentum/ocelot_c/int-handler.S b/arch/mips/momentum/ocelot_c/int-handler.S
new file mode 100644
index 0000000..2f24306
--- /dev/null
+++ b/arch/mips/momentum/ocelot_c/int-handler.S
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2002 Momentum Computer Inc.
+ * Author: Matthew Dharm <mdharm@momenco.com>
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * First-level interrupt dispatcher for Ocelot-CS board.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include "ocelot_c_fpga.h"
+
+/*
+ * First level interrupt dispatcher for Ocelot-CS board
+ */
+		.align	5
+		NESTED(ocelot_handle_int, PT_SIZE, sp)
+		SAVE_ALL
+		CLI
+		.set	at
+		mfc0	t0, CP0_CAUSE  
+		mfc0	t2, CP0_STATUS
+
+		and	t0, t2
+        
+		andi	t1, t0, STATUSF_IP0	/* sw0 software interrupt */
+		bnez	t1, ll_sw0_irq
+		andi	t1, t0, STATUSF_IP1	/* sw1 software interrupt */
+		bnez	t1, ll_sw1_irq
+		andi	t1, t0, STATUSF_IP2	/* int0 hardware line */
+		bnez	t1, ll_scsi_irq
+		andi	t1, t0, STATUSF_IP3	/* int1 hardware line */
+		bnez	t1, ll_uart_decode_irq
+		andi	t1, t0, STATUSF_IP4	/* int2 hardware line */
+		bnez	t1, ll_pmc_irq
+		andi	t1, t0, STATUSF_IP5	/* int3 hardware line */
+		bnez	t1, ll_cpci_decode_irq
+		andi	t1, t0, STATUSF_IP6	/* int4 hardware line */
+		bnez	t1, ll_mv64340_decode_irq
+		andi	t1, t0, STATUSF_IP7	/* cpu timer */
+		bnez	t1, ll_cputimer_irq
+
+		.set	reorder
+
+		/* wrong alarm or masked ... */
+		j	spurious_interrupt
+		nop
+		END(ocelot_handle_int)
+
+		.align	5
+ll_sw0_irq:
+		li	a0, 0
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+ll_sw1_irq:
+		li	a0, 1
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+ll_scsi_irq:
+		li	a0, 2
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_uart_decode_irq:
+		move	a0, sp
+		jal	ll_uart_irq
+		j	ret_from_irq
+
+ll_pmc_irq:
+		li	a0, 4
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+	
+ll_cpci_decode_irq:
+		move	a0, sp
+		jal	ll_cpci_irq
+		j	ret_from_irq
+
+ll_mv64340_decode_irq:
+		move	a0, sp
+		jal	ll_mv64340_irq
+		j	ret_from_irq
+
+ll_cputimer_irq:
+		li	a0, 7
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+	
diff --git a/arch/mips/momentum/ocelot_c/irq.c b/arch/mips/momentum/ocelot_c/irq.c
new file mode 100644
index 0000000..300fe8e
--- /dev/null
+++ b/arch/mips/momentum/ocelot_c/irq.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: RidgeRun, Inc.
+ *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ * Copyright (C) 2000, 01, 05 Ralf Baechle (ralf@linux-mips.org)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/mv64340.h>
+#include <asm/system.h>
+
+extern asmlinkage void ocelot_handle_int(void);
+extern void uart_irq_init(void);
+extern void cpci_irq_init(void);
+
+static struct irqaction cascade_fpga = {
+	no_action, SA_INTERRUPT, CPU_MASK_NONE, "cascade via FPGA", NULL, NULL
+};
+
+static struct irqaction cascade_mv64340 = {
+	no_action, SA_INTERRUPT, CPU_MASK_NONE, "cascade via MV64340", NULL, NULL
+};
+
+void __init arch_init_irq(void)
+{
+	/*
+	 * Clear all of the interrupts while we change the able around a bit.
+	 * int-handler is not on bootstrap
+	 */
+	clear_c0_status(ST0_IM);
+
+	/* Sets the first-level interrupt dispatcher. */
+	set_except_vector(0, ocelot_handle_int);
+	mips_cpu_irq_init(0);
+
+	/* set up the cascading interrupts */
+	setup_irq(3, &cascade_fpga);
+	setup_irq(5, &cascade_fpga);
+	setup_irq(6, &cascade_mv64340);
+
+	mv64340_irq_init(16);
+	uart_irq_init();
+	cpci_irq_init();
+}
diff --git a/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h b/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h
new file mode 100644
index 0000000..a6cf7a7
--- /dev/null
+++ b/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h
@@ -0,0 +1,60 @@
+/*
+ * Ocelot-C Board Register Definitions
+ *
+ * (C) 2002 Momentum Computer Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  Louis Hamilton, Red Hat, Inc.
+ *    hamilton@redhat.com  [MIPS64 modifications]
+ */
+
+#ifndef __OCELOT_C_FPGA_H__
+#define __OCELOT_C_FPGA_H__
+
+#include <linux/config.h>
+
+#ifdef CONFIG_MIPS64
+#define OCELOT_C_CS0_ADDR       (0xfffffffffc000000)
+#else
+#define OCELOT_C_CS0_ADDR               (0xfc000000)
+#endif
+
+#define OCELOT_C_REG_BOARDREV		0x0
+#define OCELOT_C_REG_FPGA_REV		0x1
+#define OCELOT_C_REG_FPGA_TYPE		0x2
+#define OCELOT_C_REG_RESET_STATUS	0x3
+#define OCELOT_C_REG_BOARD_STATUS	0x4
+#define OCELOT_C_REG_CPCI_ID		0x5
+#define OCELOT_C_REG_SET		0x6
+#define OCELOT_C_REG_CLR		0x7
+#define OCELOT_C_REG_EEPROM_MODE	0x9
+#define OCELOT_C_REG_INTMASK		0xa
+#define OCELOT_C_REG_INTSTAT		0xb
+#define OCELOT_C_REG_UART_INTMASK	0xc
+#define OCELOT_C_REG_UART_INTSTAT	0xd
+#define OCELOT_C_REG_INTSET		0xe
+#define OCELOT_C_REG_INTCLR		0xf
+
+#define OCELOT_FPGA_WRITE(x, y) writeb(x, OCELOT_C_CS0_ADDR + OCELOT_C_REG_##y)
+#define OCELOT_FPGA_READ(x) readb(OCELOT_C_CS0_ADDR + OCELOT_C_REG_##x)
+
+#endif
diff --git a/arch/mips/momentum/ocelot_c/prom.c b/arch/mips/momentum/ocelot_c/prom.c
new file mode 100644
index 0000000..49ac302
--- /dev/null
+++ b/arch/mips/momentum/ocelot_c/prom.c
@@ -0,0 +1,243 @@
+/*
+ * Copyright 2002 Momentum Computer Inc.
+ * Author: Matthew Dharm <mdharm@momenco.com>
+ *
+ * Louis Hamilton, Red Hat, Inc.
+ *   hamilton@redhat.com  [MIPS64 modifications]
+ *
+ * Based on Ocelot Linux port, which is
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/mv64340.h>
+#include <asm/pmon.h>
+
+#include "ocelot_c_fpga.h"
+
+struct callvectors* debug_vectors;
+
+extern unsigned long marvell_base;
+extern unsigned long cpu_clock;
+
+#ifdef CONFIG_MV643XX_ETH
+extern unsigned char prom_mac_addr_base[6];
+#endif
+
+const char *get_system_type(void)
+{
+#ifdef CONFIG_CPU_SR71000
+	return "Momentum Ocelot-CS";
+#else
+	return "Momentum Ocelot-C";
+#endif
+}
+
+#ifdef CONFIG_MV643XX_ETH
+static void burn_clocks(void)
+{
+	int i;
+
+	/* this loop should burn at least 1us -- this should be plenty */
+	for (i = 0; i < 0x10000; i++)
+		;
+}
+
+static u8 exchange_bit(u8 val, u8 cs)
+{
+	/* place the data */
+	OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE);
+	burn_clocks();
+
+	/* turn the clock on */
+	OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE);
+	burn_clocks();
+
+	/* turn the clock off and read-strobe */
+	OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE);
+	
+	/* return the data */
+	return ((OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1);
+}
+
+void get_mac(char dest[6])
+{
+	u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+	int i,j;
+
+	for (i = 0; i < 12; i++)
+		exchange_bit(read_opcode[i], 1);
+
+	for (j = 0; j < 6; j++) {
+		dest[j] = 0;
+		for (i = 0; i < 8; i++) {
+			dest[j] <<= 1;
+			dest[j] |= exchange_bit(0, 1);
+		}
+	}
+
+	/* turn off CS */
+	exchange_bit(0,0);
+}
+#endif
+
+
+#ifdef CONFIG_MIPS64
+
+unsigned long signext(unsigned long addr)
+{
+  addr &= 0xffffffff;
+  return (unsigned long)((int)addr);
+}
+
+void *get_arg(unsigned long args, int arc)
+{
+  unsigned long ul;
+  unsigned char *puc, uc;
+
+  args += (arc * 4);
+  ul = (unsigned long)signext(args);
+  puc = (unsigned char *)ul;
+  if (puc == 0)
+    return (void *)0;
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+  uc = *puc++;
+  ul = (unsigned long)uc;
+  uc = *puc++;
+  ul |= (((unsigned long)uc) << 8);
+  uc = *puc++;
+  ul |= (((unsigned long)uc) << 16);
+  uc = *puc++;
+  ul |= (((unsigned long)uc) << 24);
+#else  /* CONFIG_CPU_LITTLE_ENDIAN */
+  uc = *puc++;
+  ul = ((unsigned long)uc) << 24;
+  uc = *puc++;
+  ul |= (((unsigned long)uc) << 16);
+  uc = *puc++;
+  ul |= (((unsigned long)uc) << 8);
+  uc = *puc++;
+  ul |= ((unsigned long)uc);
+#endif  /* CONFIG_CPU_LITTLE_ENDIAN */
+  ul = signext(ul);
+  return (void *)ul;
+}
+
+char *arg64(unsigned long addrin, int arg_index)
+{
+  unsigned long args;
+  char *p;
+  args = signext(addrin);
+  p = (char *)get_arg(args, arg_index);
+  return p;
+}
+#endif  /* CONFIG_MIPS64 */
+
+
+void __init prom_init(void)
+{
+	int argc = fw_arg0;
+	char **arg = (char **) fw_arg1;
+	char **env = (char **) fw_arg2;
+	struct callvectors *cv = (struct callvectors *) fw_arg3;
+	int i;
+
+#ifdef CONFIG_MIPS64
+	char *ptr;
+
+	printk("prom_init - MIPS64\n");
+	/* save the PROM vectors for debugging use */
+	debug_vectors = (struct callvectors *)signext((unsigned long)cv);
+
+	/* arg[0] is "g", the rest is boot parameters */
+	arcs_cmdline[0] = '\0';
+
+	for (i = 1; i < argc; i++) {
+		ptr = (char *)arg64((unsigned long)arg, i);
+		if ((strlen(arcs_cmdline) + strlen(ptr) + 1) >=
+		    sizeof(arcs_cmdline))
+			break;
+		strcat(arcs_cmdline, ptr);
+		strcat(arcs_cmdline, " ");
+	}
+	i = 0;
+	while (1) {
+		ptr = (char *)arg64((unsigned long)env, i);
+		if (! ptr)
+			break;
+
+		if (strncmp("gtbase", ptr, strlen("gtbase")) == 0) {
+			marvell_base = simple_strtol(ptr + strlen("gtbase="),
+							NULL, 16);
+
+			if ((marvell_base & 0xffffffff00000000) == 0)
+				marvell_base |= 0xffffffff00000000;
+
+			printk("marvell_base set to 0x%016lx\n", marvell_base);
+		}
+		if (strncmp("cpuclock", ptr, strlen("cpuclock")) == 0) {
+			cpu_clock = simple_strtol(ptr + strlen("cpuclock="),
+							NULL, 10);
+			printk("cpu_clock set to %d\n", cpu_clock);
+		}
+		i++;
+	}
+	printk("arcs_cmdline: %s\n", arcs_cmdline);
+
+#else   /* CONFIG_MIPS64 */
+	/* save the PROM vectors for debugging use */
+	debug_vectors = cv;
+
+	/* arg[0] is "g", the rest is boot parameters */
+	arcs_cmdline[0] = '\0';
+	for (i = 1; i < argc; i++) {
+		if (strlen(arcs_cmdline) + strlen(arg[i] + 1)
+		    >= sizeof(arcs_cmdline))
+			break;
+		strcat(arcs_cmdline, arg[i]);
+		strcat(arcs_cmdline, " ");
+	}
+
+	while (*env) {
+		if (strncmp("gtbase", *env, strlen("gtbase")) == 0) {
+			marvell_base = simple_strtol(*env + strlen("gtbase="),
+							NULL, 16);
+		}
+		if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) {
+			cpu_clock = simple_strtol(*env + strlen("cpuclock="),
+							NULL, 10);
+		}
+		env++;
+	}
+#endif /* CONFIG_MIPS64 */
+
+	mips_machgroup = MACH_GROUP_MOMENCO;
+	mips_machtype = MACH_MOMENCO_OCELOT_C;
+
+#ifdef CONFIG_MV643XX_ETH
+	/* get the base MAC address for on-board ethernet ports */
+	get_mac(prom_mac_addr_base);
+#endif
+
+#ifndef CONFIG_MIPS64
+	debug_vectors->printf("Booting Linux kernel...\n");
+#endif
+}
+
+unsigned long __init prom_free_prom_memory(void)
+{
+	return 0;
+}
diff --git a/arch/mips/momentum/ocelot_c/reset.c b/arch/mips/momentum/ocelot_c/reset.c
new file mode 100644
index 0000000..1f2b426
--- /dev/null
+++ b/arch/mips/momentum/ocelot_c/reset.c
@@ -0,0 +1,59 @@
+/*
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Copyright (C) 1997, 2001 Ralf Baechle
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * Copyright (C) 2002 Momentum Computer Inc.
+ * Author: Matthew Dharm <mdharm@momenco.com>
+ *
+ * Louis Hamilton, Red Hat, Inc.
+ * hamilton@redhat.com  [MIPS64 modifications]
+ */
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <linux/delay.h>
+
+void momenco_ocelot_restart(char *command)
+{
+	/* base address of timekeeper portion of part */
+	void *nvram = (void *)
+#ifdef CONFIG_MIPS64
+		0xfffffffffc807000;
+#else
+		0xfc807000;
+#endif
+
+ 	/* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */
+	writeb(0x84, nvram + 0xff7);
+
+	/* wait for the watchdog to go off */
+	mdelay(100+(1000/16));
+
+	/* if the watchdog fails for some reason, let people know */
+	printk(KERN_NOTICE "Watchdog reset failed\n");
+}
+
+void momenco_ocelot_halt(void)
+{
+	printk(KERN_NOTICE "\n** You can safely turn off the power\n");
+	while (1)
+		__asm__(".set\tmips3\n\t"
+	                "wait\n\t"
+			".set\tmips0");
+}
+
+void momenco_ocelot_power_off(void)
+{
+	momenco_ocelot_halt();
+}
diff --git a/arch/mips/momentum/ocelot_c/setup.c b/arch/mips/momentum/ocelot_c/setup.c
new file mode 100644
index 0000000..021c00e
--- /dev/null
+++ b/arch/mips/momentum/ocelot_c/setup.c
@@ -0,0 +1,363 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ * Momentum Computer Ocelot-C and -CS board dependent boot routines
+ *
+ * Copyright (C) 1996, 1997, 2001  Ralf Baechle
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Copyright (C) 2001 Red Hat, Inc.
+ * Copyright (C) 2002 Momentum Computer
+ *
+ * Author: Matthew Dharm, Momentum Computer
+ *   mdharm@momenco.com
+ *
+ * Louis Hamilton, Red Hat, Inc.
+ *   hamilton@redhat.com  [MIPS64 modifications]
+ *
+ * Author: RidgeRun, Inc.
+ *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/config.h>
+#include <linux/bcd.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/timex.h>
+#include <linux/vmalloc.h>
+#include <asm/time.h>
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pci.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/reboot.h>
+#include <linux/bootmem.h>
+#include <linux/blkdev.h>
+#include <asm/mv64340.h>
+#include "ocelot_c_fpga.h"
+
+unsigned long marvell_base;
+extern unsigned long mv64340_sram_base;
+unsigned long cpu_clock;
+
+/* These functions are used for rebooting or halting the machine*/
+extern void momenco_ocelot_restart(char *command);
+extern void momenco_ocelot_halt(void);
+extern void momenco_ocelot_power_off(void);
+
+void momenco_time_init(void);
+
+static char reset_reason;
+
+void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, unsigned long entryhi, unsigned long pagemask);
+
+static unsigned long ENTRYLO(unsigned long paddr)
+{
+	return ((paddr & PAGE_MASK) |
+	       (_PAGE_PRESENT | __READABLE | __WRITEABLE | _PAGE_GLOBAL |
+		_CACHE_UNCACHED)) >> 6;
+}
+
+/* setup code for a handoff from a version 2 PMON 2000 PROM */
+void PMON_v2_setup(void)
+{
+	/* Some wired TLB entries for the MV64340 and perhiperals. The
+	   MV64340 is going to be hit on every IRQ anyway - there's
+	   absolutely no point in letting it be a random TLB entry, as
+	   it'll just cause needless churning of the TLB. And we use
+	   the other half for the serial port, which is just a PITA
+	   otherwise :)
+
+		Device			Physical	Virtual
+		MV64340 Internal Regs	0xf4000000	0xf4000000
+		Ocelot-C[S] PLD (CS0)	0xfc000000	0xfc000000
+		NVRAM (CS1)		0xfc800000	0xfc800000
+		UARTs (CS2)		0xfd000000	0xfd000000
+		Internal SRAM		0xfe000000	0xfe000000
+		M-Systems DOC (CS3)	0xff000000	0xff000000
+	*/
+  printk("PMON_v2_setup\n");
+
+#ifdef CONFIG_MIPS64
+	/* marvell and extra space */
+	add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), 0xfffffffff4000000, PM_64K);
+	/* fpga, rtc, and uart */
+	add_wired_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfd000000), 0xfffffffffc000000, PM_16M);
+	/* m-sys and internal SRAM */
+	add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000), 0xfffffffffe000000, PM_16M);
+
+	marvell_base = 0xfffffffff4000000;
+	mv64340_sram_base = 0xfffffffffe000000;
+#else
+	/* marvell and extra space */
+	add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), 0xf4000000, PM_64K);
+	/* fpga, rtc, and uart */
+	add_wired_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfd000000), 0xfc000000, PM_16M);
+	/* m-sys and internal SRAM */
+	add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000), 0xfe000000, PM_16M);
+
+	marvell_base = 0xf4000000;
+	mv64340_sram_base = 0xfe000000;
+#endif
+}
+
+unsigned long m48t37y_get_time(void)
+{
+#ifdef CONFIG_MIPS64
+	unsigned char *rtc_base = (unsigned char*)0xfffffffffc800000;
+#else
+	unsigned char* rtc_base = (unsigned char*)0xfc800000;
+#endif
+	unsigned int year, month, day, hour, min, sec;
+
+	/* stop the update */
+	rtc_base[0x7ff8] = 0x40;
+
+	year = BCD2BIN(rtc_base[0x7fff]);
+	year += BCD2BIN(rtc_base[0x7ff1]) * 100;
+
+	month = BCD2BIN(rtc_base[0x7ffe]);
+
+	day = BCD2BIN(rtc_base[0x7ffd]);
+
+	hour = BCD2BIN(rtc_base[0x7ffb]);
+	min = BCD2BIN(rtc_base[0x7ffa]);
+	sec = BCD2BIN(rtc_base[0x7ff9]);
+
+	/* start the update */
+	rtc_base[0x7ff8] = 0x00;
+
+	return mktime(year, month, day, hour, min, sec);
+}
+
+int m48t37y_set_time(unsigned long sec)
+{
+#ifdef CONFIG_MIPS64
+	unsigned char* rtc_base = (unsigned char*)0xfffffffffc800000;
+#else
+	unsigned char* rtc_base = (unsigned char*)0xfc800000;
+#endif
+	struct rtc_time tm;
+
+	/* convert to a more useful format -- note months count from 0 */
+	to_tm(sec, &tm);
+	tm.tm_mon += 1;
+
+	/* enable writing */
+	rtc_base[0x7ff8] = 0x80;
+
+	/* year */
+	rtc_base[0x7fff] = BIN2BCD(tm.tm_year % 100);
+	rtc_base[0x7ff1] = BIN2BCD(tm.tm_year / 100);
+
+	/* month */
+	rtc_base[0x7ffe] = BIN2BCD(tm.tm_mon);
+
+	/* day */
+	rtc_base[0x7ffd] = BIN2BCD(tm.tm_mday);
+
+	/* hour/min/sec */
+	rtc_base[0x7ffb] = BIN2BCD(tm.tm_hour);
+	rtc_base[0x7ffa] = BIN2BCD(tm.tm_min);
+	rtc_base[0x7ff9] = BIN2BCD(tm.tm_sec);
+
+	/* day of week -- not really used, but let's keep it up-to-date */
+	rtc_base[0x7ffc] = BIN2BCD(tm.tm_wday + 1);
+
+	/* disable writing */
+	rtc_base[0x7ff8] = 0x00;
+
+	return 0;
+}
+
+void momenco_timer_setup(struct irqaction *irq)
+{
+	setup_irq(7, irq);
+}
+
+void momenco_time_init(void)
+{
+#ifdef CONFIG_CPU_SR71000
+	mips_hpt_frequency = cpu_clock;
+#elif defined(CONFIG_CPU_RM7000)
+	mips_hpt_frequency = cpu_clock / 2;
+#else
+#error Unknown CPU for this board
+#endif
+	printk("momenco_time_init cpu_clock=%d\n", cpu_clock);
+	board_timer_setup = momenco_timer_setup;
+
+	rtc_get_time = m48t37y_get_time;
+	rtc_set_time = m48t37y_set_time;
+}
+
+static void __init momenco_ocelot_c_setup(void)
+{
+	unsigned int tmpword;
+
+	board_time_init = momenco_time_init;
+
+	_machine_restart = momenco_ocelot_restart;
+	_machine_halt = momenco_ocelot_halt;
+	_machine_power_off = momenco_ocelot_power_off;
+
+	/*
+	 * initrd_start = (ulong)ocelot_initrd_start;
+	 * initrd_end = (ulong)ocelot_initrd_start + (ulong)ocelot_initrd_size;
+	 * initrd_below_start_ok = 1;
+	 */
+
+	/* do handoff reconfiguration */
+	PMON_v2_setup();
+
+	/* shut down ethernet ports, just to be sure our memory doesn't get
+	 * corrupted by random ethernet traffic.
+	 */
+	MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8);
+	MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8);
+	MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8);
+	MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8);
+	do {}
+	  while (MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff);
+	do {}
+	  while (MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff);
+	do {}
+	  while (MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff);
+	do {}
+	  while (MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff);
+	MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0),
+	         MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1);
+	MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1),
+	         MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1);
+
+	/* Turn off the Bit-Error LED */
+	OCELOT_FPGA_WRITE(0x80, CLR);
+
+	tmpword = OCELOT_FPGA_READ(BOARDREV);
+#ifdef CONFIG_CPU_SR71000
+	if (tmpword < 26)
+		printk("Momenco Ocelot-CS: Board Assembly Rev. %c\n",
+			'A'+tmpword);
+	else
+		printk("Momenco Ocelot-CS: Board Assembly Revision #0x%x\n",
+			tmpword);
+#else
+	if (tmpword < 26)
+		printk("Momenco Ocelot-C: Board Assembly Rev. %c\n",
+			'A'+tmpword);
+	else
+		printk("Momenco Ocelot-C: Board Assembly Revision #0x%x\n",
+			tmpword);
+#endif
+
+	tmpword = OCELOT_FPGA_READ(FPGA_REV);
+	printk("FPGA Rev: %d.%d\n", tmpword>>4, tmpword&15);
+	tmpword = OCELOT_FPGA_READ(RESET_STATUS);
+	printk("Reset reason: 0x%x\n", tmpword);
+	switch (tmpword) {
+		case 0x1:
+			printk("  - Power-up reset\n");
+			break;
+		case 0x2:
+			printk("  - Push-button reset\n");
+			break;
+		case 0x4:
+			printk("  - cPCI bus reset\n");
+			break;
+		case 0x8:
+			printk("  - Watchdog reset\n");
+			break;
+		case 0x10:
+			printk("  - Software reset\n");
+			break;
+		default:
+			printk("  - Unknown reset cause\n");
+	}
+	reset_reason = tmpword;
+	OCELOT_FPGA_WRITE(0xff, RESET_STATUS);
+
+	tmpword = OCELOT_FPGA_READ(CPCI_ID);
+	printk("cPCI ID register: 0x%02x\n", tmpword);
+	printk("  - Slot number: %d\n", tmpword & 0x1f);
+	printk("  - PCI bus present: %s\n", tmpword & 0x40 ? "yes" : "no");
+	printk("  - System Slot: %s\n", tmpword & 0x20 ? "yes" : "no");
+
+	tmpword = OCELOT_FPGA_READ(BOARD_STATUS);
+	printk("Board Status register: 0x%02x\n", tmpword);
+	printk("  - User jumper: %s\n", (tmpword & 0x80)?"installed":"absent");
+	printk("  - Boot flash write jumper: %s\n", (tmpword&0x40)?"installed":"absent");
+	printk("  - L3 Cache size: %d MiB\n", (1<<((tmpword&12) >> 2))&~1);
+	printk("  - SDRAM size: %d MiB\n", 1<<(6+(tmpword&3)));
+
+	switch(tmpword &3) {
+	case 3:
+		/* 512MiB */
+		add_memory_region(0x0, 0x200<<20, BOOT_MEM_RAM);
+		break;
+	case 2:
+		/* 256MiB */
+		add_memory_region(0x0, 0x100<<20, BOOT_MEM_RAM);
+		break;
+	case 1:
+		/* 128MiB */
+		add_memory_region(0x0,  0x80<<20, BOOT_MEM_RAM);
+		break;
+	case 0:
+		/* 1GiB -- needs CONFIG_HIGHMEM */
+		add_memory_region(0x0, 0x400<<20, BOOT_MEM_RAM);
+		break;
+	}
+}
+
+early_initcall(momenco_ocelot_c_setup);
+
+#ifndef CONFIG_MIPS64
+/* This needs to be one of the first initcalls, because no I/O port access
+   can work before this */
+static int io_base_ioremap(void)
+{
+	/* we're mapping PCI accesses from 0xc0000000 to 0xf0000000 */
+	void *io_remap_range = ioremap(0xc0000000, 0x30000000);
+
+	if (!io_remap_range) {
+		panic("Could not ioremap I/O port range");
+	}
+	printk("io_remap_range set at 0x%08x\n", (uint32_t)io_remap_range);
+	set_io_port_base(io_remap_range - 0xc0000000);
+
+	return 0;
+}
+
+module_init(io_base_ioremap);
+#endif
diff --git a/arch/mips/momentum/ocelot_c/uart-irq.c b/arch/mips/momentum/ocelot_c/uart-irq.c
new file mode 100644
index 0000000..ebe1507
--- /dev/null
+++ b/arch/mips/momentum/ocelot_c/uart-irq.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2002 Momentum Computer
+ * Author: mdharm@momenco.com
+ *
+ * arch/mips/momentum/ocelot_c/uart-irq.c
+ *     Interrupt routines for UARTs.  Interrupt numbers are assigned from
+ *     80 to 81 (2 interrupt sources).
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <asm/ptrace.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include "ocelot_c_fpga.h"
+
+static inline int ls1bit8(unsigned int x)
+{
+        int b = 7, s;
+
+        s =  4; if (((unsigned char)(x << 4)) == 0) s = 0; b -= s; x <<= s;
+        s =  2; if (((unsigned char)(x << 2)) == 0) s = 0; b -= s; x <<= s;
+        s =  1; if (((unsigned char)(x << 1)) == 0) s = 0; b -= s;
+
+        return b;
+}
+
+/* mask off an interrupt -- 0 is enable, 1 is disable */
+static inline void mask_uart_irq(unsigned int irq)
+{
+	uint8_t value;
+
+	value = OCELOT_FPGA_READ(UART_INTMASK);
+	value |= 1 << (irq - 74);
+	OCELOT_FPGA_WRITE(value, UART_INTMASK);
+
+	/* read the value back to assure that it's really been written */
+	value = OCELOT_FPGA_READ(UART_INTMASK);
+}
+
+/* unmask an interrupt -- 0 is enable, 1 is disable */
+static inline void unmask_uart_irq(unsigned int irq)
+{
+	uint8_t value;
+
+	value = OCELOT_FPGA_READ(UART_INTMASK);
+	value &= ~(1 << (irq - 74));
+	OCELOT_FPGA_WRITE(value, UART_INTMASK);
+
+	/* read the value back to assure that it's really been written */
+	value = OCELOT_FPGA_READ(UART_INTMASK);
+}
+
+/*
+ * Enables the IRQ in the FPGA
+ */
+static void enable_uart_irq(unsigned int irq)
+{
+	unmask_uart_irq(irq);
+}
+
+/*
+ * Initialize the IRQ in the FPGA
+ */
+static unsigned int startup_uart_irq(unsigned int irq)
+{
+	unmask_uart_irq(irq);
+	return 0;
+}
+
+/*
+ * Disables the IRQ in the FPGA
+ */
+static void disable_uart_irq(unsigned int irq)
+{
+	mask_uart_irq(irq);
+}
+
+/*
+ * Masks and ACKs an IRQ
+ */
+static void mask_and_ack_uart_irq(unsigned int irq)
+{
+	mask_uart_irq(irq);
+}
+
+/*
+ * End IRQ processing
+ */
+static void end_uart_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		unmask_uart_irq(irq);
+}
+
+/*
+ * Interrupt handler for interrupts coming from the FPGA chip.
+ */
+void ll_uart_irq(struct pt_regs *regs)
+{
+	unsigned int irq_src, irq_mask;
+
+	/* read the interrupt status registers */
+	irq_src = OCELOT_FPGA_READ(UART_INTSTAT);
+	irq_mask = OCELOT_FPGA_READ(UART_INTMASK);
+
+	/* mask for just the interrupts we want */
+	irq_src &= ~irq_mask;
+
+	do_IRQ(ls1bit8(irq_src) + 74, regs);
+}
+
+#define shutdown_uart_irq	disable_uart_irq
+
+struct hw_interrupt_type uart_irq_type = {
+	"UART/FPGA",
+	startup_uart_irq,
+	shutdown_uart_irq,
+	enable_uart_irq,
+	disable_uart_irq,
+	mask_and_ack_uart_irq,
+	end_uart_irq,
+	NULL
+};
+
+void uart_irq_init(void)
+{
+	/* Reset irq handlers pointers to NULL */
+	irq_desc[80].status = IRQ_DISABLED;
+	irq_desc[80].action = 0;
+	irq_desc[80].depth = 2;
+	irq_desc[80].handler = &uart_irq_type;
+
+	irq_desc[81].status = IRQ_DISABLED;
+	irq_desc[81].action = 0;
+	irq_desc[81].depth = 2;
+	irq_desc[81].handler = &uart_irq_type;
+}
diff --git a/arch/mips/momentum/ocelot_g/Makefile b/arch/mips/momentum/ocelot_g/Makefile
new file mode 100644
index 0000000..e5f1cb0
--- /dev/null
+++ b/arch/mips/momentum/ocelot_g/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for Momentum Computer's Ocelot-G board.
+#
+
+obj-y	 		+= int-handler.o irq.o gt-irq.o prom.o reset.o setup.o
+obj-$(CONFIG_KGDB)	+= dbg_io.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/momentum/ocelot_g/dbg_io.c b/arch/mips/momentum/ocelot_g/dbg_io.c
new file mode 100644
index 0000000..8720bcc
--- /dev/null
+++ b/arch/mips/momentum/ocelot_g/dbg_io.c
@@ -0,0 +1,126 @@
+#include <linux/config.h>
+
+#ifdef CONFIG_KGDB
+
+#include <asm/serial.h> /* For the serial port location and base baud */
+
+/* --- CONFIG --- */
+
+typedef unsigned char uint8;
+typedef unsigned int uint32;
+
+/* --- END OF CONFIG --- */
+
+#define         UART16550_BAUD_2400             2400
+#define         UART16550_BAUD_4800             4800
+#define         UART16550_BAUD_9600             9600
+#define         UART16550_BAUD_19200            19200
+#define         UART16550_BAUD_38400            38400
+#define         UART16550_BAUD_57600            57600
+#define         UART16550_BAUD_115200           115200
+
+#define         UART16550_PARITY_NONE           0
+#define         UART16550_PARITY_ODD            0x08
+#define         UART16550_PARITY_EVEN           0x18
+#define         UART16550_PARITY_MARK           0x28
+#define         UART16550_PARITY_SPACE          0x38
+
+#define         UART16550_DATA_5BIT             0x0
+#define         UART16550_DATA_6BIT             0x1
+#define         UART16550_DATA_7BIT             0x2
+#define         UART16550_DATA_8BIT             0x3
+
+#define         UART16550_STOP_1BIT             0x0
+#define         UART16550_STOP_2BIT             0x4
+
+/* ----------------------------------------------------- */
+
+/* === CONFIG === */
+
+/* [jsun] we use the second serial port for kdb */
+#define         BASE                    OCELOT_SERIAL1_BASE
+#define         MAX_BAUD                OCELOT_BASE_BAUD
+
+/* === END OF CONFIG === */
+
+#define         REG_OFFSET              4
+
+/* register offset */
+#define         OFS_RCV_BUFFER          0
+#define         OFS_TRANS_HOLD          0
+#define         OFS_SEND_BUFFER         0
+#define         OFS_INTR_ENABLE         (1*REG_OFFSET)
+#define         OFS_INTR_ID             (2*REG_OFFSET)
+#define         OFS_DATA_FORMAT         (3*REG_OFFSET)
+#define         OFS_LINE_CONTROL        (3*REG_OFFSET)
+#define         OFS_MODEM_CONTROL       (4*REG_OFFSET)
+#define         OFS_RS232_OUTPUT        (4*REG_OFFSET)
+#define         OFS_LINE_STATUS         (5*REG_OFFSET)
+#define         OFS_MODEM_STATUS        (6*REG_OFFSET)
+#define         OFS_RS232_INPUT         (6*REG_OFFSET)
+#define         OFS_SCRATCH_PAD         (7*REG_OFFSET)
+
+#define         OFS_DIVISOR_LSB         (0*REG_OFFSET)
+#define         OFS_DIVISOR_MSB         (1*REG_OFFSET)
+
+
+/* memory-mapped read/write of the port */
+#define         UART16550_READ(y)    (*((volatile uint8*)(BASE + y)))
+#define         UART16550_WRITE(y, z)  ((*((volatile uint8*)(BASE + y))) = z)
+
+void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
+{
+	/* disable interrupts */
+	UART16550_WRITE(OFS_INTR_ENABLE, 0);
+
+	/* set up buad rate */
+	{
+		uint32 divisor;
+
+		/* set DIAB bit */
+		UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
+
+		/* set divisor */
+		divisor = MAX_BAUD / baud;
+		UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
+		UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
+
+		/* clear DIAB bit */
+		UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
+	}
+
+	/* set data format */
+	UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
+}
+
+static int remoteDebugInitialized = 0;
+
+uint8 getDebugChar(void)
+{
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(UART16550_BAUD_38400,
+			  UART16550_DATA_8BIT,
+			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+	}
+
+	while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
+	return UART16550_READ(OFS_RCV_BUFFER);
+}
+
+
+int putDebugChar(uint8 byte)
+{
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(UART16550_BAUD_38400,
+			  UART16550_DATA_8BIT,
+			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+	}
+
+	while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
+	UART16550_WRITE(OFS_SEND_BUFFER, byte);
+	return 1;
+}
+
+#endif
diff --git a/arch/mips/momentum/ocelot_g/gt-irq.c b/arch/mips/momentum/ocelot_g/gt-irq.c
new file mode 100644
index 0000000..d0b5c9d
--- /dev/null
+++ b/arch/mips/momentum/ocelot_g/gt-irq.c
@@ -0,0 +1,214 @@
+/*
+ *
+ * Copyright 2002 Momentum Computer
+ * Author: mdharm@momenco.com
+ *
+ * arch/mips/momentum/ocelot_g/gt_irq.c
+ *     Interrupt routines for gt64240.  Currently it only handles timer irq.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <asm/ptrace.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <asm/gt64240.h>
+#include <asm/io.h>
+
+unsigned long bus_clock;
+
+/*
+ * These are interrupt handlers for the GT on-chip interrupts.  They
+ * all come in to the MIPS on a single interrupt line, and have to
+ * be handled and ack'ed differently than other MIPS interrupts.
+ */
+
+#if CURRENTLY_UNUSED
+
+struct tq_struct irq_handlers[MAX_CAUSE_REGS][MAX_CAUSE_REG_WIDTH];
+void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr);
+
+/*
+ * Hooks IRQ handler to the system. When the system is interrupted
+ * the interrupt service routine is called.
+ *
+ * Inputs :
+ * int_cause - The interrupt cause number. In EVB64120 two parameters
+ *             are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
+ * bit_num   - Indicates which bit number in the cause register
+ * isr_ptr   - Pointer to the interrupt service routine
+ */
+void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr)
+{
+	irq_handlers[int_cause][bit_num].routine = isr_ptr;
+}
+
+
+/*
+ * Enables the IRQ on Galileo Chip
+ *
+ * Inputs :
+ * int_cause - The interrupt cause number. In EVB64120 two parameters
+ *             are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
+ * bit_num   - Indicates which bit number in the cause register
+ *
+ * Outputs :
+ * 1 if succesful, 0 if failure
+ */
+int enable_galileo_irq(int int_cause, int bit_num)
+{
+	if (int_cause == INT_CAUSE_MAIN)
+		SET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER, (1 << bit_num));
+	else if (int_cause == INT_CAUSE_HIGH)
+		SET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER,
+			     (1 << bit_num));
+	else
+		return 0;
+
+	return 1;
+}
+
+/*
+ * Disables the IRQ on Galileo Chip
+ *
+ * Inputs :
+ * int_cause - The interrupt cause number. In EVB64120 two parameters
+ *             are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
+ * bit_num   - Indicates which bit number in the cause register
+ *
+ * Outputs :
+ * 1 if succesful, 0 if failure
+ */
+int disable_galileo_irq(int int_cause, int bit_num)
+{
+	if (int_cause == INT_CAUSE_MAIN)
+		RESET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER,
+			       (1 << bit_num));
+	else if (int_cause == INT_CAUSE_HIGH)
+		RESET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER,
+			       (1 << bit_num));
+	else
+		return 0;
+	return 1;
+}
+#endif				/*  UNUSED  */
+
+/*
+ * Interrupt handler for interrupts coming from the Galileo chip via P0_INT#.
+ *
+ * We route the timer interrupt to P0_INT# (IRQ 6), and that's all this
+ * routine can handle, for now.
+ *
+ * In the future, we'll route more interrupts to this pin, and that's why
+ * we keep this particular structure in the function.
+ */
+
+static irqreturn_t gt64240_p0int_irq(int irq, void *dev, struct pt_regs *regs)
+{
+	uint32_t irq_src, irq_src_mask;
+	int handled;
+
+	/* get the low interrupt cause register */
+	irq_src = MV_READ(LOW_INTERRUPT_CAUSE_REGISTER);
+
+	/* get the mask register for this pin */
+	irq_src_mask = MV_READ(PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW);
+
+	/* mask off only the interrupts we're interested in */
+	irq_src = irq_src & irq_src_mask;
+
+	handled = IRQ_NONE;
+
+	/* Check for timer interrupt */
+	if (irq_src & 0x00000100) {
+		handled = IRQ_HANDLED;
+		irq_src &= ~0x00000100;
+
+		/* Clear any pending cause bits */
+		MV_WRITE(TIMER_COUNTER_0_3_INTERRUPT_CAUSE, 0x0);
+
+		/* handle the timer call */
+		do_timer(regs);
+#ifndef CONFIG_SMP
+		update_process_times(user_mode(regs));
+#endif
+	}
+
+	if (irq_src) {
+		printk(KERN_INFO
+		       "UNKNOWN P0_INT# interrupt received, irq_src=0x%x\n",
+		       irq_src);
+	}
+
+	return handled;
+}
+
+/*
+ * Initializes timer using galileo's built in timer.
+ */
+
+/*
+ * This will ignore the standard MIPS timer interrupt handler
+ * that is passed in as *irq (=irq0 in ../kernel/time.c).
+ * We will do our own timer interrupt handling.
+ */
+void gt64240_time_init(void)
+{
+	static struct irqaction timer;
+
+	/* Stop the timer -- we'll use timer #0 */
+	MV_WRITE(TIMER_COUNTER_0_3_CONTROL, 0x0);
+
+	/* Load timer value for 100 Hz */
+	MV_WRITE(TIMER_COUNTER0, bus_clock / 100);
+
+	/*
+	 * Create the IRQ structure entry for the timer.  Since we're too early
+	 * in the boot process to use the "request_irq()" call, we'll hard-code
+	 * the values to the correct interrupt line.
+	 */
+	timer.handler = &gt64240_p0int_irq;
+	timer.flags = SA_SHIRQ | SA_INTERRUPT;
+	timer.name = "timer";
+	timer.dev_id = NULL;
+	timer.next = NULL;
+	timer.mask = 0;
+	irq_desc[6].action = &timer;
+
+	enable_irq(6);
+
+	/* Clear any pending cause bits */
+	MV_WRITE(TIMER_COUNTER_0_3_INTERRUPT_CAUSE, 0x0);
+
+	/* Enable the interrupt for timer 0 */
+	MV_WRITE(TIMER_COUNTER_0_3_INTERRUPT_MASK, 0x1);
+
+	/* Enable the timer interrupt for GT-64240 pin P0_INT# */
+	MV_WRITE (PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW, 0x100);
+
+	/* Configure and start the timer */
+	MV_WRITE(TIMER_COUNTER_0_3_CONTROL, 0x3);
+}
+
+void gt64240_irq_init(void)
+{
+#if CURRENTLY_UNUSED
+	int i, j;
+
+	/* Reset irq handlers pointers to NULL */
+	for (i = 0; i < MAX_CAUSE_REGS; i++) {
+		for (j = 0; j < MAX_CAUSE_REG_WIDTH; j++) {
+			irq_handlers[i][j].next = NULL;
+			irq_handlers[i][j].sync = 0;
+			irq_handlers[i][j].routine = NULL;
+			irq_handlers[i][j].data = NULL;
+		}
+	}
+#endif
+}
diff --git a/arch/mips/momentum/ocelot_g/int-handler.S b/arch/mips/momentum/ocelot_g/int-handler.S
new file mode 100644
index 0000000..772e8f7
--- /dev/null
+++ b/arch/mips/momentum/ocelot_g/int-handler.S
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * First-level interrupt dispatcher for ocelot board.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/*
+ * first level interrupt dispatcher for ocelot board -
+ * We check for the timer first, then check PCI ints A and D.
+ * Then check for serial IRQ and fall through.
+ */
+		.align	5
+		NESTED(ocelot_handle_int, PT_SIZE, sp)
+		SAVE_ALL
+		CLI
+		.set	at
+		mfc0	t0, CP0_CAUSE
+		mfc0	t2, CP0_STATUS
+
+		and	t0, t2
+
+		 andi	t1, t0, STATUSF_IP2	/* int0 hardware line */
+		bnez	t1, ll_pri_enet_irq
+		 andi	t1, t0, STATUSF_IP3	/* int1 hardware line */
+		bnez	t1, ll_sec_enet_irq
+		 andi	t1, t0, STATUSF_IP4	/* int2 hardware line */
+		bnez	t1, ll_uart_irq
+		 andi	t1, t0, STATUSF_IP5	/* int3 hardware line */
+		bnez	t1, ll_cpci_irq
+		 andi	t1, t0, STATUSF_IP6	/* int4 hardware line */
+		bnez	t1, ll_galileo_p0_irq
+		 andi	t1, t0, STATUSF_IP7	/* cpu timer */
+		bnez	t1, ll_cputimer_irq
+
+                /* now look at the extended interrupts */
+		mfc0	t0, CP0_CAUSE
+		cfc0	t1, CP0_S1_INTCONTROL
+
+		/* shift the mask 8 bits left to line up the bits */
+		 sll	t2, t1, 8
+
+		 and	t0, t2
+		 srl	t0, t0, 16
+
+		 andi	t1, t0, STATUSF_IP8	/* int6 hardware line */
+		bnez	t1, ll_galileo_p1_irq
+		 andi	t1, t0, STATUSF_IP9	/* int7 hardware line */
+		bnez	t1, ll_pmc_irq
+		 andi	t1, t0, STATUSF_IP10	/* int8 hardware line */
+		bnez	t1, ll_cpci_abcd_irq
+		 andi	t1, t0, STATUSF_IP11	/* int9 hardware line */
+		bnez	t1, ll_testpoint_irq
+
+		.set	reorder
+
+		/* wrong alarm or masked ... */
+		j	spurious_interrupt
+		nop
+		END(ocelot_handle_int)
+
+		.align	5
+ll_pri_enet_irq:
+		li	a0, 2
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_sec_enet_irq:
+		li	a0, 3
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_uart_irq:
+		li	a0, 4
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_cpci_irq:
+		li	a0, 5
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_galileo_p0_irq:
+		li	a0, 6
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_cputimer_irq:
+		li	a0, 7
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_galileo_p1_irq:
+		li	a0, 8
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_pmc_irq:
+		li	a0, 9
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_cpci_abcd_irq:
+		li	a0, 10
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_testpoint_irq:
+		li	a0, 11
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
diff --git a/arch/mips/momentum/ocelot_g/irq.c b/arch/mips/momentum/ocelot_g/irq.c
new file mode 100644
index 0000000..5eb85b1
--- /dev/null
+++ b/arch/mips/momentum/ocelot_g/irq.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: RidgeRun, Inc.
+ *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ * Copyright (C) 2000, 01, 05 Ralf Baechle (ralf@linux-mips.org)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+extern asmlinkage void ocelot_handle_int(void);
+extern void gt64240_irq_init(void);
+
+void __init arch_init_irq(void)
+{
+	/*
+	 * Clear all of the interrupts while we change the able around a bit.
+	 * int-handler is not on bootstrap
+	 */
+	clear_c0_status(ST0_IM);
+	local_irq_disable();
+
+	/* Sets the first-level interrupt dispatcher. */
+	set_except_vector(0, ocelot_handle_int);
+	mips_cpu_irq_init(0);
+	rm7k_cpu_irq_init(8);
+
+	gt64240_irq_init();
+}
diff --git a/arch/mips/momentum/ocelot_g/ocelot_pld.h b/arch/mips/momentum/ocelot_g/ocelot_pld.h
new file mode 100644
index 0000000..fcb8275
--- /dev/null
+++ b/arch/mips/momentum/ocelot_g/ocelot_pld.h
@@ -0,0 +1,30 @@
+/*
+ * Ocelot Board Register Definitions
+ *
+ * (C) 2001 Red Hat, Inc.
+ *
+ * GPL'd
+ */
+#ifndef __MOMENCO_OCELOT_PLD_H__
+#define __MOMENCO_OCELOT_PLD_H__
+
+#define OCELOT_CS0_ADDR (0xfc000000)
+
+#define OCELOT_REG_BOARDREV (0)
+#define OCELOT_REG_PLD1_ID (1)
+#define OCELOT_REG_PLD2_ID (2)
+#define OCELOT_REG_RESET_STATUS (3)
+#define OCELOT_REG_BOARD_STATUS (4)
+#define OCELOT_REG_CPCI_ID (5)
+#define OCELOT_REG_I2C_CTRL (8)
+#define OCELOT_REG_EEPROM_MODE (9)
+#define OCELOT_REG_INTMASK (10)
+#define OCELOT_REG_INTSTATUS (11)
+#define OCELOT_REG_INTSET (12)
+#define OCELOT_REG_INTCLR (13)
+
+#define OCELOT_PLD_WRITE(x, y) writeb(x, OCELOT_CS0_ADDR + OCELOT_REG_##y)
+#define OCELOT_PLD_READ(x) readb(OCELOT_CS0_ADDR + OCELOT_REG_##x)
+
+
+#endif /* __MOMENCO_OCELOT_PLD_H__ */
diff --git a/arch/mips/momentum/ocelot_g/prom.c b/arch/mips/momentum/ocelot_g/prom.c
new file mode 100644
index 0000000..6b4f577
--- /dev/null
+++ b/arch/mips/momentum/ocelot_g/prom.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2002 Momentum Computer Inc.
+ * Author: Matthew Dharm <mdharm@momenco.com>
+ *
+ * Based on Ocelot Linux port, which is
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/pmon.h>
+#include <asm/gt64240.h>
+
+#include "ocelot_pld.h"
+
+struct callvectors* debug_vectors;
+
+extern unsigned long marvell_base;
+extern unsigned long bus_clock;
+
+#ifdef CONFIG_GALILLEO_GT64240_ETH
+extern unsigned char prom_mac_addr_base[6];
+#endif
+
+const char *get_system_type(void)
+{
+	return "Momentum Ocelot";
+}
+
+void __init prom_init(void)
+{
+	int argc = fw_arg0;
+	char **arg = (char **) fw_arg1;
+	char **env = (char **) fw_arg2;
+	struct callvectors *cv = (struct callvectors *) fw_arg3;
+	int i;
+
+	/* save the PROM vectors for debugging use */
+	debug_vectors = cv;
+
+	/* arg[0] is "g", the rest is boot parameters */
+	arcs_cmdline[0] = '\0';
+	for (i = 1; i < argc; i++) {
+		if (strlen(arcs_cmdline) + strlen(arg[i] + 1)
+		    >= sizeof(arcs_cmdline))
+			break;
+		strcat(arcs_cmdline, arg[i]);
+		strcat(arcs_cmdline, " ");
+	}
+
+	mips_machgroup = MACH_GROUP_MOMENCO;
+	mips_machtype = MACH_MOMENCO_OCELOT_G;
+
+#ifdef CONFIG_GALILLEO_GT64240_ETH
+	/* get the base MAC address for on-board ethernet ports */
+	memcpy(prom_mac_addr_base, (void*)0xfc807cf2, 6);
+#endif
+
+	while (*env) {
+		if (strncmp("gtbase", *env, strlen("gtbase")) == 0) {
+			marvell_base = simple_strtol(*env + strlen("gtbase="),
+							NULL, 16);
+		}
+		if (strncmp("busclock", *env, strlen("busclock")) == 0) {
+			bus_clock = simple_strtol(*env + strlen("busclock="),
+							NULL, 10);
+		}
+		env++;
+	}
+}
+
+unsigned long __init prom_free_prom_memory(void)
+{
+	return 0;
+}
diff --git a/arch/mips/momentum/ocelot_g/reset.c b/arch/mips/momentum/ocelot_g/reset.c
new file mode 100644
index 0000000..3fd499a
--- /dev/null
+++ b/arch/mips/momentum/ocelot_g/reset.c
@@ -0,0 +1,47 @@
+/*
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Copyright (C) 1997, 2001 Ralf Baechle
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <linux/delay.h>
+
+void momenco_ocelot_restart(char *command)
+{
+	void *nvram = ioremap_nocache(0x2c807000, 0x1000);
+
+	if (!nvram) {
+		printk(KERN_NOTICE "ioremap of reset register failed\n");
+		return;
+	}
+	writeb(0x84, nvram + 0xff7); /* Ask the NVRAM/RTC/watchdog chip to
+					assert reset in 1/16 second */
+	mdelay(10+(1000/16));
+	iounmap(nvram);
+	printk(KERN_NOTICE "Watchdog reset failed\n");
+}
+
+void momenco_ocelot_halt(void)
+{
+	printk(KERN_NOTICE "\n** You can safely turn off the power\n");
+	while (1)
+		__asm__(".set\tmips3\n\t"
+	                "wait\n\t"
+			".set\tmips0");
+}
+
+void momenco_ocelot_power_off(void)
+{
+	momenco_ocelot_halt();
+}
diff --git a/arch/mips/momentum/ocelot_g/setup.c b/arch/mips/momentum/ocelot_g/setup.c
new file mode 100644
index 0000000..38a78ab
--- /dev/null
+++ b/arch/mips/momentum/ocelot_g/setup.c
@@ -0,0 +1,266 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ * Momentum Computer Ocelot-G (CP7000G) - board dependent boot routines
+ *
+ * Copyright (C) 1996, 1997, 2001  Ralf Baechle
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Copyright (C) 2001 Red Hat, Inc.
+ * Copyright (C) 2002 Momentum Computer
+ *
+ * Author: Matthew Dharm, Momentum Computer
+ *   mdharm@momenco.com
+ *
+ * Author: RidgeRun, Inc.
+ *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/timex.h>
+#include <linux/vmalloc.h>
+#include <asm/time.h>
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/gt64240.h>
+#include <asm/irq.h>
+#include <asm/pci.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/reboot.h>
+#include <linux/bootmem.h>
+
+#include "ocelot_pld.h"
+
+#ifdef CONFIG_GALILLEO_GT64240_ETH
+extern unsigned char prom_mac_addr_base[6];
+#endif
+
+unsigned long marvell_base;
+
+/* These functions are used for rebooting or halting the machine*/
+extern void momenco_ocelot_restart(char *command);
+extern void momenco_ocelot_halt(void);
+extern void momenco_ocelot_power_off(void);
+
+extern void gt64240_time_init(void);
+extern void momenco_ocelot_irq_setup(void);
+
+static char reset_reason;
+
+static unsigned long ENTRYLO(unsigned long paddr)
+{
+	return ((paddr & PAGE_MASK) |
+	       (_PAGE_PRESENT | __READABLE | __WRITEABLE | _PAGE_GLOBAL |
+		_CACHE_UNCACHED)) >> 6;
+}
+
+/* setup code for a handoff from a version 2 PMON 2000 PROM */
+void PMON_v2_setup(void)
+{
+	/* A wired TLB entry for the GT64240 and the serial port. The
+	   GT64240 is going to be hit on every IRQ anyway - there's
+	   absolutely no point in letting it be a random TLB entry, as
+	   it'll just cause needless churning of the TLB. And we use
+	   the other half for the serial port, which is just a PITA
+	   otherwise :)
+
+		Device			Physical	Virtual
+		GT64240 Internal Regs	0xf4000000	0xe0000000
+		UARTs (CS2)		0xfd000000	0xe0001000
+	*/
+	add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000),
+	                0xf4000000, PM_64K);
+	add_wired_entry(ENTRYLO(0xfd000000), ENTRYLO(0xfd001000),
+	                0xfd000000, PM_4K);
+
+	/* Also a temporary entry to let us talk to the Ocelot PLD and NVRAM
+	   in the CS[012] region. We can't use ioremap() yet. The NVRAM
+	   is a ST M48T37Y, which includes NVRAM, RTC, and Watchdog functions.
+
+		Ocelot PLD (CS0)	0xfc000000	0xe0020000
+		NVRAM (CS1)		0xfc800000	0xe0030000
+	*/
+	add_temporary_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfc010000),
+	                    0xfc000000, PM_64K);
+	add_temporary_entry(ENTRYLO(0xfc800000), ENTRYLO(0xfc810000),
+	                    0xfc800000, PM_64K);
+
+	marvell_base = 0xf4000000;
+}
+
+extern int rm7k_tcache_enabled;
+
+/*
+ * This runs in KSEG1. See the verbiage in rm7k.c::probe_scache()
+ */
+#define Page_Invalidate_T 0x16
+static void __init setup_l3cache(unsigned long size)
+{
+	int register i;
+
+	printk("Enabling L3 cache...");
+
+	/* Enable the L3 cache in the GT64120A's CPU Configuration register */
+	MV_WRITE(0, MV_READ(0) | (1<<14));
+
+	/* Enable the L3 cache in the CPU */
+	set_c0_config(1<<12 /* CONF_TE */);
+
+	/* Clear the cache */
+	write_c0_taglo(0);
+	write_c0_taghi(0);
+
+	for (i=0; i < size; i+= 4096) {
+		__asm__ __volatile__ (
+			".set noreorder\n\t"
+			".set mips3\n\t"
+			"cache %1, (%0)\n\t"
+			".set mips0\n\t"
+			".set reorder"
+			:
+			: "r" (KSEG0ADDR(i)),
+			  "i" (Page_Invalidate_T));
+	}
+
+	/* Let the RM7000 MM code know that the tertiary cache is enabled */
+	rm7k_tcache_enabled = 1;
+
+	printk("Done\n");
+}
+
+static int  __init momenco_ocelot_g_setup(void)
+{
+	void (*l3func)(unsigned long) = (void *) KSEG1ADDR(setup_l3cache);
+	unsigned int tmpword;
+
+	board_time_init = gt64240_time_init;
+
+	_machine_restart = momenco_ocelot_restart;
+	_machine_halt = momenco_ocelot_halt;
+	_machine_power_off = momenco_ocelot_power_off;
+
+	/*
+	 * initrd_start = (ulong)ocelot_initrd_start;
+	 * initrd_end = (ulong)ocelot_initrd_start + (ulong)ocelot_initrd_size;
+	 * initrd_below_start_ok = 1;
+	 */
+
+	/* do handoff reconfiguration */
+	PMON_v2_setup();
+
+#ifdef CONFIG_GALILLEO_GT64240_ETH
+	/* get the mac addr */
+	memcpy(prom_mac_addr_base, (void*)0xfc807cf2, 6);
+#endif
+
+	/* Turn off the Bit-Error LED */
+	OCELOT_PLD_WRITE(0x80, INTCLR);
+
+	tmpword = OCELOT_PLD_READ(BOARDREV);
+	if (tmpword < 26)
+		printk("Momenco Ocelot-G: Board Assembly Rev. %c\n", 'A'+tmpword);
+	else
+		printk("Momenco Ocelot-G: Board Assembly Revision #0x%x\n", tmpword);
+
+	tmpword = OCELOT_PLD_READ(PLD1_ID);
+	printk("PLD 1 ID: %d.%d\n", tmpword>>4, tmpword&15);
+	tmpword = OCELOT_PLD_READ(PLD2_ID);
+	printk("PLD 2 ID: %d.%d\n", tmpword>>4, tmpword&15);
+	tmpword = OCELOT_PLD_READ(RESET_STATUS);
+	printk("Reset reason: 0x%x\n", tmpword);
+	reset_reason = tmpword;
+	OCELOT_PLD_WRITE(0xff, RESET_STATUS);
+
+	tmpword = OCELOT_PLD_READ(BOARD_STATUS);
+	printk("Board Status register: 0x%02x\n", tmpword);
+	printk("  - User jumper: %s\n", (tmpword & 0x80)?"installed":"absent");
+	printk("  - Boot flash write jumper: %s\n", (tmpword&0x40)?"installed":"absent");
+	printk("  - Tulip PHY %s connected\n", (tmpword&0x10)?"is":"not");
+	printk("  - L3 Cache size: %d MiB\n", (1<<((tmpword&12) >> 2))&~1);
+	printk("  - SDRAM size: %d MiB\n", 1<<(6+(tmpword&3)));
+
+	if (tmpword&12)
+		l3func((1<<(((tmpword&12) >> 2)+20)));
+
+	switch(tmpword &3) {
+	case 3:
+		/* 512MiB -- two banks of 256MiB */
+		add_memory_region(  0x0<<20, 0x100<<20, BOOT_MEM_RAM);
+/*
+		add_memory_region(0x100<<20, 0x100<<20, BOOT_MEM_RAM);
+*/
+		break;
+	case 2:
+		/* 256MiB -- two banks of 128MiB */
+		add_memory_region( 0x0<<20, 0x80<<20, BOOT_MEM_RAM);
+		add_memory_region(0x80<<20, 0x80<<20, BOOT_MEM_RAM);
+		break;
+	case 1:
+		/* 128MiB -- 64MiB per bank */
+		add_memory_region( 0x0<<20, 0x40<<20, BOOT_MEM_RAM);
+		add_memory_region(0x40<<20, 0x40<<20, BOOT_MEM_RAM);
+		break;
+	case 0:
+		/* 64MiB */
+		add_memory_region( 0x0<<20, 0x40<<20, BOOT_MEM_RAM);
+		break;
+	}
+
+	/* FIXME: Fix up the DiskOnChip mapping */
+	MV_WRITE(0x468, 0xfef73);
+
+	return 0;
+}
+
+early_initcall(momenco_ocelot_g_setup);
+
+/* This needs to be one of the first initcalls, because no I/O port access
+   can work before this */
+
+static int io_base_ioremap(void)
+{
+	/* we're mapping PCI accesses from 0xc0000000 to 0xf0000000 */
+	unsigned long io_remap_range;
+
+	io_remap_range = (unsigned long) ioremap(0xc0000000, 0x30000000);
+	if (!io_remap_range)
+		panic("Could not ioremap I/O port range");
+
+	set_io_port_base(io_remap_range - 0xc0000000);
+
+	return 0;
+}
+
+module_init(io_base_ioremap);
diff --git a/arch/mips/oprofile/Kconfig b/arch/mips/oprofile/Kconfig
new file mode 100644
index 0000000..19d3773
--- /dev/null
+++ b/arch/mips/oprofile/Kconfig
@@ -0,0 +1,23 @@
+
+menu "Profiling support"
+	depends on EXPERIMENTAL
+
+config PROFILING
+	bool "Profiling support (EXPERIMENTAL)"
+	help
+	  Say Y here to enable the extended profiling support mechanisms used
+	  by profilers such as OProfile.
+
+
+config OPROFILE
+	tristate "OProfile system profiling (EXPERIMENTAL)"
+	depends on PROFILING
+	help
+	  OProfile is a profiling system capable of profiling the
+	  whole system, include the kernel, kernel modules, libraries,
+	  and applications.
+
+	  If unsure, say N.
+
+endmenu
+
diff --git a/arch/mips/oprofile/Makefile b/arch/mips/oprofile/Makefile
new file mode 100644
index 0000000..354261d
--- /dev/null
+++ b/arch/mips/oprofile/Makefile
@@ -0,0 +1,15 @@
+EXTRA_CFLAGS := -Werror
+
+obj-$(CONFIG_OPROFILE) += oprofile.o
+
+DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
+		oprof.o cpu_buffer.o buffer_sync.o \
+		event_buffer.o oprofile_files.o \
+		oprofilefs.o oprofile_stats.o \
+		timer_int.o )
+
+oprofile-y				:= $(DRIVER_OBJS) common.o
+
+oprofile-$(CONFIG_CPU_MIPS32)		+= op_model_mipsxx.o
+oprofile-$(CONFIG_CPU_MIPS64)		+= op_model_mipsxx.o
+oprofile-$(CONFIG_CPU_RM9000)		+= op_model_rm9000.o
diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c
new file mode 100644
index 0000000..ab65ce3
--- /dev/null
+++ b/arch/mips/oprofile/common.c
@@ -0,0 +1,106 @@
+/*
+ * 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) 2004 by Ralf Baechle
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/oprofile.h>
+#include <linux/smp.h>
+#include <asm/cpu-info.h>
+
+#include "op_impl.h"
+
+extern struct op_mips_model op_model_mipsxx __attribute__((weak));
+extern struct op_mips_model op_model_rm9000 __attribute__((weak));
+
+static struct op_mips_model *model;
+
+static struct op_counter_config ctr[20];
+
+static int op_mips_setup(void)
+{
+	/* Pre-compute the values to stuff in the hardware registers.  */
+	model->reg_setup(ctr);
+
+	/* Configure the registers on all cpus.  */
+	on_each_cpu(model->cpu_setup, 0, 0, 1);
+
+        return 0;
+}
+
+static int op_mips_create_files(struct super_block * sb, struct dentry * root)
+{
+	int i;
+
+	for (i = 0; i < model->num_counters; ++i) {
+		struct dentry *dir;
+		char buf[3];
+
+		snprintf(buf, sizeof buf, "%d", i);
+		dir = oprofilefs_mkdir(sb, root, buf);
+
+		oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
+		oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
+		oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
+		/* Dummies.  */
+		oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
+		oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
+		oprofilefs_create_ulong(sb, dir, "exl", &ctr[i].exl);
+		oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
+	}
+
+	return 0;
+}
+
+static int op_mips_start(void)
+{
+	on_each_cpu(model->cpu_start, NULL, 0, 1);
+
+	return 0;
+}
+
+static void op_mips_stop(void)
+{
+	/* Disable performance monitoring for all counters.  */
+	on_each_cpu(model->cpu_stop, NULL, 0, 1);
+}
+
+void __init oprofile_arch_init(struct oprofile_operations *ops)
+{
+	struct op_mips_model *lmodel = NULL;
+
+	switch (current_cpu_data.cputype) {
+	case CPU_24K:
+		lmodel = &op_model_mipsxx;
+		break;
+
+	case CPU_RM9000:
+		lmodel = &op_model_rm9000;
+		break;
+	};
+
+	if (!lmodel)
+		return;
+
+	if (lmodel->init())
+		return;
+
+	model = lmodel;
+
+	ops->create_files = op_mips_create_files;
+	ops->setup = op_mips_setup;
+	ops->start = op_mips_start;
+	ops->stop = op_mips_stop;
+	ops->cpu_type = lmodel->cpu_type;
+
+	printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
+	       lmodel->cpu_type);
+}
+
+void oprofile_arch_exit(void)
+{
+	model->exit();
+}
diff --git a/arch/mips/oprofile/op_impl.h b/arch/mips/oprofile/op_impl.h
new file mode 100644
index 0000000..9f5cdff
--- /dev/null
+++ b/arch/mips/oprofile/op_impl.h
@@ -0,0 +1,37 @@
+/**
+ * @file arch/alpha/oprofile/op_impl.h
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author Richard Henderson <rth@twiddle.net>
+ */
+
+#ifndef OP_IMPL_H
+#define OP_IMPL_H 1
+
+/* Per-counter configuration as set via oprofilefs.  */
+struct op_counter_config {
+	unsigned long enabled;
+	unsigned long event;
+	unsigned long count;
+	/* Dummies because I am too lazy to hack the userspace tools.  */
+	unsigned long kernel;
+	unsigned long user;
+	unsigned long exl;
+	unsigned long unit_mask;
+};
+
+/* Per-architecture configury and hooks.  */
+struct op_mips_model {
+	void (*reg_setup) (struct op_counter_config *);
+	void (*cpu_setup) (void * dummy);
+	int (*init)(void);
+	void (*exit)(void);
+	void (*cpu_start)(void *args);
+	void (*cpu_stop)(void *args);
+	char *cpu_type;
+	unsigned char num_counters;
+};
+
+#endif
diff --git a/arch/mips/oprofile/op_model_rm9000.c b/arch/mips/oprofile/op_model_rm9000.c
new file mode 100644
index 0000000..bee4779
--- /dev/null
+++ b/arch/mips/oprofile/op_model_rm9000.c
@@ -0,0 +1,137 @@
+/*
+ * 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) 2004 by Ralf Baechle
+ */
+#include <linux/oprofile.h>
+#include <linux/interrupt.h>
+#include <linux/smp.h>
+
+#include "op_impl.h"
+
+#define RM9K_COUNTER1_EVENT(event)	((event) << 0)
+#define RM9K_COUNTER1_SUPERVISOR	(1ULL    <<  7)
+#define RM9K_COUNTER1_KERNEL		(1ULL    <<  8)
+#define RM9K_COUNTER1_USER		(1ULL    <<  9)
+#define RM9K_COUNTER1_ENABLE		(1ULL    << 10)
+#define RM9K_COUNTER1_OVERFLOW		(1ULL    << 15)
+
+#define RM9K_COUNTER2_EVENT(event)	((event) << 16)
+#define RM9K_COUNTER2_SUPERVISOR	(1ULL    << 23)
+#define RM9K_COUNTER2_KERNEL		(1ULL    << 24)
+#define RM9K_COUNTER2_USER		(1ULL    << 25)
+#define RM9K_COUNTER2_ENABLE		(1ULL    << 26)
+#define RM9K_COUNTER2_OVERFLOW		(1ULL    << 31)
+
+extern unsigned int rm9000_perfcount_irq;
+
+static struct rm9k_register_config {
+	unsigned int control;
+	unsigned int reset_counter1;
+	unsigned int reset_counter2;
+} reg;
+
+/* Compute all of the registers in preparation for enabling profiling.  */
+
+static void rm9000_reg_setup(struct op_counter_config *ctr)
+{
+	unsigned int control = 0;
+
+	/* Compute the performance counter control word.  */
+	/* For now count kernel and user mode */
+	if (ctr[0].enabled)
+		control |= RM9K_COUNTER1_EVENT(ctr[0].event) |
+		           RM9K_COUNTER1_KERNEL |
+		           RM9K_COUNTER1_USER |
+		           RM9K_COUNTER1_ENABLE;
+	if (ctr[1].enabled)
+		control |= RM9K_COUNTER2_EVENT(ctr[1].event) |
+		           RM9K_COUNTER2_KERNEL |
+		           RM9K_COUNTER2_USER |
+		           RM9K_COUNTER2_ENABLE;
+	reg.control = control;
+
+	reg.reset_counter1 = 0x80000000 - ctr[0].count;
+	reg.reset_counter2 = 0x80000000 - ctr[1].count;
+}
+
+/* Program all of the registers in preparation for enabling profiling.  */
+
+static void rm9000_cpu_setup (void *args)
+{
+	uint64_t perfcount;
+
+	perfcount = ((uint64_t) reg.reset_counter2 << 32) | reg.reset_counter1;
+	write_c0_perfcount(perfcount);
+}
+
+static void rm9000_cpu_start(void *args)
+{
+	/* Start all counters on current CPU */
+	write_c0_perfcontrol(reg.control);
+}
+
+static void rm9000_cpu_stop(void *args)
+{
+	/* Stop all counters on current CPU */
+	write_c0_perfcontrol(0);
+}
+
+static irqreturn_t rm9000_perfcount_handler(int irq, void * dev_id,
+	struct pt_regs *regs)
+{
+	unsigned int control = read_c0_perfcontrol();
+	uint32_t counter1, counter2;
+	uint64_t counters;
+
+	/*
+	 * RM9000 combines two 32-bit performance counters into a single
+	 * 64-bit coprocessor zero register.  To avoid a race updating the
+	 * registers we need to stop the counters while we're messing with
+	 * them ...
+	 */
+	write_c0_perfcontrol(0);
+
+	counters = read_c0_perfcount();
+	counter1 = counters;
+	counter2 = counters >> 32;
+
+	if (control & RM9K_COUNTER1_OVERFLOW) {
+		oprofile_add_sample(regs, 0);
+		counter1 = reg.reset_counter1;
+	}
+	if (control & RM9K_COUNTER2_OVERFLOW) {
+		oprofile_add_sample(regs, 1);
+		counter2 = reg.reset_counter2;
+	}
+
+	counters = ((uint64_t)counter2 << 32) | counter1;
+	write_c0_perfcount(counters);
+	write_c0_perfcontrol(reg.control);
+
+	return IRQ_HANDLED;
+}
+
+static int rm9000_init(void)
+{
+	return request_irq(rm9000_perfcount_irq, rm9000_perfcount_handler,
+	                   0, "Perfcounter", NULL);
+}
+
+static void rm9000_exit(void)
+{
+	free_irq(rm9000_perfcount_irq, NULL);
+}
+
+struct op_mips_model op_model_rm9000 = {
+	.reg_setup	= rm9000_reg_setup,
+	.cpu_setup	= rm9000_cpu_setup,
+	.init		= rm9000_init,
+	.exit		= rm9000_exit,
+	.cpu_start	= rm9000_cpu_start,
+	.cpu_stop	= rm9000_cpu_stop,
+	.cpu_type	= "mips/rm9000",
+	.num_counters	= 2
+};
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
new file mode 100644
index 0000000..c53e4cb
--- /dev/null
+++ b/arch/mips/pci/Makefile
@@ -0,0 +1,54 @@
+#
+# Makefile for the PCI specific kernel interface routines under Linux.
+#
+
+obj-y				+= pci.o
+
+#
+# PCI bus host bridge specific code
+#
+obj-$(CONFIG_ITE_BOARD_GEN)	+= ops-it8172.o
+obj-$(CONFIG_MIPS_BONITO64)	+= ops-bonito64.o
+obj-$(CONFIG_MIPS_GT64111)	+= ops-gt64111.o
+obj-$(CONFIG_MIPS_GT64120)	+= ops-gt64120.o
+obj-$(CONFIG_MIPS_GT96100)	+= ops-gt96100.o
+obj-$(CONFIG_PCI_MARVELL)	+= ops-marvell.o
+obj-$(CONFIG_MIPS_MSC)		+= ops-msc.o
+obj-$(CONFIG_MIPS_NILE4)	+= ops-nile4.o
+obj-$(CONFIG_MIPS_TX3927)	+= ops-jmr3927.o
+obj-$(CONFIG_PCI_VR41XX)	+= ops-vr41xx.o pci-vr41xx.o
+obj-$(CONFIG_NEC_CMBVR4133)	+= fixup-vr4133.o
+
+#
+# These are still pretty much in the old state, watch, go blind.
+#
+obj-$(CONFIG_DDB5074)		+= fixup-ddb5074.o pci-ddb5074.o ops-ddb5074.o
+obj-$(CONFIG_DDB5476)		+= ops-ddb5476.o pci-ddb5476.o
+obj-$(CONFIG_DDB5477)		+= fixup-ddb5477.o pci-ddb5477.o ops-ddb5477.o
+obj-$(CONFIG_LASAT)		+= pci-lasat.o
+obj-$(CONFIG_MIPS_ATLAS)	+= fixup-atlas.o
+obj-$(CONFIG_MIPS_COBALT)	+= fixup-cobalt.o
+obj-$(CONFIG_MIPS_EV96100)	+= fixup-ev64120.o
+obj-$(CONFIG_MIPS_EV96100)	+= fixup-ev96100.o pci-ev96100.o
+obj-$(CONFIG_MIPS_ITE8172)	+= fixup-ite8172g.o
+obj-$(CONFIG_MIPS_IVR)		+= fixup-ivr.o
+obj-$(CONFIG_SOC_AU1500)	+= fixup-au1000.o ops-au1000.o
+obj-$(CONFIG_SOC_AU1550)	+= fixup-au1000.o ops-au1000.o
+obj-$(CONFIG_MIPS_MALTA)	+= fixup-malta.o
+obj-$(CONFIG_MOMENCO_JAGUAR_ATX)+= fixup-jaguar.o
+obj-$(CONFIG_MOMENCO_OCELOT)	+= fixup-ocelot.o pci-ocelot.o
+obj-$(CONFIG_MOMENCO_OCELOT_3)	+= fixup-ocelot3.o
+obj-$(CONFIG_MOMENCO_OCELOT_C)	+= fixup-ocelot-c.o pci-ocelot-c.o
+obj-$(CONFIG_MOMENCO_OCELOT_G)	+= fixup-ocelot-g.o pci-ocelot-g.o
+obj-$(CONFIG_PMC_YOSEMITE)	+= fixup-yosemite.o ops-titan.o ops-titan-ht.o \
+				   pci-yosemite.o
+obj-$(CONFIG_SGI_IP27)		+= pci-ip27.o
+obj-$(CONFIG_SGI_IP32)		+= fixup-ip32.o ops-mace.o pci-ip32.o
+obj-$(CONFIG_SIBYTE_SB1250)	+= fixup-sb1250.o pci-sb1250.o
+obj-$(CONFIG_SNI_RM200_PCI)	+= fixup-sni.o ops-sni.o
+obj-$(CONFIG_TANBAC_TB0219)	+= fixup-tb0219.o
+obj-$(CONFIG_TANBAC_TB0226)	+= fixup-tb0226.o
+obj-$(CONFIG_TOSHIBA_JMR3927)	+= fixup-jmr3927.o pci-jmr3927.o
+obj-$(CONFIG_TOSHIBA_RBTX4927)	+= fixup-rbtx4927.o ops-tx4927.o
+obj-$(CONFIG_VICTOR_MPC30X)	+= fixup-mpc30x.o
+obj-$(CONFIG_ZAO_CAPCELLA)	+= fixup-capcella.o
diff --git a/arch/mips/pci/fixup-atlas.c b/arch/mips/pci/fixup-atlas.c
new file mode 100644
index 0000000..2406835
--- /dev/null
+++ b/arch/mips/pci/fixup-atlas.c
@@ -0,0 +1,69 @@
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <asm/mips-boards/atlasint.h>
+
+#define INTD		ATLASINT_INTD
+#define INTC		ATLASINT_INTC
+#define INTB		ATLASINT_INTB
+#define INTA		ATLASINT_INTA
+#define SCSI		ATLASINT_SCSI
+#define ETH		ATLASINT_ETH
+
+static char irq_tab[][5] __initdata = {
+	/*      INTA    INTB    INTC    INTD */
+	{0,	0,	0,	0,	0 },	/*  0: Unused */
+	{0,	0,	0,	0,	0 },	/*  1: Unused */
+	{0,	0,	0,	0,	0 },	/*  2: Unused */
+	{0,	0,	0,	0,	0 },	/*  3: Unused */
+	{0,	0,	0,	0,	0 },	/*  4: Unused */
+	{0,	0,	0,	0,	0 },	/*  5: Unused */
+	{0,	0,	0,	0,	0 },	/*  6: Unused */
+	{0,	0,	0,	0,	0 },	/*  7: Unused */
+	{0,	0,	0,	0,	0 },	/*  8: Unused */
+	{0,	0,	0,	0,	0 },	/*  9: Unused */
+	{0,	0,	0,	0,	0 },	/* 10: Unused */
+	{0,	0,	0,	0,	0 },	/* 11: Unused */
+	{0,	0,	0,	0,	0 },	/* 12: Unused */
+	{0,	0,	0,	0,	0 },	/* 13: Unused */
+	{0,	0,	0,	0,	0 },	/* 14: Unused */
+	{0,	0,	0,	0,	0 },	/* 15: Unused */
+	{0,	SCSI,	0,	0,	0 },	/* 16: SYM53C810A SCSI */
+	{0,	0,	0,	0,	0 },	/* 17: Core */
+	{0,	INTA,	INTB,	INTC,	INTD },	/* 18: PCI Slot 1 */
+	{0,	ETH,	0,	0,	0 },	/* 19: SAA9730 Ethernet */
+	{0,	0,	0,	0,	0 },	/* 20: PCI Slot 3 */
+	{0,	0,	0,	0,	0 }	/* 21: PCI Slot 4 */
+};
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	return irq_tab[slot][pin];
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
+
+#ifdef CONFIG_KGDB
+/*
+ * The PCI scan may have moved the saa9730 I/O address, so reread
+ * the address here.
+ * This does mean that it's not possible to debug the PCI bus configuration
+ * code, but it is better than nothing...
+ */
+
+static void atlas_saa9730_base_fixup (struct pci_dev *pdev)
+{
+	extern void *saa9730_base;
+	if (pdev->bus == 0 && PCI_SLOT(pdev->devfn) == 19)
+		(void) pci_read_config_dword (pdev, 0x14, (u32 *)&saa9730_base);
+	printk ("saa9730_base = %x\n", saa9730_base);
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA9730,
+	 atlas_saa9730_base_fixup);
+
+#endif
diff --git a/arch/mips/pci/fixup-au1000.c b/arch/mips/pci/fixup-au1000.c
new file mode 100644
index 0000000..39fe2b1
--- /dev/null
+++ b/arch/mips/pci/fixup-au1000.c
@@ -0,0 +1,123 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Board specific pci fixups.
+ *
+ * Copyright 2001-2003 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/mach-au1x00/au1000.h>
+
+/*
+ * Shortcut
+ */
+#ifdef CONFIG_SOC_AU1500
+#define INTA AU1000_PCI_INTA
+#define INTB AU1000_PCI_INTB
+#define INTC AU1000_PCI_INTC
+#define INTD AU1000_PCI_INTD
+#endif
+
+#ifdef CONFIG_SOC_AU1550
+#define INTA AU1550_PCI_INTA
+#define INTB AU1550_PCI_INTB
+#define INTC AU1550_PCI_INTC
+#define INTD AU1550_PCI_INTD
+#endif
+
+#define INTX    0xFF /* not valid */
+
+#ifdef CONFIG_MIPS_DB1500
+static char irq_tab_alchemy[][5] __initdata = {
+ [12] =	{ -1, INTA, INTX, INTX, INTX},   /* IDSEL 12 - HPT371   */
+ [13] =	{ -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot */
+};
+#endif
+
+#ifdef CONFIG_MIPS_BOSPORUS
+static char irq_tab_alchemy[][5] __initdata = {
+ [11] =	{ -1, INTA, INTB, INTX, INTX},   /* IDSEL 11 - miniPCI  */
+ [12] =	{ -1, INTA, INTX, INTX, INTX},   /* IDSEL 12 - SN1741   */
+ [13] =	{ -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot */
+};
+#endif
+
+#ifdef CONFIG_MIPS_MIRAGE
+static char irq_tab_alchemy[][5] __initdata = {
+ [11] =	{ -1, INTD, INTX, INTX, INTX},   /* IDSEL 11 - SMI VGX */
+ [12] =	{ -1, INTX, INTX, INTC, INTX},   /* IDSEL 12 - PNX1300 */
+ [13] =	{ -1, INTA, INTB, INTX, INTX},   /* IDSEL 13 - miniPCI */
+};
+#endif
+
+#ifdef CONFIG_MIPS_DB1550
+static char irq_tab_alchemy[][5] __initdata = {
+ [11] =	{ -1, INTC, INTX, INTX, INTX},   /* IDSEL 11 - on-board HPT371    */
+ [12] =	{ -1, INTB, INTC, INTD, INTA},   /* IDSEL 12 - PCI slot 2 (left)  */
+ [13] =	{ -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot 1 (right) */
+};
+#endif
+
+#ifdef CONFIG_MIPS_PB1500
+static char irq_tab_alchemy[][5] __initdata = {
+ [12] = { -1, INTA, INTX, INTX, INTX},   /* IDSEL 12 - HPT370   */
+ [13] = { -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot */
+};
+#endif
+
+#ifdef CONFIG_MIPS_PB1550
+static char irq_tab_alchemy[][5] __initdata = {
+ [12] =	{ -1, INTB, INTC, INTD, INTA},   /* IDSEL 12 - PCI slot 2 (left)  */
+ [13] =	{ -1, INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot 1 (right) */
+};
+#endif
+
+#ifdef CONFIG_MIPS_MTX1
+static char irq_tab_alchemy[][5] __initdata = {
+ [0] = { -1, INTA, INTB, INTX, INTX},   /* IDSEL 00 - AdapterA-Slot0 (top)    */
+ [1] = { -1, INTB, INTA, INTX, INTX},   /* IDSEL 01 - AdapterA-Slot1 (bottom) */
+ [2] = { -1, INTC, INTD, INTX, INTX},   /* IDSEL 02 - AdapterB-Slot0 (top)    */
+ [3] = { -1, INTD, INTC, INTX, INTX},   /* IDSEL 03 - AdapterB-Slot1 (bottom) */
+ [4] = { -1, INTA, INTB, INTX, INTX},   /* IDSEL 04 - AdapterC-Slot0 (top)    */
+ [5] = { -1, INTB, INTA, INTX, INTX},   /* IDSEL 05 - AdapterC-Slot1 (bottom) */
+ [6] = { -1, INTC, INTD, INTX, INTX},   /* IDSEL 06 - AdapterD-Slot0 (top)    */
+ [7] = { -1, INTD, INTC, INTX, INTX},   /* IDSEL 07 - AdapterD-Slot1 (bottom) */
+};
+#endif
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	return irq_tab_alchemy[slot][pin];
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
diff --git a/arch/mips/pci/fixup-capcella.c b/arch/mips/pci/fixup-capcella.c
new file mode 100644
index 0000000..f2fc82c
--- /dev/null
+++ b/arch/mips/pci/fixup-capcella.c
@@ -0,0 +1,50 @@
+/*
+ *  fixup-cappcela.c, The ZAO Networks Capcella specific PCI fixups.
+ *
+ *  Copyright (C) 2002,2004  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/vr41xx/capcella.h>
+
+/*
+ * Shortcuts
+ */
+#define INT1	RTL8139_1_IRQ
+#define INT2	RTL8139_2_IRQ
+#define INTA	PC104PLUS_INTA_IRQ
+#define INTB	PC104PLUS_INTB_IRQ
+#define INTC	PC104PLUS_INTC_IRQ
+#define INTD	PC104PLUS_INTD_IRQ
+
+static char irq_tab_capcella[][5] __initdata = {
+ [11] = { -1, INT1, INT1, INT1, INT1 },
+ [12] = { -1, INT2, INT2, INT2, INT2 },
+ [14] = { -1, INTA, INTB, INTC, INTD }
+};
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	return irq_tab_capcella[slot][pin];
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
diff --git a/arch/mips/pci/fixup-cobalt.c b/arch/mips/pci/fixup-cobalt.c
new file mode 100644
index 0000000..57e1ca2
--- /dev/null
+++ b/arch/mips/pci/fixup-cobalt.c
@@ -0,0 +1,112 @@
+/*
+ * Cobalt Qube/Raq PCI support
+ *
+ * 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, 1996, 1997, 2002, 2003 by Ralf Baechle
+ * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv)
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/pci.h>
+#include <asm/io.h>
+#include <asm/gt64120.h>
+
+#include <asm/cobalt/cobalt.h>
+
+extern int cobalt_board_id;
+
+static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev)
+{
+	unsigned short cfgword;
+	unsigned char lt;
+
+	/* Enable Bus Mastering and fast back to back. */
+	pci_read_config_word(dev, PCI_COMMAND, &cfgword);
+	cfgword |= (PCI_COMMAND_FAST_BACK | PCI_COMMAND_MASTER);
+	pci_write_config_word(dev, PCI_COMMAND, cfgword);
+
+	/* Enable both ide interfaces. ROM only enables primary one.  */
+	pci_write_config_byte(dev, 0x40, 0xb);
+
+	/* Set latency timer to reasonable value. */
+	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lt);
+	if (lt < 64)
+		pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
+	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 7);
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1,
+	 qube_raq_via_bmIDE_fixup);
+
+static void qube_raq_galileo_fixup(struct pci_dev *dev)
+{
+	unsigned short galileo_id;
+
+	/* Fix PCI latency-timer and cache-line-size values in Galileo
+	 * host bridge.
+	 */
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
+	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 7);
+
+	/*
+	 * On all machines prior to Q2, we had the STOP line disconnected
+	 * from Galileo to VIA on PCI.  The new Galileo does not function
+	 * correctly unless we have it connected.
+	 *
+	 * Therefore we must set the disconnect/retry cycle values to
+	 * something sensible when using the new Galileo.
+	 */
+	pci_read_config_word(dev, PCI_REVISION_ID, &galileo_id);
+	galileo_id &= 0xff;	/* mask off class info */
+	if (galileo_id >= 0x10) {
+		/* New Galileo, assumes PCI stop line to VIA is connected. */
+		GALILEO_OUTL(0x4020, GT_PCI0_TOR_OFS);
+	} else if (galileo_id == 0x1 || galileo_id == 0x2) {
+		signed int timeo;
+		/* XXX WE MUST DO THIS ELSE GALILEO LOCKS UP! -DaveM */
+		timeo = GALILEO_INL(GT_PCI0_TOR_OFS);
+		/* Old Galileo, assumes PCI STOP line to VIA is disconnected. */
+		GALILEO_OUTL(0xffff, GT_PCI0_TOR_OFS);
+	}
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_GALILEO, PCI_ANY_ID,
+	 qube_raq_galileo_fixup);
+
+static char irq_tab_cobalt[] __initdata = {
+  [COBALT_PCICONF_CPU]     = 0,
+  [COBALT_PCICONF_ETH0]    = COBALT_ETH0_IRQ,
+  [COBALT_PCICONF_RAQSCSI] = COBALT_SCSI_IRQ,
+  [COBALT_PCICONF_VIA]     = 0,
+  [COBALT_PCICONF_PCISLOT] = COBALT_QUBE_SLOT_IRQ,
+  [COBALT_PCICONF_ETH1]    = COBALT_ETH1_IRQ
+};
+
+static char irq_tab_raq2[] __initdata = {
+  [COBALT_PCICONF_CPU]     = 0,
+  [COBALT_PCICONF_ETH0]    = COBALT_ETH0_IRQ,
+  [COBALT_PCICONF_RAQSCSI] = COBALT_RAQ_SCSI_IRQ,
+  [COBALT_PCICONF_VIA]     = 0,
+  [COBALT_PCICONF_PCISLOT] = COBALT_QUBE_SLOT_IRQ,
+  [COBALT_PCICONF_ETH1]    = COBALT_ETH1_IRQ
+};
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	if (cobalt_board_id == COBALT_BRD_ID_RAQ2)
+		return irq_tab_raq2[slot];
+
+	return irq_tab_cobalt[slot];
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
diff --git a/arch/mips/pci/fixup-ddb5074.c b/arch/mips/pci/fixup-ddb5074.c
new file mode 100644
index 0000000..b345e52
--- /dev/null
+++ b/arch/mips/pci/fixup-ddb5074.c
@@ -0,0 +1,21 @@
+/*
+ * It's nice to have the LEDs on the GPIO pins available for debugging
+ */
+static void ddb5074_fixup(struct pci_dev *dev)
+{
+	extern struct pci_dev *pci_pmu;
+	u8 t8;
+                                                                
+	pci_pmu = dev;  /* for LEDs D2 and D3 */
+	/* Program the lines for LEDs D2 and D3 to output */
+	pci_read_config_byte(dev, 0x7d, &t8);
+	t8 |= 0xc0;
+	pci_write_config_byte(dev, 0x7d, t8);
+	/* Turn LEDs D2 and D3 off */
+	pci_read_config_byte(dev, 0x7e, &t8);
+	t8 |= 0xc0;
+	pci_write_config_byte(dev, 0x7e, t8);
+}
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101,
+	  ddb5074_fixup);
diff --git a/arch/mips/pci/fixup-ddb5477.c b/arch/mips/pci/fixup-ddb5477.c
new file mode 100644
index 0000000..6abdc88
--- /dev/null
+++ b/arch/mips/pci/fixup-ddb5477.c
@@ -0,0 +1,78 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Board specific pci fixups.
+ *
+ * Copyright 2001, 2002, 2003 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+static void ddb5477_fixup(struct pci_dev *dev)
+{
+	u8 old;
+
+	printk(KERN_NOTICE "Enabling ALI M1533/35 PS2 keyboard/mouse.\n");
+	pci_read_config_byte(dev, 0x41, &old);
+	pci_write_config_byte(dev, 0x41, old | 0xd0);
+}
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
+	  ddb5477_fixup);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1535,
+	  ddb5477_fixup);
+
+/*
+ * Fixup baseboard AMD chip so that tx does not underflow.
+ *      bcr_18 |= 0x0800
+ * This sets NOUFLO bit which makes tx not start until whole pkt
+ * is fetched to the chip.
+ */
+#define PCNET32_WIO_RDP		0x10
+#define PCNET32_WIO_RAP		0x12
+#define PCNET32_WIO_RESET	0x14
+#define PCNET32_WIO_BDP		0x16
+
+static void ddb5477_amd_lance_fixup(struct pci_dev *dev)
+{
+	unsigned long ioaddr;
+	u16 temp;
+
+	ioaddr = pci_resource_start(dev, 0);
+
+	inw(ioaddr + PCNET32_WIO_RESET);	/* reset chip */
+                                                                                
+	/* bcr_18 |= 0x0800 */
+	outw(18, ioaddr + PCNET32_WIO_RAP);
+	temp = inw(ioaddr + PCNET32_WIO_BDP);
+	temp |= 0x0800;
+	outw(18, ioaddr + PCNET32_WIO_RAP);
+	outw(temp, ioaddr + PCNET32_WIO_BDP);
+}
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE,
+	  ddb5477_amd_lance_fixup);
diff --git a/arch/mips/pci/fixup-ev64120.c b/arch/mips/pci/fixup-ev64120.c
new file mode 100644
index 0000000..8dbb90d
--- /dev/null
+++ b/arch/mips/pci/fixup-ev64120.c
@@ -0,0 +1,34 @@
+#include <linux/pci.h>
+#include <linux/init.h>
+
+int pci_range_ck(unsigned char bus, unsigned char dev)
+{
+	if (((bus == 0) || (bus == 1)) && (dev >= 6) && (dev <= 8))
+		return 0;
+
+	return -1;
+}
+
+/*
+ * After detecting all agents over the PCI , this function is called
+ * in order to give an interrupt number for each PCI device starting
+ * from IRQ 20. It does also enables master for each device.
+ */
+void __devinit pcibios_fixup_bus(struct pci_bus *bus)
+{
+	unsigned int irq = 20;
+	struct pci_bus *current_bus = bus;
+	struct pci_dev *dev;
+	struct list_head *devices_link;
+
+	list_for_each(devices_link, &(current_bus->devices)) {
+		dev = pci_dev_b(devices_link);
+		if (dev != NULL) {
+			dev->irq = irq++;
+
+			/* Assign an interrupt number for the device */
+			pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+			pcibios_set_master(dev);
+		}
+	}
+}
diff --git a/arch/mips/pci/fixup-ev96100.c b/arch/mips/pci/fixup-ev96100.c
new file mode 100644
index 0000000..e2bc977
--- /dev/null
+++ b/arch/mips/pci/fixup-ev96100.c
@@ -0,0 +1,48 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	EV96100 Board specific pci fixups.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+
+static char irq_tab_ev96100[][5] __initdata = {
+ [8] = { 0, 5, 5, 5, 5 },
+ [9] = { 0, 2, 2, 2, 2 }
+};
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	return irq_tab_ev96100[slot][pin];
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
diff --git a/arch/mips/pci/fixup-ip32.c b/arch/mips/pci/fixup-ip32.c
new file mode 100644
index 0000000..3e66b0a
--- /dev/null
+++ b/arch/mips/pci/fixup-ip32.c
@@ -0,0 +1,51 @@
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <asm/ip32/ip32_ints.h>
+/*
+ * O2 has up to 5 PCI devices connected into the MACE bridge.  The device
+ * map looks like this:
+ *
+ * 0  aic7xxx 0
+ * 1  aic7xxx 1
+ * 2  expansion slot
+ * 3  N/C
+ * 4  N/C
+ */
+
+#define SCSI0  MACEPCI_SCSI0_IRQ
+#define SCSI1  MACEPCI_SCSI1_IRQ
+#define INTA0  MACEPCI_SLOT0_IRQ
+#define INTA1  MACEPCI_SLOT1_IRQ
+#define INTA2  MACEPCI_SLOT2_IRQ
+#define INTB   MACEPCI_SHARED0_IRQ
+#define INTC   MACEPCI_SHARED1_IRQ
+#define INTD   MACEPCI_SHARED2_IRQ
+static char irq_tab_mace[][5] __initdata = {
+      /* Dummy  INT#A  INT#B  INT#C  INT#D */
+	{0,         0,     0,     0,     0}, /* This is placeholder row - never used */
+	{0,     SCSI0, SCSI0, SCSI0, SCSI0},
+	{0,     SCSI1, SCSI1, SCSI1, SCSI1},
+	{0,     INTA0,  INTB,  INTC,  INTD},
+	{0,     INTA1,  INTC,  INTD,  INTB},
+	{0,     INTA2,  INTD,  INTB,  INTC},
+};
+
+
+/*
+ * Given a PCI slot number (a la PCI_SLOT(...)) and the interrupt pin of
+ * the device (1-4 => A-D), tell what irq to use.  Note that we don't
+ * in theory have slots 4 and 5, and we never normally use the shared
+ * irqs.  I suppose a device without a pin A will thank us for doing it
+ * right if there exists such a broken piece of crap.
+ */
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	return irq_tab_mace[slot][pin];
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
diff --git a/arch/mips/pci/fixup-ite8172g.c b/arch/mips/pci/fixup-ite8172g.c
new file mode 100644
index 0000000..2290ea4
--- /dev/null
+++ b/arch/mips/pci/fixup-ite8172g.c
@@ -0,0 +1,80 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Board specific pci fixups.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/it8172/it8172.h>
+#include <asm/it8172/it8172_pci.h>
+#include <asm/it8172/it8172_int.h>
+
+/*
+ * Shortcuts
+ */
+#define INTA	IT8172_PCI_INTA_IRQ
+#define INTB	IT8172_PCI_INTB_IRQ
+#define INTC	IT8172_PCI_INTC_IRQ
+#define INTD	IT8172_PCI_INTD_IRQ
+
+static const int internal_func_irqs[7] __initdata = {
+	IT8172_AC97_IRQ,
+	IT8172_DMA_IRQ,
+	IT8172_CDMA_IRQ,
+	IT8172_USB_IRQ,
+	IT8172_BRIDGE_MASTER_IRQ,
+	IT8172_IDE_IRQ,
+	IT8172_MC68K_IRQ
+};
+
+static char irq_tab_ite8172g[][5] __initdata = {
+ [0x10] = {	0, INTA, INTB, INTC, INTD },
+ [0x11] = {	0, INTA, INTB, INTC, INTD },
+ [0x12] = {	0, INTB, INTC, INTD, INTA },
+ [0x13] = {	0, INTC, INTD, INTA, INTB },
+ [0x14] = {	0, INTD, INTA, INTB, INTC },
+};
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	/*
+	 * Internal device 1 is actually 7 different internal devices on the
+	 * IT8172G (a multifunction device).
+	 */
+	if (slot == 1)
+		return internal_func_irqs[PCI_FUNC(dev->devfn)];
+
+	return irq_tab_ite8172g[slot][pin];
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
diff --git a/arch/mips/pci/fixup-ivr.c b/arch/mips/pci/fixup-ivr.c
new file mode 100644
index 0000000..0c7c164
--- /dev/null
+++ b/arch/mips/pci/fixup-ivr.c
@@ -0,0 +1,75 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Globespan IVR board-specific pci fixups.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/it8172/it8172.h>
+#include <asm/it8172/it8172_pci.h>
+#include <asm/it8172/it8172_int.h>
+
+/*
+ * Shortcuts
+ */
+#define INTA	IT8172_PCI_INTA_IRQ
+#define INTB	IT8172_PCI_INTB_IRQ
+#define INTC	IT8172_PCI_INTC_IRQ
+#define INTD	IT8172_PCI_INTD_IRQ
+
+static const int internal_func_irqs[7] __initdata = {
+	IT8172_AC97_IRQ,
+	IT8172_DMA_IRQ,
+	IT8172_CDMA_IRQ,
+	IT8172_USB_IRQ,
+	IT8172_BRIDGE_MASTER_IRQ,
+	IT8172_IDE_IRQ,
+	IT8172_MC68K_IRQ
+};
+
+static char irq_tab_ivr[][5] __initdata = {
+ [0x11] = { INTC, INTC, INTD, INTA, INTB },	/* Realtek RTL-8139	*/
+ [0x12] = { INTB, INTB, INTB, INTC, INTC },	/* IVR slot		*/
+ [0x13] = { INTA, INTA, INTB, INTC, INTD }	/* Expansion slot	*/
+};
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	if (slot == 1)
+		return internal_func_irqs[PCI_FUNC(dev->devfn)];
+
+	return irq_tab_ivr[slot][pin];
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
diff --git a/arch/mips/pci/fixup-jaguar.c b/arch/mips/pci/fixup-jaguar.c
new file mode 100644
index 0000000..6c5e1d4
--- /dev/null
+++ b/arch/mips/pci/fixup-jaguar.c
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ *
+ * Marvell MV64340 interrupt fixup code.
+ *
+ * Marvell wants an NDA for their docs so this was written without
+ * documentation.  You've been warned.
+ *
+ * Copyright (C) 2004 Ralf Baechle (ralf@linux-mips.org)
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/mipsregs.h>
+
+/*
+ * WARNING: Example of how _NOT_ to do it.
+ */
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	int bus = dev->bus->number;
+
+	if (bus == 0 && slot == 1)
+		return 3;	/* PCI-X A */
+	if (bus == 0 && slot == 2)
+		return 4;	/* PCI-X B */
+	if (bus == 1 && slot == 1)
+		return 5;	/* PCI A */
+	if (bus == 1 && slot == 2)
+		return 6;	/* PCI B */
+
+return 0;
+	panic("Whooops in pcibios_map_irq");
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
diff --git a/arch/mips/pci/fixup-jmr3927.c b/arch/mips/pci/fixup-jmr3927.c
new file mode 100644
index 0000000..f869608
--- /dev/null
+++ b/arch/mips/pci/fixup-jmr3927.c
@@ -0,0 +1,105 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Board specific pci fixups.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/jmr3927/jmr3927.h>
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	unsigned char irq = pin;
+
+	/* IRQ rotation (PICMG) */
+	irq--;			/* 0-3 */
+	if (dev->bus->parent == NULL &&
+	    slot == TX3927_PCIC_IDSEL_AD_TO_SLOT(23)) {
+		/* PCI CardSlot (IDSEL=A23, DevNu=12) */
+		/* PCIA => PCIC (IDSEL=A23) */
+		/* NOTE: JMR3927 JP1 must be set to OPEN */
+		irq = (irq + 2) % 4;
+	} else if (dev->bus->parent == NULL &&
+		   slot == TX3927_PCIC_IDSEL_AD_TO_SLOT(22)) {
+		/* PCI CardSlot (IDSEL=A22, DevNu=11) */
+		/* PCIA => PCIA (IDSEL=A22) */
+		/* NOTE: JMR3927 JP1 must be set to OPEN */
+		irq = (irq + 0) % 4;
+	} else {
+		/* PCI Backplane */
+		irq = (irq + 3 + slot) % 4;
+	}
+	irq++;			/* 1-4 */
+
+	switch (irq) {
+	case 1:
+		irq = JMR3927_IRQ_IOC_PCIA;
+		break;
+	case 2:
+		// wrong for backplane irq = JMR3927_IRQ_IOC_PCIB;
+		irq = JMR3927_IRQ_IOC_PCID;
+		break;
+	case 3:
+		irq = JMR3927_IRQ_IOC_PCIC;
+		break;
+	case 4:
+		// wrong for backplane irq = JMR3927_IRQ_IOC_PCID;
+		irq = JMR3927_IRQ_IOC_PCIB;
+		break;
+	}
+
+	/* Check OnBoard Ethernet (IDSEL=A24, DevNu=13) */
+	if (dev->bus->parent == NULL &&
+	    slot == TX3927_PCIC_IDSEL_AD_TO_SLOT(24)) {
+		extern int jmr3927_ether1_irq;
+		/* check this irq line was reserved for ether1 */
+		if (jmr3927_ether1_irq != JMR3927_IRQ_ETHER0)
+			irq = JMR3927_IRQ_ETHER0;
+		else
+			irq = 0;	/* disable */
+	}
+	return irq;
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	/* SMSC SLC90E66 IDE uses irq 14, 15 (default) */
+	if (!(dev->vendor == PCI_VENDOR_ID_EFAR &&
+	      dev->device == PCI_DEVICE_ID_EFAR_SLC90E66_1))
+		return pci_get_irq(dev, pin);
+
+	dev->irq = irq;
+}
diff --git a/arch/mips/pci/fixup-malta.c b/arch/mips/pci/fixup-malta.c
new file mode 100644
index 0000000..b9296d9
--- /dev/null
+++ b/arch/mips/pci/fixup-malta.c
@@ -0,0 +1,103 @@
+#include <linux/init.h>
+#include <linux/pci.h>
+
+/* PCI interrupt pins */
+#define PCIA		1
+#define PCIB		2
+#define PCIC		3
+#define PCID		4
+
+/* This table is filled in by interrogating the PIIX4 chip */
+static char pci_irq[5] __initdata;
+
+static char irq_tab[][5] __initdata = {
+	/*      INTA    INTB    INTC    INTD */
+	{0,	0,	0,	0,	0 },	/*  0: GT64120 PCI bridge */
+	{0,	0,	0,	0,	0 },	/*  1: Unused */
+	{0,	0,	0,	0,	0 },	/*  2: Unused */
+	{0,	0,	0,	0,	0 },	/*  3: Unused */
+	{0,	0,	0,	0,	0 },	/*  4: Unused */
+	{0,	0,	0,	0,	0 },	/*  5: Unused */
+	{0,	0,	0,	0,	0 },	/*  6: Unused */
+	{0,	0,	0,	0,	0 },	/*  7: Unused */
+	{0,	0,	0,	0,	0 },	/*  8: Unused */
+	{0,	0,	0,	0,	0 },	/*  9: Unused */
+	{0,	0,	0,	0,	PCID },	/* 10: PIIX4 USB */
+	{0,	PCIB,	0,	0,	0 },	/* 11: AMD 79C973 Ethernet */
+	{0,	PCIC,	0,	0,	0 },	/* 12: Crystal 4281 Sound */
+	{0,	0,	0,	0,	0 },	/* 13: Unused */
+	{0,	0,	0,	0,	0 },	/* 14: Unused */
+	{0,	0,	0,	0,	0 },	/* 15: Unused */
+	{0,	0,	0,	0,	0 },	/* 16: Unused */
+	{0,	0,	0,	0,	0 },	/* 17: Bonito/SOC-it PCI Bridge*/
+	{0,	PCIA,	PCIB,	PCIC,	PCID },	/* 18: PCI Slot 1 */
+	{0,	PCIB,	PCIC,	PCID,	PCIA },	/* 19: PCI Slot 2 */
+	{0,	PCIC,	PCID,	PCIA,	PCIB },	/* 20: PCI Slot 3 */
+	{0,	PCID,	PCIA,	PCIB,	PCIC }	/* 21: PCI Slot 4 */
+};
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	int virq;
+	virq = irq_tab[slot][pin];
+	return pci_irq[virq];
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
+
+static void __init malta_piix_func0_fixup(struct pci_dev *pdev)
+{
+	unsigned char reg_val;
+	static int piixirqmap[16] __initdata = {  /* PIIX PIRQC[A:D] irq mappings */
+		0,  0, 	0,  3,
+		4,  5,  6,  7,
+		0,  9, 10, 11,
+		12, 0, 14, 15 
+	};
+	int i;
+
+	/* Interrogate PIIX4 to get PCI IRQ mapping */
+	for (i = 0; i <= 3; i++) {
+		pci_read_config_byte(pdev, 0x60+i, &reg_val);
+		if (reg_val & 0x80)
+			pci_irq[PCIA+i] = 0;	/* Disabled */
+		else
+			pci_irq[PCIA+i] = piixirqmap[reg_val & 15];
+	}
+
+	/* Done by YAMON 2.00 onwards */
+	if (PCI_SLOT(pdev->devfn) == 10) {
+		/*
+		 * Set top of main memory accessible by ISA or DMA
+		 * devices to 16 Mb.
+		 */
+		pci_read_config_byte(pdev, 0x69, &reg_val);
+		pci_write_config_byte(pdev, 0x69, reg_val | 0xf0);
+	}
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0,
+	 malta_piix_func0_fixup);
+
+static void __init malta_piix_func1_fixup(struct pci_dev *pdev)
+{
+	unsigned char reg_val;
+
+	/* Done by YAMON 2.02 onwards */
+	if (PCI_SLOT(pdev->devfn) == 10) {
+		/*
+		 * IDE Decode enable.
+		 */
+		pci_read_config_byte(pdev, 0x41, &reg_val);
+		pci_write_config_byte(pdev, 0x41, reg_val|0x80);
+		pci_read_config_byte(pdev, 0x43, &reg_val);
+		pci_write_config_byte(pdev, 0x43, reg_val|0x80);
+	}
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB,
+	 malta_piix_func1_fixup);
diff --git a/arch/mips/pci/fixup-mpc30x.c b/arch/mips/pci/fixup-mpc30x.c
new file mode 100644
index 0000000..4975846
--- /dev/null
+++ b/arch/mips/pci/fixup-mpc30x.c
@@ -0,0 +1,50 @@
+/*
+ *  fixup-mpc30x.c, The Victor MP-C303/304 specific PCI fixups.
+ *
+ *  Copyright (C) 2002,2004  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/vr41xx/mpc30x.h>
+#include <asm/vr41xx/vrc4173.h>
+
+static const int internal_func_irqs[] __initdata = {
+	VRC4173_CASCADE_IRQ,
+	VRC4173_AC97_IRQ,
+	VRC4173_USB_IRQ,
+};
+
+static const int irq_tab_mpc30x[] __initdata = {
+ [12] = VRC4173_PCMCIA1_IRQ,
+ [13] = VRC4173_PCMCIA2_IRQ,
+ [29] = MQ200_IRQ,
+};
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	if (slot == 30)
+		return internal_func_irqs[PCI_FUNC(dev->devfn)];
+
+	return irq_tab_mpc30x[slot];
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
diff --git a/arch/mips/pci/fixup-ocelot-c.c b/arch/mips/pci/fixup-ocelot-c.c
new file mode 100644
index 0000000..d454948
--- /dev/null
+++ b/arch/mips/pci/fixup-ocelot-c.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2002 Momentum Computer Inc.
+ * Author: Matthew Dharm <mdharm@momenco.com>
+ *
+ * Based on work for the Linux port to the Ocelot board, which is
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/momentum/ocelot_g/pci.c
+ *     Board-specific PCI routines for mv64340 controller.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	int bus = dev->bus->number;
+
+	if (bus == 0 && slot == 1)
+		return 2;       /* PCI-X A */
+	if (bus == 1 && slot == 1)
+		return 12;      /* PCI-X B */
+	if (bus == 1 && slot == 2)
+		return 4;       /* PCI B */
+
+return 0;
+	panic("Whooops in pcibios_map_irq");
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
diff --git a/arch/mips/pci/fixup-ocelot-g.c b/arch/mips/pci/fixup-ocelot-g.c
new file mode 100644
index 0000000..d7a652e
--- /dev/null
+++ b/arch/mips/pci/fixup-ocelot-g.c
@@ -0,0 +1,37 @@
+/*
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Copyright (C) 2004 Ralf Baechle (ralf@linux-mips.org)
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	int bus = dev->bus->number;
+
+	if (bus == 0 && slot == 1)	/* Intel 82543 Gigabit MAC */
+		return 2;		/* irq_nr is 2 for INT0 */
+
+	if (bus == 0 && slot == 2)	/* Intel 82543 Gigabit MAC */
+		return 3;		/* irq_nr is 3 for INT1 */
+
+	if (bus == 1 && slot == 3)	/* Intel 21555 bridge */
+		return 5;		/* irq_nr is 8 for INT6 */
+
+	if (bus == 1 && slot == 4)	/* PMC Slot */
+		return 9;		/* irq_nr is 9 for INT7 */
+
+	return -1;
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
diff --git a/arch/mips/pci/fixup-ocelot.c b/arch/mips/pci/fixup-ocelot.c
new file mode 100644
index 0000000..99629bd
--- /dev/null
+++ b/arch/mips/pci/fixup-ocelot.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/gt64120/momenco_ocelot/pci.c
+ *     Board-specific PCI routines for gt64120 controller.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/pci.h>
+
+
+void __devinit pcibios_fixup_bus(struct pci_bus *bus)
+{
+	struct pci_bus *current_bus = bus;
+	struct pci_dev *devices;
+	struct list_head *devices_link;
+	u16 cmd;
+
+	list_for_each(devices_link, &(current_bus->devices)) {
+
+		devices = pci_dev_b(devices_link);
+		if (devices == NULL)
+			continue;
+
+		if (PCI_SLOT(devices->devfn) == 1) {
+			/*
+			 * Slot 1 is primary ether port, i82559
+			 * we double-check against that assumption
+			 */
+			if ((devices->vendor != 0x8086) ||
+			    (devices->device != 0x1209)) {
+				panic("pcibios_fixup_bus: found "
+				     "unexpected PCI device in slot 1.");
+			}
+			devices->irq = 2;	/* irq_nr is 2 for INT0 */
+		} else if (PCI_SLOT(devices->devfn) == 2) {
+			/*
+			 * Slot 2 is secondary ether port, i21143
+			 * we double-check against that assumption
+			 */
+			if ((devices->vendor != 0x1011) ||
+			    (devices->device != 0x19)) {
+				panic("galileo_pcibios_fixup_bus: "
+				      "found unexpected PCI device in slot 2.");
+			}
+			devices->irq = 3;	/* irq_nr is 3 for INT1 */
+		} else if (PCI_SLOT(devices->devfn) == 4) {
+			/* PMC Slot 1 */
+			devices->irq = 8;	/* irq_nr is 8 for INT6 */
+		} else if (PCI_SLOT(devices->devfn) == 5) {
+			/* PMC Slot 1 */
+			devices->irq = 9;	/* irq_nr is 9 for INT7 */
+		} else {
+			/* We don't have assign interrupts for other devices. */
+			devices->irq = 0xff;
+		}
+
+		/* Assign an interrupt number for the device */
+		bus->ops->write_byte(devices, PCI_INTERRUPT_LINE,
+				     devices->irq);
+
+		/* enable master */
+		bus->ops->read_word(devices, PCI_COMMAND, &cmd);
+		cmd |= PCI_COMMAND_MASTER;
+		bus->ops->write_word(devices, PCI_COMMAND, cmd);
+	}
+}
diff --git a/arch/mips/pci/fixup-ocelot3.c b/arch/mips/pci/fixup-ocelot3.c
new file mode 100644
index 0000000..ececc03
--- /dev/null
+++ b/arch/mips/pci/fixup-ocelot3.c
@@ -0,0 +1,41 @@
+/*
+ * 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) 2004 Montavista Software Inc.
+ * Author: Manish Lachwani (mlachwani@mvista.com)
+ *
+ * Looking at the schematics for the Ocelot-3 board, there are
+ * two PCI busses and each bus has two PCI slots.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <asm/mipsregs.h>
+
+/*
+ * Do platform specific device initialization at
+ * pci_enable_device() time
+ */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	int bus = dev->bus->number;
+
+	if (bus == 0 && slot == 1)
+		return 2;	/* PCI-X A */
+	if (bus == 0 && slot == 2)
+		return 3;	/* PCI-X B */
+	if (bus == 1 && slot == 1)
+		return 4;	/* PCI A */
+	if (bus == 1 && slot == 2)
+		return 5;	/* PCI B */
+
+return 0;
+	panic("Whooops in pcibios_map_irq");
+}
diff --git a/arch/mips/pci/fixup-rbtx4927.c b/arch/mips/pci/fixup-rbtx4927.c
new file mode 100644
index 0000000..de4e443
--- /dev/null
+++ b/arch/mips/pci/fixup-rbtx4927.c
@@ -0,0 +1,140 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *      Board specific pci fixups for the Toshiba rbtx4927
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *              ppopov@mvista.com or source@mvista.com
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation 
+ *
+ * Copyright (C) 2004 MontaVista Software Inc.
+ * Author: Manish Lachwani (mlachwani@mvista.com)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/tx4927/tx4927.h>
+#include <asm/tx4927/tx4927_pci.h>
+
+#undef  DEBUG
+#ifdef  DEBUG
+#define DBG(x...)       printk(x)
+#else
+#define DBG(x...)
+#endif
+
+/* look up table for backplane pci irq for slots 17-20 by pin # */
+static unsigned char backplane_pci_irq[4][4] = {
+	/* PJ6 SLOT:  17, PIN: 1 */ {TX4927_IRQ_IOC_PCIA,
+				     /* PJ6 SLOT:  17, PIN: 2 */
+				     TX4927_IRQ_IOC_PCIB,
+				     /* PJ6 SLOT:  17, PIN: 3 */
+				     TX4927_IRQ_IOC_PCIC,
+				     /* PJ6 SLOT:  17, PIN: 4 */
+				     TX4927_IRQ_IOC_PCID},
+	/* SB  SLOT:  18, PIN: 1 */ {TX4927_IRQ_IOC_PCIB,
+				     /* SB  SLOT:  18, PIN: 2 */
+				     TX4927_IRQ_IOC_PCIC,
+				     /* SB  SLOT:  18, PIN: 3 */
+				     TX4927_IRQ_IOC_PCID,
+				     /* SB  SLOT:  18, PIN: 4 */
+				     TX4927_IRQ_IOC_PCIA},
+	/* PJ5 SLOT:  19, PIN: 1 */ {TX4927_IRQ_IOC_PCIC,
+				     /* PJ5 SLOT:  19, PIN: 2 */
+				     TX4927_IRQ_IOC_PCID,
+				     /* PJ5 SLOT:  19, PIN: 3 */
+				     TX4927_IRQ_IOC_PCIA,
+				     /* PJ5 SLOT:  19, PIN: 4 */
+				     TX4927_IRQ_IOC_PCIB},
+	/* PJ4 SLOT:  20, PIN: 1 */ {TX4927_IRQ_IOC_PCID,
+				     /* PJ4 SLOT:  20, PIN: 2 */
+				     TX4927_IRQ_IOC_PCIA,
+				     /* PJ4 SLOT:  20, PIN: 3 */
+				     TX4927_IRQ_IOC_PCIB,
+				     /* PJ4 SLOT:  20, PIN: 4 */
+				     TX4927_IRQ_IOC_PCIC}
+};
+
+int pci_get_irq(struct pci_dev *dev, int pin)
+{
+	unsigned char irq = pin;
+
+	DBG("pci_get_irq: pin is %d\n", pin);
+	/* IRQ rotation */
+	irq--;			/* 0-3 */
+	if (dev->bus->parent == NULL &&
+	    PCI_SLOT(dev->devfn) == TX4927_PCIC_IDSEL_AD_TO_SLOT(23)) {
+		printk("Onboard PCI_SLOT(dev->devfn) is %d\n",
+		       PCI_SLOT(dev->devfn));
+		/* IDSEL=A23 is tx4927 onboard pci slot */
+		irq = (irq + PCI_SLOT(dev->devfn)) % 4;
+		irq++;		/* 1-4 */
+		DBG("irq is now %d\n", irq);
+
+		switch (irq) {
+		case 1:
+			irq = TX4927_IRQ_IOC_PCIA;
+			break;
+		case 2:
+			irq = TX4927_IRQ_IOC_PCIB;
+			break;
+		case 3:
+			irq = TX4927_IRQ_IOC_PCIC;
+			break;
+		case 4:
+			irq = TX4927_IRQ_IOC_PCID;
+			break;
+		}
+	} else {
+		/* PCI Backplane */
+		DBG("PCI Backplane PCI_SLOT(dev->devfn) is %d\n",
+		    PCI_SLOT(dev->devfn));
+		irq = backplane_pci_irq[PCI_SLOT(dev->devfn) - 17][irq];
+	}
+	DBG("assigned irq %d\n", irq);
+	return irq;
+}
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	unsigned char irq;
+
+	printk("PCI Setup for pin %d \n", pin);
+
+	if (dev->device == 0x9130) /* IDE */
+		irq = 14;
+	else
+		irq = pci_get_irq(dev, pin);
+
+	return irq;
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
diff --git a/arch/mips/pci/fixup-sb1250.c b/arch/mips/pci/fixup-sb1250.c
new file mode 100644
index 0000000..13791b7
--- /dev/null
+++ b/arch/mips/pci/fixup-sb1250.c
@@ -0,0 +1,24 @@
+/*
+ *	arch/mips/pci/fixup-sb1250.c
+ *
+ *	Copyright (C) 2004  MIPS Technologies, Inc.  All rights reserved.
+ *	    Author:	Maciej W. Rozycki <macro@mips.com>
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/pci.h>
+
+/*
+ * The BCM1250, etc. PCI/HT bridge reports as a host bridge.
+ */
+static void __init quirk_sb1250_ht(struct pci_dev *dev)
+{
+	dev->class = PCI_CLASS_BRIDGE_PCI << 8;
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIBYTE, PCI_DEVICE_ID_BCM1250_HT,
+			quirk_sb1250_ht);
diff --git a/arch/mips/pci/fixup-sni.c b/arch/mips/pci/fixup-sni.c
new file mode 100644
index 0000000..c8ef01a
--- /dev/null
+++ b/arch/mips/pci/fixup-sni.c
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ *
+ * SNI specific PCI support for RM200/RM300.
+ *
+ * Copyright (C) 1997 - 2000, 2003, 04 Ralf Baechle (ralf@linux-mips.org)
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/mipsregs.h>
+#include <asm/sni.h>
+
+/*
+ * Shortcuts ...
+ */
+#define SCSI	PCIMT_IRQ_SCSI
+#define ETH	PCIMT_IRQ_ETHERNET
+#define INTA	PCIMT_IRQ_INTA
+#define INTB	PCIMT_IRQ_INTB
+#define INTC	PCIMT_IRQ_INTC
+#define INTD	PCIMT_IRQ_INTD
+
+/*
+ * Device 0: PCI EISA Bridge	(directly routed)
+ * Device 1: NCR53c810 SCSI	(directly routed)
+ * Device 2: PCnet32 Ethernet	(directly routed)
+ * Device 3: VGA		(routed to INTB)
+ * Device 4: Unused
+ * Device 5: Slot 2
+ * Device 6: Slot 3
+ * Device 7: Slot 4	
+ *
+ * Documentation says the VGA is device 5 and device 3 is unused but that
+ * seem to be a documentation error.  At least on my RM200C the Cirrus
+ * Logic CL-GD5434 VGA is device 3.
+ */
+static char irq_tab_rm200[8][5] __initdata = {
+	/*       INTA  INTB  INTC  INTD */
+	{     0,    0,    0,    0,    0 },	/* EISA bridge */
+	{  SCSI, SCSI, SCSI, SCSI, SCSI },	/* SCSI */
+	{   ETH,  ETH,  ETH,  ETH,  ETH },	/* Ethernet */
+	{  INTB, INTB, INTB, INTB, INTB },	/* VGA */
+	{     0,    0,    0,    0,    0 },	/* Unused */
+	{     0, INTB, INTC, INTD, INTA },	/* Slot 2 */
+	{     0, INTC, INTD, INTA, INTB },	/* Slot 3 */
+	{     0, INTD, INTA, INTB, INTC },	/* Slot 4 */
+};
+
+/*
+ * In Revision D of the RM300 Device 2 has become a normal purpose Slot 1
+ *
+ * The VGA card is optional for RM300 systems.
+ */
+static char irq_tab_rm300d[8][5] __initdata = {
+	/*       INTA  INTB  INTC  INTD */
+	{     0,    0,    0,    0,    0 },	/* EISA bridge */
+	{  SCSI, SCSI, SCSI, SCSI, SCSI },	/* SCSI */
+	{     0, INTC, INTD, INTA, INTB },	/* Slot 1 */
+	{  INTB, INTB, INTB, INTB, INTB },	/* VGA */
+	{     0,    0,    0,    0,    0 },	/* Unused */
+	{     0, INTB, INTC, INTD, INTA },	/* Slot 2 */
+	{     0, INTC, INTD, INTA, INTB },	/* Slot 3 */
+	{     0, INTD, INTA, INTB, INTC },	/* Slot 4 */
+};
+
+static inline int is_rm300_revd(void)
+{
+	unsigned char csmsr = *(volatile unsigned char *)PCIMT_CSMSR;
+
+	return (csmsr & 0xa0) == 0x20;
+}
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	if (is_rm300_revd())
+		return irq_tab_rm300d[slot][pin];
+
+	return irq_tab_rm200[slot][pin];
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
diff --git a/arch/mips/pci/fixup-tb0219.c b/arch/mips/pci/fixup-tb0219.c
new file mode 100644
index 0000000..850a900
--- /dev/null
+++ b/arch/mips/pci/fixup-tb0219.c
@@ -0,0 +1,66 @@
+/*
+ *  fixup-tb0219.c, The TANBAC TB0219 specific PCI fixups.
+ *
+ *  Copyright (C) 2003  Megasolution Inc. <matsu@megasolution.jp>
+ *  Copyright (C) 2004  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/vr41xx/tb0219.h>
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	int irq = -1;
+
+	switch (slot) {
+	case 12:
+		vr41xx_set_irq_trigger(TB0219_PCI_SLOT1_PIN,
+				       TRIGGER_LEVEL,
+				       SIGNAL_THROUGH);
+		vr41xx_set_irq_level(TB0219_PCI_SLOT1_PIN,
+				     LEVEL_LOW);
+		irq = TB0219_PCI_SLOT1_IRQ;
+		break;
+	case 13:
+		vr41xx_set_irq_trigger(TB0219_PCI_SLOT2_PIN,
+				       TRIGGER_LEVEL,
+				       SIGNAL_THROUGH);
+		vr41xx_set_irq_level(TB0219_PCI_SLOT2_PIN,
+				     LEVEL_LOW);
+		irq = TB0219_PCI_SLOT2_IRQ;
+		break;
+	case 14:
+		vr41xx_set_irq_trigger(TB0219_PCI_SLOT3_PIN,
+				       TRIGGER_LEVEL,
+				       SIGNAL_THROUGH);
+		vr41xx_set_irq_level(TB0219_PCI_SLOT3_PIN,
+				     LEVEL_LOW);
+		irq = TB0219_PCI_SLOT3_IRQ;
+		break;
+	default:
+		break;
+	}
+
+	return irq;
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
diff --git a/arch/mips/pci/fixup-tb0226.c b/arch/mips/pci/fixup-tb0226.c
new file mode 100644
index 0000000..61513d5
--- /dev/null
+++ b/arch/mips/pci/fixup-tb0226.c
@@ -0,0 +1,85 @@
+/*
+ *  fixup-tb0226.c, The TANBAC TB0226 specific PCI fixups.
+ *
+ *  Copyright (C) 2002-2004  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/vr41xx/tb0226.h>
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	int irq = -1;
+
+	switch (slot) {
+	case 12:
+		vr41xx_set_irq_trigger(GD82559_1_PIN,
+				       TRIGGER_LEVEL,
+				       SIGNAL_THROUGH);
+		vr41xx_set_irq_level(GD82559_1_PIN, LEVEL_LOW);
+		irq = GD82559_1_IRQ;
+		break;
+	case 13:
+		vr41xx_set_irq_trigger(GD82559_2_PIN,
+				       TRIGGER_LEVEL,
+				       SIGNAL_THROUGH);
+		vr41xx_set_irq_level(GD82559_2_PIN, LEVEL_LOW);
+		irq = GD82559_2_IRQ;
+		break;
+	case 14:
+		switch (pin) {
+		case 1:
+			vr41xx_set_irq_trigger(UPD720100_INTA_PIN,
+					       TRIGGER_LEVEL,
+					       SIGNAL_THROUGH);
+			vr41xx_set_irq_level(UPD720100_INTA_PIN,
+					     LEVEL_LOW);
+			irq = UPD720100_INTA_IRQ;
+			break;
+		case 2:
+			vr41xx_set_irq_trigger(UPD720100_INTB_PIN,
+					       TRIGGER_LEVEL,
+					       SIGNAL_THROUGH);
+			vr41xx_set_irq_level(UPD720100_INTB_PIN,
+					     LEVEL_LOW);
+			irq = UPD720100_INTB_IRQ;
+			break;
+		case 3:
+			vr41xx_set_irq_trigger(UPD720100_INTC_PIN,
+					       TRIGGER_LEVEL,
+					       SIGNAL_THROUGH);
+			vr41xx_set_irq_level(UPD720100_INTC_PIN,
+					     LEVEL_LOW);
+			irq = UPD720100_INTC_IRQ;
+			break;
+		default:
+			break;
+		}
+		break;
+	default:
+		break;
+	}
+
+	return irq;
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
diff --git a/arch/mips/pci/fixup-vr4133.c b/arch/mips/pci/fixup-vr4133.c
new file mode 100644
index 0000000..03a0ff2
--- /dev/null
+++ b/arch/mips/pci/fixup-vr4133.c
@@ -0,0 +1,204 @@
+/*
+ * arch/mips/vr41xx/nec-cmbvr4133/pci_fixup.c
+ *
+ * The NEC CMB-VR4133 Board specific PCI fixups.
+ *
+ * Author: Yoichi Yuasa <yyuasa@mvista.com, or source@mvista.com> and
+ *         Alex Sapkov <asapkov@ru.mvista.com>
+ *
+ * 2003-2004 (c) MontaVista, Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Modified for support in 2.6
+ * Author: Manish Lachwani (mlachwani@mvista.com)
+ *
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/io.h>
+#include <asm/vr41xx/cmbvr4133.h>
+
+extern int vr4133_rockhopper;
+extern void ali_m1535plus_init(struct pci_dev *dev);
+extern void ali_m5229_init(struct pci_dev *dev);
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	/*
+	 * We have to reset AMD PCnet adapter on Rockhopper since
+	 * PMON leaves it enabled and generating interrupts. This leads
+	 * to a lock if some PCI device driver later enables the IRQ line
+	 * shared with PCnet and there is no AMD PCnet driver to catch its
+	 * interrupts.
+	 */
+#ifdef CONFIG_ROCKHOPPER
+	if (dev->vendor == PCI_VENDOR_ID_AMD &&
+		dev->device == PCI_DEVICE_ID_AMD_LANCE) {
+		inl(pci_resource_start(dev, 0) + 0x18);
+	}
+#endif
+
+	/*
+	 * we have to open the bridges' windows down to 0 because otherwise
+ 	 * we cannot access ISA south bridge I/O registers that get mapped from
+	 * 0. for example, 8259 PIC would be unaccessible without that
+	 */
+	if(dev->vendor == PCI_VENDOR_ID_INTEL && dev->device == PCI_DEVICE_ID_INTEL_S21152BB) {
+		pci_write_config_byte(dev, PCI_IO_BASE, 0);
+		if(dev->bus->number == 0) {
+			pci_write_config_word(dev, PCI_IO_BASE_UPPER16, 0);
+		} else {
+			pci_write_config_word(dev, PCI_IO_BASE_UPPER16, 1);
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * M1535 IRQ mapping
+ * Feel free to change this, although it shouldn't be needed
+ */
+#define M1535_IRQ_INTA  7
+#define M1535_IRQ_INTB  9
+#define M1535_IRQ_INTC  10
+#define M1535_IRQ_INTD  11
+
+#define M1535_IRQ_USB   9
+#define M1535_IRQ_IDE   14
+#define M1535_IRQ_IDE2  15
+#define M1535_IRQ_PS2   12
+#define M1535_IRQ_RTC   8
+#define M1535_IRQ_FDC   6
+#define M1535_IRQ_AUDIO 5
+#define M1535_IRQ_COM1  4
+#define M1535_IRQ_COM2  4
+#define M1535_IRQ_IRDA  3
+#define M1535_IRQ_KBD   1
+#define M1535_IRQ_TMR   0
+
+/* Rockhopper "slots" assignment; this is hard-coded ... */
+#define ROCKHOPPER_M5451_SLOT  1
+#define ROCKHOPPER_M1535_SLOT  2
+#define ROCKHOPPER_M5229_SLOT  11
+#define ROCKHOPPER_M5237_SLOT  15
+#define ROCKHOPPER_PMU_SLOT    12
+/* ... and hard-wired. */
+#define ROCKHOPPER_PCI1_SLOT   3
+#define ROCKHOPPER_PCI2_SLOT   4
+#define ROCKHOPPER_PCI3_SLOT   5
+#define ROCKHOPPER_PCI4_SLOT   6
+#define ROCKHOPPER_PCNET_SLOT  1
+
+#define M1535_IRQ_MASK(n) (1 << (n))
+
+#define M1535_IRQ_EDGE  (M1535_IRQ_MASK(M1535_IRQ_TMR)  | \
+                         M1535_IRQ_MASK(M1535_IRQ_KBD)  | \
+                         M1535_IRQ_MASK(M1535_IRQ_COM1) | \
+                         M1535_IRQ_MASK(M1535_IRQ_COM2) | \
+                         M1535_IRQ_MASK(M1535_IRQ_IRDA) | \
+                         M1535_IRQ_MASK(M1535_IRQ_RTC)  | \
+                         M1535_IRQ_MASK(M1535_IRQ_FDC)  | \
+                         M1535_IRQ_MASK(M1535_IRQ_PS2))
+
+#define M1535_IRQ_LEVEL (M1535_IRQ_MASK(M1535_IRQ_IDE)  | \
+                         M1535_IRQ_MASK(M1535_IRQ_USB)  | \
+                         M1535_IRQ_MASK(M1535_IRQ_INTA) | \
+                         M1535_IRQ_MASK(M1535_IRQ_INTB) | \
+                         M1535_IRQ_MASK(M1535_IRQ_INTC) | \
+                         M1535_IRQ_MASK(M1535_IRQ_INTD))
+
+struct irq_map_entry {
+	u16 bus;
+	u8 slot;
+	u8 irq;
+};
+static struct irq_map_entry int_map[] = {
+	{1, ROCKHOPPER_M5451_SLOT, M1535_IRQ_AUDIO},	/* Audio controller */
+	{1, ROCKHOPPER_PCI1_SLOT, M1535_IRQ_INTD},	/* PCI slot #1 */
+	{1, ROCKHOPPER_PCI2_SLOT, M1535_IRQ_INTC},	/* PCI slot #2 */
+	{1, ROCKHOPPER_M5237_SLOT, M1535_IRQ_USB},	/* USB host controller */
+	{1, ROCKHOPPER_M5229_SLOT, IDE_PRIMARY_IRQ},	/* IDE controller */
+	{2, ROCKHOPPER_PCNET_SLOT, M1535_IRQ_INTD},	/* AMD Am79c973 on-board
+							   ethernet */
+	{2, ROCKHOPPER_PCI3_SLOT, M1535_IRQ_INTB},	/* PCI slot #3 */
+	{2, ROCKHOPPER_PCI4_SLOT, M1535_IRQ_INTC}	/* PCI slot #4 */
+};
+
+static int pci_intlines[] =
+    { M1535_IRQ_INTA, M1535_IRQ_INTB, M1535_IRQ_INTC, M1535_IRQ_INTD };
+
+/* Determine the Rockhopper IRQ line number for the PCI device */
+int rockhopper_get_irq(struct pci_dev *dev, u8 pin, u8 slot)
+{
+	struct pci_bus *bus;
+	int i;
+
+	bus = dev->bus;
+	if (bus == NULL)
+		return -1;
+
+	for (i = 0; i < sizeof (int_map) / sizeof (int_map[0]); i++) {
+		if (int_map[i].bus == bus->number && int_map[i].slot == slot) {
+			int line;
+			for (line = 0; line < 4; line++)
+				if (pci_intlines[line] == int_map[i].irq)
+					break;
+			if (line < 4)
+				return pci_intlines[(line + (pin - 1)) % 4];
+			else
+				return int_map[i].irq;
+		}
+	}
+	return -1;
+}
+
+#ifdef CONFIG_ROCKHOPPER
+void i8259_init(void)
+{
+	outb(0x11, 0x20);		/* Master ICW1 */
+	outb(I8259_IRQ_BASE, 0x21);	/* Master ICW2 */
+	outb(0x04, 0x21);		/* Master ICW3 */
+	outb(0x01, 0x21);		/* Master ICW4 */
+	outb(0xff, 0x21);		/* Master IMW */
+
+	outb(0x11, 0xa0);		/* Slave ICW1 */
+	outb(I8259_IRQ_BASE + 8, 0xa1);	/* Slave ICW2 */
+	outb(0x02, 0xa1);		/* Slave ICW3 */
+	outb(0x01, 0xa1);		/* Slave ICW4 */
+	outb(0xff, 0xa1);		/* Slave IMW */
+
+	outb(0x00, 0x4d0);
+	outb(0x02, 0x4d1);	/* USB IRQ9 is level */
+}
+#endif
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	extern int pci_probe_only;
+	pci_probe_only = 1;
+
+#ifdef CONFIG_ROCKHOPPER
+	if( dev->bus->number == 1 && vr4133_rockhopper )  {
+		if(slot == ROCKHOPPER_PCI1_SLOT || slot == ROCKHOPPER_PCI2_SLOT)
+			dev->irq = CMBVR41XX_INTA_IRQ;
+		else
+			dev->irq = rockhopper_get_irq(dev, pin, slot);
+	} else
+		dev->irq = CMBVR41XX_INTA_IRQ;
+#else
+	dev->irq = CMBVR41XX_INTA_IRQ;
+#endif
+
+	return dev->irq;
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, ali_m1535plus_init);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229, ali_m5229_init);
+
+
diff --git a/arch/mips/pci/fixup-yosemite.c b/arch/mips/pci/fixup-yosemite.c
new file mode 100644
index 0000000..81d77a5
--- /dev/null
+++ b/arch/mips/pci/fixup-yosemite.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2003 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	if (pin == 0)
+		return -1;
+
+	return 3;			/* Everything goes to one irq bit */
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
diff --git a/arch/mips/pci/ops-au1000.c b/arch/mips/pci/ops-au1000.c
new file mode 100644
index 0000000..c1c91ca
--- /dev/null
+++ b/arch/mips/pci/ops-au1000.c
@@ -0,0 +1,325 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Alchemy/AMD Au1x00 pci support.
+ *
+ * Copyright 2001,2002,2003 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ *  Support for all devices (greater than 16) added by David Gathright.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/vmalloc.h>
+
+#include <asm/mach-au1x00/au1000.h>
+
+#undef DEBUG
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+#define PCI_ACCESS_READ  0
+#define PCI_ACCESS_WRITE 1
+
+
+int (*board_pci_idsel)(unsigned int devsel, int assert);
+
+/* CP0 hazard avoidance. */
+#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
+				     "nop; nop; nop; nop;\t" \
+				     ".set reorder\n\t")
+
+void mod_wired_entry(int entry, unsigned long entrylo0,
+		unsigned long entrylo1, unsigned long entryhi,
+		unsigned long pagemask)
+{
+	unsigned long old_pagemask;
+	unsigned long old_ctx;
+
+	/* Save old context and create impossible VPN2 value */
+	old_ctx = read_c0_entryhi() & 0xff;
+	old_pagemask = read_c0_pagemask();
+	write_c0_index(entry);
+	BARRIER;
+	write_c0_pagemask(pagemask);
+	write_c0_entryhi(entryhi);
+	write_c0_entrylo0(entrylo0);
+	write_c0_entrylo1(entrylo1);
+	BARRIER;
+	tlb_write_indexed();
+	BARRIER;
+	write_c0_entryhi(old_ctx);
+	BARRIER;
+	write_c0_pagemask(old_pagemask);
+}
+
+struct vm_struct *pci_cfg_vm;
+static int pci_cfg_wired_entry;
+static int first_cfg = 1;
+unsigned long last_entryLo0, last_entryLo1;
+
+static int config_access(unsigned char access_type, struct pci_bus *bus,
+			 unsigned int dev_fn, unsigned char where,
+			 u32 * data)
+{
+#if defined( CONFIG_SOC_AU1500 ) || defined( CONFIG_SOC_AU1550 )
+	unsigned int device = PCI_SLOT(dev_fn);
+	unsigned int function = PCI_FUNC(dev_fn);
+	unsigned long offset, status;
+	unsigned long cfg_base;
+	unsigned long flags;
+	int error = PCIBIOS_SUCCESSFUL;
+	unsigned long entryLo0, entryLo1;
+
+	if (device > 19) {
+		*data = 0xffffffff;
+		return -1;
+	}
+
+	local_irq_save(flags);
+	au_writel(((0x2000 << 16) | (au_readl(Au1500_PCI_STATCMD) & 0xffff)),
+			Au1500_PCI_STATCMD);
+	au_sync_udelay(1);
+
+	/*
+	 * We can't ioremap the entire pci config space because it's
+	 * too large. Nor can we call ioremap dynamically because some
+	 * device drivers use the pci config routines from within
+	 * interrupt handlers and that becomes a problem in get_vm_area().
+	 * We use one wired tlb to handle all config accesses for all
+	 * busses. To improve performance, if the current device
+	 * is the same as the last device accessed, we don't touch the
+	 * tlb.
+	 */
+	if (first_cfg) {
+		/* reserve a wired entry for pci config accesses */
+		first_cfg = 0;
+		pci_cfg_vm = get_vm_area(0x2000, 0);
+		if (!pci_cfg_vm)
+			panic (KERN_ERR "PCI unable to get vm area\n");
+		pci_cfg_wired_entry = read_c0_wired();
+		add_wired_entry(0, 0, (unsigned long)pci_cfg_vm->addr, PM_4K);
+		last_entryLo0  = last_entryLo1 = 0xffffffff;
+	}
+
+	/* Since the Au1xxx doesn't do the idsel timing exactly to spec,
+	 * many board vendors implement their own off-chip idsel, so call
+	 * it now.  If it doesn't succeed, may as well bail out at this point.
+	 */
+	if (board_pci_idsel) {
+		if (board_pci_idsel(device, 1) == 0) {
+			*data = 0xffffffff;
+			local_irq_restore(flags);
+			return -1;
+		}
+	}
+
+        /* setup the config window */
+        if (bus->number == 0) {
+                cfg_base = ((1<<device)<<11);
+        } else {
+                cfg_base = 0x80000000 | (bus->number<<16) | (device<<11);
+        }
+
+        /* setup the lower bits of the 36 bit address */
+        offset = (function << 8) | (where & ~0x3);
+	/* pick up any address that falls below the page mask */
+	offset |= cfg_base & ~PAGE_MASK;
+
+	/* page boundary */
+	cfg_base = cfg_base & PAGE_MASK;
+
+	entryLo0 = (6 << 26)  | (cfg_base >> 6) | (2 << 3) | 7;
+	entryLo1 = (6 << 26)  | (cfg_base >> 6) | (0x1000 >> 6) | (2 << 3) | 7;
+
+	if ((entryLo0 != last_entryLo0) || (entryLo1 != last_entryLo1)) {
+		mod_wired_entry(pci_cfg_wired_entry, entryLo0, entryLo1,
+				(unsigned long)pci_cfg_vm->addr, PM_4K);
+		last_entryLo0 = entryLo0;
+		last_entryLo1 = entryLo1;
+	}
+
+	if (access_type == PCI_ACCESS_WRITE) {
+		au_writel(*data, (int)(pci_cfg_vm->addr + offset));
+	} else {
+		*data = au_readl((int)(pci_cfg_vm->addr + offset));
+	}
+	au_sync_udelay(2);
+
+	DBG("cfg_access %d bus->number %d dev %d at %x *data %x conf %x\n",
+			access_type, bus->number, device, where, *data, offset);
+
+	/* check master abort */
+	status = au_readl(Au1500_PCI_STATCMD);
+
+	if (status & (1<<29)) {
+		*data = 0xffffffff;
+		error = -1;
+		DBG("Au1x Master Abort\n");
+	} else if ((status >> 28) & 0xf) {
+		DBG("PCI ERR detected: status %x\n", status);
+		*data = 0xffffffff;
+		error = -1;
+	}
+
+	/* Take away the idsel.
+	*/
+	if (board_pci_idsel) {
+		(void)board_pci_idsel(device, 0);
+	}
+
+	local_irq_restore(flags);
+	return error;
+#endif
+}
+
+static int read_config_byte(struct pci_bus *bus, unsigned int devfn,
+			    int where, u8 * val)
+{
+	u32 data;
+	int ret;
+
+	ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
+	if (where & 1)
+		data >>= 8;
+	if (where & 2)
+		data >>= 16;
+	*val = data & 0xff;
+	return ret;
+}
+
+
+static int read_config_word(struct pci_bus *bus, unsigned int devfn,
+			    int where, u16 * val)
+{
+	u32 data;
+	int ret;
+
+	ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
+	if (where & 2)
+		data >>= 16;
+	*val = data & 0xffff;
+	return ret;
+}
+
+static int read_config_dword(struct pci_bus *bus, unsigned int devfn,
+			     int where, u32 * val)
+{
+	int ret;
+
+	ret = config_access(PCI_ACCESS_READ, bus, devfn, where, val);
+	return ret;
+}
+
+static int
+write_config_byte(struct pci_bus *bus, unsigned int devfn, int where,
+		  u8 val)
+{
+	u32 data = 0;
+
+	if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
+		return -1;
+
+	data = (data & ~(0xff << ((where & 3) << 3))) |
+	    (val << ((where & 3) << 3));
+
+	if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
+		return -1;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+write_config_word(struct pci_bus *bus, unsigned int devfn, int where,
+		  u16 val)
+{
+	u32 data = 0;
+
+	if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
+		return -1;
+
+	data = (data & ~(0xffff << ((where & 3) << 3))) |
+	    (val << ((where & 3) << 3));
+
+	if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
+		return -1;
+
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+write_config_dword(struct pci_bus *bus, unsigned int devfn, int where,
+		   u32 val)
+{
+	if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val))
+		return -1;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int config_read(struct pci_bus *bus, unsigned int devfn,
+		       int where, int size, u32 * val)
+{
+	switch (size) {
+	case 1: {
+			u8 _val;
+			int rc = read_config_byte(bus, devfn, where, &_val);
+			*val = _val;
+			return rc;
+		}
+       case 2: {
+			u16 _val;
+			int rc = read_config_word(bus, devfn, where, &_val);
+			*val = _val;
+			return rc;
+		}
+	default:
+		return read_config_dword(bus, devfn, where, val);
+	}
+}
+
+static int config_write(struct pci_bus *bus, unsigned int devfn,
+			int where, int size, u32 val)
+{
+	switch (size) {
+	case 1:
+		return write_config_byte(bus, devfn, where, (u8) val);
+	case 2:
+		return write_config_word(bus, devfn, where, (u16) val);
+	default:
+		return write_config_dword(bus, devfn, where, val);
+	}
+}
+
+
+struct pci_ops au1x_pci_ops = {
+	config_read,
+	config_write
+};
diff --git a/arch/mips/pci/ops-bonito64.c b/arch/mips/pci/ops-bonito64.c
new file mode 100644
index 0000000..4b4e086
--- /dev/null
+++ b/arch/mips/pci/ops-bonito64.c
@@ -0,0 +1,196 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999, 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * MIPS boards specific PCI support.
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/mips-boards/bonito64.h>
+
+#define PCI_ACCESS_READ  0
+#define PCI_ACCESS_WRITE 1
+
+/*
+ *  PCI configuration cycle AD bus definition
+ */
+/* Type 0 */
+#define PCI_CFG_TYPE0_REG_SHF           0
+#define PCI_CFG_TYPE0_FUNC_SHF          8
+
+/* Type 1 */
+#define PCI_CFG_TYPE1_REG_SHF           0
+#define PCI_CFG_TYPE1_FUNC_SHF          8
+#define PCI_CFG_TYPE1_DEV_SHF           11
+#define PCI_CFG_TYPE1_BUS_SHF           16
+
+static int bonito64_pcibios_config_access(unsigned char access_type,
+				      struct pci_bus *bus,
+				      unsigned int devfn, int where,
+				      u32 * data)
+{
+	unsigned char busnum = bus->number;
+	u32 dummy;
+	u64 pci_addr;
+
+	/* Algorithmics Bonito64 system controller. */
+
+	if ((busnum == 0) && (PCI_SLOT(devfn) > 21)) {
+		/* We number bus 0 devices from 0..21 */
+		return -1;
+	}
+
+#ifdef CONFIG_MIPS_BOARDS_GEN
+	if ((busnum == 0) && (PCI_SLOT(devfn) == 17)) {
+		/* MIPS Core boards have Bonito connected as device 17 */
+		return -1;
+	}
+#endif
+
+	/* Clear cause register bits */
+	BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR |
+			  BONITO_PCICMD_MTABORT_CLR);
+
+	/*
+	 * Setup pattern to be used as PCI "address" for
+	 * Type 0 cycle
+	 */
+	if (busnum == 0) {
+		/* IDSEL */
+		pci_addr = (u64) 1 << (PCI_SLOT(devfn) + 10);
+	} else {
+		/* Bus number */
+		pci_addr = busnum << PCI_CFG_TYPE1_BUS_SHF;
+
+		/* Device number */
+		pci_addr |=
+		    PCI_SLOT(devfn) << PCI_CFG_TYPE1_DEV_SHF;
+	}
+
+	/* Function (same for Type 0/1) */
+	pci_addr |= PCI_FUNC(devfn) << PCI_CFG_TYPE0_FUNC_SHF;
+
+	/* Register number (same for Type 0/1) */
+	pci_addr |= (where & ~0x3) << PCI_CFG_TYPE0_REG_SHF;
+
+	if (busnum == 0) {
+		/* Type 0 */
+		BONITO_PCIMAP_CFG = pci_addr >> 16;
+	} else {
+		/* Type 1 */
+		BONITO_PCIMAP_CFG = (pci_addr >> 16) | 0x10000;
+	}
+
+	pci_addr &= 0xffff;
+
+	/* Flush Bonito register block */
+	dummy = BONITO_PCIMAP_CFG;
+	iob();		/* sync */
+
+	/* Perform access */
+	if (access_type == PCI_ACCESS_WRITE) {
+		*(volatile u32 *) (_pcictrl_bonito_pcicfg + (u32)pci_addr) = *(u32 *) data;
+
+		/* Wait till done */
+		while (BONITO_PCIMSTAT & 0xF);
+	} else {
+		*(u32 *) data = *(volatile u32 *) (_pcictrl_bonito_pcicfg + (u32)pci_addr);
+	}
+
+	/* Detect Master/Target abort */
+	if (BONITO_PCICMD & (BONITO_PCICMD_MABORT_CLR |
+			     BONITO_PCICMD_MTABORT_CLR)) {
+		/* Error occurred */
+
+		/* Clear bits */
+		BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR |
+				  BONITO_PCICMD_MTABORT_CLR);
+
+		return -1;
+	}
+
+	return 0;
+}
+
+
+/*
+ * We can't address 8 and 16 bit words directly.  Instead we have to
+ * read/write a 32bit word and mask/modify the data we actually want.
+ */
+static int bonito64_pcibios_read(struct pci_bus *bus, unsigned int devfn,
+			     int where, int size, u32 * val)
+{
+	u32 data = 0;
+
+	if ((size == 2) && (where & 1))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	else if ((size == 4) && (where & 3))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (bonito64_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
+				       &data))
+		return -1;
+
+	if (size == 1)
+		*val = (data >> ((where & 3) << 3)) & 0xff;
+	else if (size == 2)
+		*val = (data >> ((where & 3) << 3)) & 0xffff;
+	else
+		*val = data;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int bonito64_pcibios_write(struct pci_bus *bus, unsigned int devfn,
+			      int where, int size, u32 val)
+{
+	u32 data = 0;
+
+	if ((size == 2) && (where & 1))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	else if ((size == 4) && (where & 3))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (size == 4)
+		data = val;
+	else {
+		if (bonito64_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
+		                               where, &data))
+			return -1;
+
+		if (size == 1)
+			data = (data & ~(0xff << ((where & 3) << 3))) |
+				(val << ((where & 3) << 3));
+		else if (size == 2)
+			data = (data & ~(0xffff << ((where & 3) << 3))) |
+				(val << ((where & 3) << 3));
+	}
+
+	if (bonito64_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, where,
+				       &data))
+		return -1;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops bonito64_pci_ops = {
+	.read = bonito64_pcibios_read,
+	.write = bonito64_pcibios_write
+};
diff --git a/arch/mips/pci/ops-ddb5074.c b/arch/mips/pci/ops-ddb5074.c
new file mode 100644
index 0000000..89f97bef4
--- /dev/null
+++ b/arch/mips/pci/ops-ddb5074.c
@@ -0,0 +1,271 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/ddb5xxx/ddb5476/pci_ops.c
+ *     Define the pci_ops for DB5477.
+ *
+ * Much of the code is derived from the original DDB5074 port by
+ * Geert Uytterhoeven <geert@sonycom.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/debug.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+/*
+ * config_swap structure records what set of pdar/pmr are used
+ * to access pci config space.  It also provides a place hold the
+ * original values for future restoring.
+ */
+struct pci_config_swap {
+	u32 pdar;
+	u32 pmr;
+	u32 config_base;
+	u32 config_size;
+	u32 pdar_backup;
+	u32 pmr_backup;
+};
+
+/*
+ * On DDB5476, we have one set of swap registers
+ */
+struct pci_config_swap ext_pci_swap = {
+	DDB_PCIW0,
+	DDB_PCIINIT0,
+	DDB_PCI_CONFIG_BASE,
+	DDB_PCI_CONFIG_SIZE
+};
+
+static int pci_config_workaround = 1;
+
+/*
+ * access config space
+ */
+static inline u32 ddb_access_config_base(struct pci_config_swap *swap, u32 bus,	/* 0 means top level bus */
+					 u32 slot_num)
+{
+	u32 pci_addr = 0;
+	u32 pciinit_offset = 0;
+	u32 virt_addr = swap->config_base;
+	u32 option;
+
+	if (pci_config_workaround) {
+		if (slot_num == 5)
+			slot_num = 14;
+	} else {
+		if (slot_num == 5)
+			return DDB_BASE + DDB_PCI_BASE;
+	}
+
+	/* minimum pdar (window) size is 2MB */
+	db_assert(swap->config_size >= (2 << 20));
+
+	db_assert(slot_num < (1 << 5));
+	db_assert(bus < (1 << 8));
+
+	/* backup registers */
+	swap->pdar_backup = ddb_in32(swap->pdar);
+	swap->pmr_backup = ddb_in32(swap->pmr);
+
+	/* set the pdar (pci window) register */
+	ddb_set_pdar(swap->pdar, swap->config_base, swap->config_size, 32,	/* 32 bit wide */
+		     0,		/* not on local memory bus */
+		     0);	/* not visible from PCI bus (N/A) */
+
+	/*
+	 * calcuate the absolute pci config addr;
+	 * according to the spec, we start scanning from adr:11 (0x800)
+	 */
+	if (bus == 0) {
+		/* type 0 config */
+		pci_addr = 0x00040000 << slot_num;
+	} else {
+		/* type 1 config */
+		pci_addr = 0x00040000 << slot_num;
+		panic
+		    ("ddb_access_config_base: we don't support type 1 config Yet");
+	}
+
+	/*
+	 * if pci_addr is less than pci config window size,  we set
+	 * pciinit_offset to 0 and adjust the virt_address.
+	 * Otherwise we will try to adjust pciinit_offset.
+	 */
+	if (pci_addr < swap->config_size) {
+		virt_addr = KSEG1ADDR(swap->config_base + pci_addr);
+		pciinit_offset = 0;
+	} else {
+		db_assert((pci_addr & (swap->config_size - 1)) == 0);
+		virt_addr = KSEG1ADDR(swap->config_base);
+		pciinit_offset = pci_addr;
+	}
+
+	/* set the pmr register */
+	option = DDB_PCI_ACCESS_32;
+	if (bus != 0)
+		option |= DDB_PCI_CFGTYPE1;
+	ddb_set_pmr(swap->pmr, DDB_PCICMD_CFG, pciinit_offset, option);
+
+	return virt_addr;
+}
+
+static inline void ddb_close_config_base(struct pci_config_swap *swap)
+{
+	ddb_out32(swap->pdar, swap->pdar_backup);
+	ddb_out32(swap->pmr, swap->pmr_backup);
+}
+
+static int read_config_dword(struct pci_config_swap *swap,
+			     struct pci_dev *dev, u32 where, u32 * val)
+{
+	u32 bus, slot_num, func_num;
+	u32 base;
+
+	db_assert((where & 3) == 0);
+	db_assert(where < (1 << 8));
+
+	/* check if the bus is top-level */
+	if (dev->bus->parent != NULL) {
+		bus = dev->bus->number;
+		db_assert(bus != 0);
+	} else {
+		bus = 0;
+	}
+
+	slot_num = PCI_SLOT(dev->devfn);
+	func_num = PCI_FUNC(dev->devfn);
+	base = ddb_access_config_base(swap, bus, slot_num);
+	*val = *(volatile u32 *) (base + (func_num << 8) + where);
+	ddb_close_config_base(swap);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int read_config_word(struct pci_config_swap *swap,
+			    struct pci_dev *dev, u32 where, u16 * val)
+{
+	int status;
+	u32 result;
+
+	db_assert((where & 1) == 0);
+
+	status = read_config_dword(swap, dev, where & ~3, &result);
+	if (where & 2)
+		result >>= 16;
+	*val = result & 0xffff;
+	return status;
+}
+
+static int read_config_byte(struct pci_config_swap *swap,
+			    struct pci_dev *dev, u32 where, u8 * val)
+{
+	int status;
+	u32 result;
+
+	status = read_config_dword(swap, dev, where & ~3, &result);
+	if (where & 1)
+		result >>= 8;
+	if (where & 2)
+		result >>= 16;
+	*val = result & 0xff;
+	return status;
+}
+
+static int write_config_dword(struct pci_config_swap *swap,
+			      struct pci_dev *dev, u32 where, u32 val)
+{
+	u32 bus, slot_num, func_num;
+	u32 base;
+
+	db_assert((where & 3) == 0);
+	db_assert(where < (1 << 8));
+
+	/* check if the bus is top-level */
+	if (dev->bus->parent != NULL) {
+		bus = dev->bus->number;
+		db_assert(bus != 0);
+	} else {
+		bus = 0;
+	}
+
+	slot_num = PCI_SLOT(dev->devfn);
+	func_num = PCI_FUNC(dev->devfn);
+	base = ddb_access_config_base(swap, bus, slot_num);
+	*(volatile u32 *) (base + (func_num << 8) + where) = val;
+	ddb_close_config_base(swap);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int write_config_word(struct pci_config_swap *swap,
+			     struct pci_dev *dev, u32 where, u16 val)
+{
+	int status, shift = 0;
+	u32 result;
+
+	db_assert((where & 1) == 0);
+
+	status = read_config_dword(swap, dev, where & ~3, &result);
+	if (status != PCIBIOS_SUCCESSFUL)
+		return status;
+
+	if (where & 2)
+		shift += 16;
+	result &= ~(0xffff << shift);
+	result |= val << shift;
+	return write_config_dword(swap, dev, where & ~3, result);
+}
+
+static int write_config_byte(struct pci_config_swap *swap,
+			     struct pci_dev *dev, u32 where, u8 val)
+{
+	int status, shift = 0;
+	u32 result;
+
+	status = read_config_dword(swap, dev, where & ~3, &result);
+	if (status != PCIBIOS_SUCCESSFUL)
+		return status;
+
+	if (where & 2)
+		shift += 16;
+	if (where & 1)
+		shift += 8;
+	result &= ~(0xff << shift);
+	result |= val << shift;
+	return write_config_dword(swap, dev, where & ~3, result);
+}
+
+#define	MAKE_PCI_OPS(prefix, rw, unitname, unittype, pciswap) \
+static int prefix##_##rw##_config_##unitname(struct pci_dev *dev, int where, unittype val) \
+{ \
+     return rw##_config_##unitname(pciswap, \
+                                   dev, \
+                                   where, \
+                                   val); \
+}
+
+MAKE_PCI_OPS(extpci, read, byte, u8 *, &ext_pci_swap)
+    MAKE_PCI_OPS(extpci, read, word, u16 *, &ext_pci_swap)
+    MAKE_PCI_OPS(extpci, read, dword, u32 *, &ext_pci_swap)
+
+    MAKE_PCI_OPS(extpci, write, byte, u8, &ext_pci_swap)
+    MAKE_PCI_OPS(extpci, write, word, u16, &ext_pci_swap)
+    MAKE_PCI_OPS(extpci, write, dword, u32, &ext_pci_swap)
+
+struct pci_ops ddb5476_ext_pci_ops = {
+	extpci_read_config_byte,
+	extpci_read_config_word,
+	extpci_read_config_dword,
+	extpci_write_config_byte,
+	extpci_write_config_word,
+	extpci_write_config_dword
+};
diff --git a/arch/mips/pci/ops-ddb5476.c b/arch/mips/pci/ops-ddb5476.c
new file mode 100644
index 0000000..12da58e
--- /dev/null
+++ b/arch/mips/pci/ops-ddb5476.c
@@ -0,0 +1,286 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/ddb5xxx/ddb5476/pci_ops.c
+ *     Define the pci_ops for DB5477.
+ *
+ * Much of the code is derived from the original DDB5074 port by
+ * Geert Uytterhoeven <geert@sonycom.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/debug.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+/*
+ * config_swap structure records what set of pdar/pmr are used
+ * to access pci config space.  It also provides a place hold the
+ * original values for future restoring.
+ */
+struct pci_config_swap {
+	u32 pdar;
+	u32 pmr;
+	u32 config_base;
+	u32 config_size;
+	u32 pdar_backup;
+	u32 pmr_backup;
+};
+
+/*
+ * On DDB5476, we have one set of swap registers
+ */
+struct pci_config_swap ext_pci_swap = {
+	DDB_PCIW0,
+	DDB_PCIINIT0,
+	DDB_PCI_CONFIG_BASE,
+	DDB_PCI_CONFIG_SIZE
+};
+
+static int pci_config_workaround = 1;
+
+/*
+ * access config space
+ */
+static inline u32 ddb_access_config_base(struct pci_config_swap *swap, u32 bus,	/* 0 means top level bus */
+					 u32 slot_num)
+{
+	u32 pci_addr = 0;
+	u32 pciinit_offset = 0;
+	u32 virt_addr = swap->config_base;
+	u32 option;
+
+	if (pci_config_workaround) {
+		/* [jsun] work around Vrc5476 controller itself, returnning
+		 * slot 0 essentially makes vrc5476 invisible
+		 */
+		if (slot_num == 12)
+			slot_num = 0;
+
+#if 0
+		/* BUG : skip P2P bridge for now */
+		if (slot_num == 5)
+			slot_num = 0;
+#endif
+
+	} else {
+		/* now we have to be hornest, returning the true
+		 * PCI config headers for vrc5476
+		 */
+		if (slot_num == 12) {
+			swap->pdar_backup = ddb_in32(swap->pdar);
+			swap->pmr_backup = ddb_in32(swap->pmr);
+			return DDB_BASE + DDB_PCI_BASE;
+		}
+	}
+
+	/* minimum pdar (window) size is 2MB */
+	db_assert(swap->config_size >= (2 << 20));
+
+	db_assert(slot_num < (1 << 5));
+	db_assert(bus < (1 << 8));
+
+	/* backup registers */
+	swap->pdar_backup = ddb_in32(swap->pdar);
+	swap->pmr_backup = ddb_in32(swap->pmr);
+
+	/* set the pdar (pci window) register */
+	ddb_set_pdar(swap->pdar, swap->config_base, swap->config_size, 32,	/* 32 bit wide */
+		     0,		/* not on local memory bus */
+		     0);	/* not visible from PCI bus (N/A) */
+
+	/*
+	 * calcuate the absolute pci config addr;
+	 * according to the spec, we start scanning from adr:11 (0x800)
+	 */
+	if (bus == 0) {
+		/* type 0 config */
+		pci_addr = 0x800 << slot_num;
+	} else {
+		/* type 1 config */
+		pci_addr = (bus << 16) | (slot_num << 11);
+		/* panic("ddb_access_config_base: we don't support type 1 config Yet"); */
+	}
+
+	/*
+	 * if pci_addr is less than pci config window size,  we set
+	 * pciinit_offset to 0 and adjust the virt_address.
+	 * Otherwise we will try to adjust pciinit_offset.
+	 */
+	if (pci_addr < swap->config_size) {
+		virt_addr = KSEG1ADDR(swap->config_base + pci_addr);
+		pciinit_offset = 0;
+	} else {
+		db_assert((pci_addr & (swap->config_size - 1)) == 0);
+		virt_addr = KSEG1ADDR(swap->config_base);
+		pciinit_offset = pci_addr;
+	}
+
+	/* set the pmr register */
+	option = DDB_PCI_ACCESS_32;
+	if (bus != 0)
+		option |= DDB_PCI_CFGTYPE1;
+	ddb_set_pmr(swap->pmr, DDB_PCICMD_CFG, pciinit_offset, option);
+
+	return virt_addr;
+}
+
+static inline void ddb_close_config_base(struct pci_config_swap *swap)
+{
+	ddb_out32(swap->pdar, swap->pdar_backup);
+	ddb_out32(swap->pmr, swap->pmr_backup);
+}
+
+static int read_config_dword(struct pci_config_swap *swap,
+			     struct pci_dev *dev, u32 where, u32 * val)
+{
+	u32 bus, slot_num, func_num;
+	u32 base;
+
+	db_assert((where & 3) == 0);
+	db_assert(where < (1 << 8));
+
+	/* check if the bus is top-level */
+	if (dev->bus->parent != NULL) {
+		bus = dev->bus->number;
+		db_assert(bus != 0);
+	} else {
+		bus = 0;
+	}
+
+	slot_num = PCI_SLOT(dev->devfn);
+	func_num = PCI_FUNC(dev->devfn);
+	base = ddb_access_config_base(swap, bus, slot_num);
+	*val = *(volatile u32 *) (base + (func_num << 8) + where);
+	ddb_close_config_base(swap);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int read_config_word(struct pci_config_swap *swap,
+			    struct pci_dev *dev, u32 where, u16 * val)
+{
+	int status;
+	u32 result;
+
+	db_assert((where & 1) == 0);
+
+	status = read_config_dword(swap, dev, where & ~3, &result);
+	if (where & 2)
+		result >>= 16;
+	*val = result & 0xffff;
+	return status;
+}
+
+static int read_config_byte(struct pci_config_swap *swap,
+			    struct pci_dev *dev, u32 where, u8 * val)
+{
+	int status;
+	u32 result;
+
+	status = read_config_dword(swap, dev, where & ~3, &result);
+	if (where & 1)
+		result >>= 8;
+	if (where & 2)
+		result >>= 16;
+	*val = result & 0xff;
+	return status;
+}
+
+static int write_config_dword(struct pci_config_swap *swap,
+			      struct pci_dev *dev, u32 where, u32 val)
+{
+	u32 bus, slot_num, func_num;
+	u32 base;
+
+	db_assert((where & 3) == 0);
+	db_assert(where < (1 << 8));
+
+	/* check if the bus is top-level */
+	if (dev->bus->parent != NULL) {
+		bus = dev->bus->number;
+		db_assert(bus != 0);
+	} else {
+		bus = 0;
+	}
+
+	slot_num = PCI_SLOT(dev->devfn);
+	func_num = PCI_FUNC(dev->devfn);
+	base = ddb_access_config_base(swap, bus, slot_num);
+	*(volatile u32 *) (base + (func_num << 8) + where) = val;
+	ddb_close_config_base(swap);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int write_config_word(struct pci_config_swap *swap,
+			     struct pci_dev *dev, u32 where, u16 val)
+{
+	int status, shift = 0;
+	u32 result;
+
+	db_assert((where & 1) == 0);
+
+	status = read_config_dword(swap, dev, where & ~3, &result);
+	if (status != PCIBIOS_SUCCESSFUL)
+		return status;
+
+	if (where & 2)
+		shift += 16;
+	result &= ~(0xffff << shift);
+	result |= val << shift;
+	return write_config_dword(swap, dev, where & ~3, result);
+}
+
+static int write_config_byte(struct pci_config_swap *swap,
+			     struct pci_dev *dev, u32 where, u8 val)
+{
+	int status, shift = 0;
+	u32 result;
+
+	status = read_config_dword(swap, dev, where & ~3, &result);
+	if (status != PCIBIOS_SUCCESSFUL)
+		return status;
+
+	if (where & 2)
+		shift += 16;
+	if (where & 1)
+		shift += 8;
+	result &= ~(0xff << shift);
+	result |= val << shift;
+	return write_config_dword(swap, dev, where & ~3, result);
+}
+
+#define	MAKE_PCI_OPS(prefix, rw, unitname, unittype, pciswap) \
+static int prefix##_##rw##_config_##unitname(struct pci_dev *dev, int where, unittype val) \
+{ \
+     return rw##_config_##unitname(pciswap, \
+                                   dev, \
+                                   where, \
+                                   val); \
+}
+
+MAKE_PCI_OPS(extpci, read, byte, u8 *, &ext_pci_swap)
+    MAKE_PCI_OPS(extpci, read, word, u16 *, &ext_pci_swap)
+    MAKE_PCI_OPS(extpci, read, dword, u32 *, &ext_pci_swap)
+
+    MAKE_PCI_OPS(extpci, write, byte, u8, &ext_pci_swap)
+    MAKE_PCI_OPS(extpci, write, word, u16, &ext_pci_swap)
+    MAKE_PCI_OPS(extpci, write, dword, u32, &ext_pci_swap)
+
+struct pci_ops ddb5476_ext_pci_ops = {
+	extpci_read_config_byte,
+	extpci_read_config_word,
+	extpci_read_config_dword,
+	extpci_write_config_byte,
+	extpci_write_config_word,
+	extpci_write_config_dword
+};
diff --git a/arch/mips/pci/ops-ddb5477.c b/arch/mips/pci/ops-ddb5477.c
new file mode 100644
index 0000000..e955443
--- /dev/null
+++ b/arch/mips/pci/ops-ddb5477.c
@@ -0,0 +1,278 @@
+/***********************************************************************
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/ddb5xxx/ddb5477/pci_ops.c
+ *     Define the pci_ops for DB5477.
+ *
+ * Much of the code is derived from the original DDB5074 port by
+ * Geert Uytterhoeven <geert@sonycom.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ ***********************************************************************
+ */
+
+/*
+ * DDB5477 has two PCI channels, external PCI and IOPIC (internal)
+ * Therefore we provide two sets of pci_ops.
+ */
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/debug.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+/*
+ * config_swap structure records what set of pdar/pmr are used
+ * to access pci config space.  It also provides a place hold the
+ * original values for future restoring.
+ */
+struct pci_config_swap {
+	u32 pdar;
+	u32 pmr;
+	u32 config_base;
+	u32 config_size;
+	u32 pdar_backup;
+	u32 pmr_backup;
+};
+
+/*
+ * On DDB5477, we have two sets of swap registers, for ext PCI and IOPCI.
+ */
+struct pci_config_swap ext_pci_swap = {
+	DDB_PCIW0,
+	DDB_PCIINIT00,
+	DDB_PCI0_CONFIG_BASE,
+	DDB_PCI0_CONFIG_SIZE
+};
+struct pci_config_swap io_pci_swap = {
+	DDB_IOPCIW0,
+	DDB_PCIINIT01,
+	DDB_PCI1_CONFIG_BASE,
+	DDB_PCI1_CONFIG_SIZE
+};
+
+
+/*
+ * access config space
+ */
+static inline u32 ddb_access_config_base(struct pci_config_swap *swap, u32 bus,	/* 0 means top level bus */
+					 u32 slot_num)
+{
+	u32 pci_addr = 0;
+	u32 pciinit_offset = 0;
+	u32 virt_addr;
+	u32 option;
+
+	/* minimum pdar (window) size is 2MB */
+	db_assert(swap->config_size >= (2 << 20));
+
+	db_assert(slot_num < (1 << 5));
+	db_assert(bus < (1 << 8));
+
+	/* backup registers */
+	swap->pdar_backup = ddb_in32(swap->pdar);
+	swap->pmr_backup = ddb_in32(swap->pmr);
+
+	/* set the pdar (pci window) register */
+	ddb_set_pdar(swap->pdar, swap->config_base, swap->config_size, 32,	/* 32 bit wide */
+		     0,		/* not on local memory bus */
+		     0);	/* not visible from PCI bus (N/A) */
+
+	/*
+	 * calcuate the absolute pci config addr;
+	 * according to the spec, we start scanning from adr:11 (0x800)
+	 */
+	if (bus == 0) {
+		/* type 0 config */
+		pci_addr = 0x800 << slot_num;
+	} else {
+		/* type 1 config */
+		pci_addr = (bus << 16) | (slot_num << 11);
+	}
+
+	/*
+	 * if pci_addr is less than pci config window size,  we set
+	 * pciinit_offset to 0 and adjust the virt_address.
+	 * Otherwise we will try to adjust pciinit_offset.
+	 */
+	if (pci_addr < swap->config_size) {
+		virt_addr = KSEG1ADDR(swap->config_base + pci_addr);
+		pciinit_offset = 0;
+	} else {
+		db_assert((pci_addr & (swap->config_size - 1)) == 0);
+		virt_addr = KSEG1ADDR(swap->config_base);
+		pciinit_offset = pci_addr;
+	}
+
+	/* set the pmr register */
+	option = DDB_PCI_ACCESS_32;
+	if (bus != 0)
+		option |= DDB_PCI_CFGTYPE1;
+	ddb_set_pmr(swap->pmr, DDB_PCICMD_CFG, pciinit_offset, option);
+
+	return virt_addr;
+}
+
+static inline void ddb_close_config_base(struct pci_config_swap *swap)
+{
+	ddb_out32(swap->pdar, swap->pdar_backup);
+	ddb_out32(swap->pmr, swap->pmr_backup);
+}
+
+static int read_config_dword(struct pci_config_swap *swap,
+			     struct pci_bus *bus, u32 devfn, u32 where, 
+			     u32 * val)
+{
+	u32 bus_num, slot_num, func_num;
+	u32 base;
+
+	db_assert((where & 3) == 0);
+	db_assert(where < (1 << 8));
+
+	/* check if the bus is top-level */
+	if (bus->parent != NULL) {
+		bus_num = bus->number;
+		db_assert(bus_num != 0);
+	} else {
+		bus_num = 0;
+	}
+
+	slot_num = PCI_SLOT(devfn);
+	func_num = PCI_FUNC(devfn);
+	base = ddb_access_config_base(swap, bus_num, slot_num);
+	*val = *(volatile u32 *) (base + (func_num << 8) + where);
+	ddb_close_config_base(swap);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int read_config_word(struct pci_config_swap *swap,
+			    struct pci_bus *bus, u32 devfn, u32 where, 
+			    u16 * val)
+{
+	int status;
+	u32 result;
+
+	db_assert((where & 1) == 0);
+
+	status = read_config_dword(swap, bus, devfn, where & ~3, &result);
+	if (where & 2)
+		result >>= 16;
+	*val = result & 0xffff;
+	return status;
+}
+
+static int read_config_byte(struct pci_config_swap *swap,
+			    struct pci_bus *bus, u32 devfn, u32 where,
+			    u8 * val)
+{
+	int status;
+	u32 result;
+
+	status = read_config_dword(swap, bus, devfn, where & ~3, &result);
+	if (where & 1)
+		result >>= 8;
+	if (where & 2)
+		result >>= 16;
+	*val = result & 0xff;
+
+	return status;
+}
+
+static int write_config_dword(struct pci_config_swap *swap,
+			      struct pci_bus *bus, u32 devfn, u32 where,
+			      u32 val)
+{
+	u32 bus_num, slot_num, func_num;
+	u32 base;
+
+	db_assert((where & 3) == 0);
+	db_assert(where < (1 << 8));
+
+	/* check if the bus is top-level */
+	if (bus->parent != NULL) {
+		bus_num = bus->number;
+		db_assert(bus_num != 0);
+	} else {
+		bus_num = 0;
+	}
+
+	slot_num = PCI_SLOT(devfn);
+	func_num = PCI_FUNC(devfn);
+	base = ddb_access_config_base(swap, bus_num, slot_num);
+	*(volatile u32 *) (base + (func_num << 8) + where) = val;
+	ddb_close_config_base(swap);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int write_config_word(struct pci_config_swap *swap,
+			     struct pci_bus *bus, u32 devfn, u32 where, u16 val)
+{
+	int status, shift = 0;
+	u32 result;
+
+	db_assert((where & 1) == 0);
+
+	status = read_config_dword(swap, bus, devfn, where & ~3, &result);
+	if (status != PCIBIOS_SUCCESSFUL)
+		return status;
+
+	if (where & 2)
+		shift += 16;
+	result &= ~(0xffff << shift);
+	result |= val << shift;
+	return write_config_dword(swap, bus, devfn, where & ~3, result);
+}
+
+static int write_config_byte(struct pci_config_swap *swap,
+			     struct pci_bus *bus, u32 devfn, u32 where, u8 val)
+{
+	int status, shift = 0;
+	u32 result;
+
+	status = read_config_dword(swap, bus, devfn, where & ~3, &result);
+	if (status != PCIBIOS_SUCCESSFUL)
+		return status;
+
+	if (where & 2)
+		shift += 16;
+	if (where & 1)
+		shift += 8;
+	result &= ~(0xff << shift);
+	result |= val << shift;
+	return write_config_dword(swap, bus, devfn, where & ~3, result);
+}
+
+#define        MAKE_PCI_OPS(prefix, rw, pciswap, star) \
+static int prefix##_##rw##_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 star val) \
+{ \
+	if (size == 1) \
+     		return rw##_config_byte(pciswap, bus, devfn, where, (u8 star)val); \
+	else if (size == 2) \
+     		return rw##_config_word(pciswap, bus, devfn, where, (u16 star)val); \
+	/* Size must be 4 */ \
+     	return rw##_config_dword(pciswap, bus, devfn, where, val); \
+}
+
+MAKE_PCI_OPS(extpci, read, &ext_pci_swap, *)
+MAKE_PCI_OPS(extpci, write, &ext_pci_swap,)
+
+MAKE_PCI_OPS(iopci, read, &io_pci_swap, *)
+MAKE_PCI_OPS(iopci, write, &io_pci_swap,)
+
+struct pci_ops ddb5477_ext_pci_ops = {
+	.read = extpci_read_config,
+	.write = extpci_write_config
+};
+
+
+struct pci_ops ddb5477_io_pci_ops = {
+	.read = iopci_read_config,
+	.write = iopci_write_config
+};
diff --git a/arch/mips/pci/ops-gt64111.c b/arch/mips/pci/ops-gt64111.c
new file mode 100644
index 0000000..c5b0fc1
--- /dev/null
+++ b/arch/mips/pci/ops-gt64111.c
@@ -0,0 +1,100 @@
+/*
+ * 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, 1996, 1997, 2002 by Ralf Baechle
+ * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv)
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/pci.h>
+#include <asm/io.h>
+#include <asm/gt64120.h>
+
+#include <asm/cobalt/cobalt.h>
+
+/*
+ * Accessing device 31 hangs the GT64120.  Not sure if this will also hang
+ * the GT64111, let's be paranoid for now.
+ */
+static inline int pci_range_ck(struct pci_bus *bus, unsigned int devfn)
+{
+	if (bus->number == 0 && devfn == PCI_DEVFN(31, 0))
+		return -1;
+
+	return 0;
+}
+
+static int gt64111_pci_read_config(struct pci_bus *bus, unsigned int devfn,
+	int where, int size, u32 * val)
+{
+	if (pci_range_ck(bus, devfn))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	switch (size) {
+	case 4:
+		PCI_CFG_SET(devfn, where);
+		*val = GALILEO_INL(GT_PCI0_CFGDATA_OFS);
+		return PCIBIOS_SUCCESSFUL;
+
+	case 2:
+		PCI_CFG_SET(devfn, (where & ~0x3));
+		*val = GALILEO_INL(GT_PCI0_CFGDATA_OFS)
+		    >> ((where & 3) * 8);
+		return PCIBIOS_SUCCESSFUL;
+
+	case 1:
+		PCI_CFG_SET(devfn, (where & ~0x3));
+		*val = GALILEO_INL(GT_PCI0_CFGDATA_OFS)
+		    >> ((where & 3) * 8);
+		return PCIBIOS_SUCCESSFUL;
+	}
+
+	return PCIBIOS_BAD_REGISTER_NUMBER;
+}
+
+static int gt64111_pci_write_config(struct pci_bus *bus, unsigned int devfn,
+	int where, int size, u32 val)
+{
+	u32 tmp;
+
+	if (pci_range_ck(bus, devfn))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	switch (size) {
+	case 4:
+		PCI_CFG_SET(devfn, where);
+		GALILEO_OUTL(val, GT_PCI0_CFGDATA_OFS);
+
+		return PCIBIOS_SUCCESSFUL;
+
+	case 2:
+		PCI_CFG_SET(devfn, (where & ~0x3));
+		tmp = GALILEO_INL(GT_PCI0_CFGDATA_OFS);
+		tmp &= ~(0xffff << ((where & 0x3) * 8));
+		tmp |= (val << ((where & 0x3) * 8));
+		GALILEO_OUTL(tmp, GT_PCI0_CFGDATA_OFS);
+
+		return PCIBIOS_SUCCESSFUL;
+
+	case 1:
+		PCI_CFG_SET(devfn, (where & ~0x3));
+		tmp = GALILEO_INL(GT_PCI0_CFGDATA_OFS);
+		tmp &= ~(0xff << ((where & 0x3) * 8));
+		tmp |= (val << ((where & 0x3) * 8));
+		GALILEO_OUTL(tmp, GT_PCI0_CFGDATA_OFS);
+
+		return PCIBIOS_SUCCESSFUL;
+	}
+
+	return PCIBIOS_BAD_REGISTER_NUMBER;
+}
+
+struct pci_ops gt64111_pci_ops = {
+	.read = gt64111_pci_read_config,
+	.write = gt64111_pci_write_config,
+};
diff --git a/arch/mips/pci/ops-gt64120.c b/arch/mips/pci/ops-gt64120.c
new file mode 100644
index 0000000..7b99dfa
--- /dev/null
+++ b/arch/mips/pci/ops-gt64120.c
@@ -0,0 +1,154 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999, 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+
+#include <asm/gt64120.h>
+
+#define PCI_ACCESS_READ  0
+#define PCI_ACCESS_WRITE 1
+
+/*
+ *  PCI configuration cycle AD bus definition
+ */
+/* Type 0 */
+#define PCI_CFG_TYPE0_REG_SHF           0
+#define PCI_CFG_TYPE0_FUNC_SHF          8
+
+/* Type 1 */
+#define PCI_CFG_TYPE1_REG_SHF           0
+#define PCI_CFG_TYPE1_FUNC_SHF          8
+#define PCI_CFG_TYPE1_DEV_SHF           11
+#define PCI_CFG_TYPE1_BUS_SHF           16
+
+static int gt64120_pcibios_config_access(unsigned char access_type,
+	struct pci_bus *bus, unsigned int devfn, int where, u32 * data)
+{
+	unsigned char busnum = bus->number;
+	u32 intr;
+
+	if ((busnum == 0) && (PCI_SLOT(devfn) == 0))
+		/* Galileo itself is devfn 0, don't move it around */
+		return -1;
+
+	if ((busnum == 0) && (devfn >= PCI_DEVFN(31, 0)))
+		return -1;	/* Because of a bug in the galileo (for slot 31). */
+
+	/* Clear cause register bits */
+	GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
+	                             GT_INTRCAUSE_TARABORT0_BIT));
+
+	/* Setup address */
+	GT_WRITE(GT_PCI0_CFGADDR_OFS,
+		 (busnum << GT_PCI0_CFGADDR_BUSNUM_SHF) |
+		 (devfn << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
+		 ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) |
+		 GT_PCI0_CFGADDR_CONFIGEN_BIT);
+
+	if (access_type == PCI_ACCESS_WRITE) {
+		if (busnum == 0 && PCI_SLOT(devfn) == 0) {
+			/*
+			 * The Galileo system controller is acting
+			 * differently than other devices.
+			 */
+			GT_WRITE(GT_PCI0_CFGDATA_OFS, *data);
+		} else
+			__GT_WRITE(GT_PCI0_CFGDATA_OFS, *data);
+	} else {
+		if (busnum == 0 && PCI_SLOT(devfn) == 0) {
+			/*
+			 * The Galileo system controller is acting
+			 * differently than other devices.
+			 */
+			*data = GT_READ(GT_PCI0_CFGDATA_OFS);
+		} else
+			*data = __GT_READ(GT_PCI0_CFGDATA_OFS);
+	}
+
+	/* Check for master or target abort */
+	intr = GT_READ(GT_INTRCAUSE_OFS);
+
+	if (intr & (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT)) {
+		/* Error occurred */
+
+		/* Clear bits */
+		GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
+		                             GT_INTRCAUSE_TARABORT0_BIT));
+
+		return -1;
+	}
+
+	return 0;
+}
+
+
+/*
+ * We can't address 8 and 16 bit words directly.  Instead we have to
+ * read/write a 32bit word and mask/modify the data we actually want.
+ */
+static int gt64120_pcibios_read(struct pci_bus *bus, unsigned int devfn,
+                                int where, int size, u32 * val)
+{
+	u32 data = 0;
+
+	if (gt64120_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
+				          &data))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	if (size == 1)
+		*val = (data >> ((where & 3) << 3)) & 0xff;
+	else if (size == 2)
+		*val = (data >> ((where & 3) << 3)) & 0xffff;
+	else
+		*val = data;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int gt64120_pcibios_write(struct pci_bus *bus, unsigned int devfn,
+			      int where, int size, u32 val)
+{
+	u32 data = 0;
+
+	if (size == 4)
+		data = val;
+	else {
+		if (gt64120_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
+		                                  where, &data))
+			return PCIBIOS_DEVICE_NOT_FOUND;
+
+		if (size == 1)
+			data = (data & ~(0xff << ((where & 3) << 3))) |
+				(val << ((where & 3) << 3));
+		else if (size == 2)
+			data = (data & ~(0xffff << ((where & 3) << 3))) |
+				(val << ((where & 3) << 3));
+	}
+
+	if (gt64120_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, where,
+				       &data))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops gt64120_pci_ops = {
+	.read = gt64120_pcibios_read,
+	.write = gt64120_pcibios_write
+};
diff --git a/arch/mips/pci/ops-gt96100.c b/arch/mips/pci/ops-gt96100.c
new file mode 100644
index 0000000..9e4ea66
--- /dev/null
+++ b/arch/mips/pci/ops-gt96100.c
@@ -0,0 +1,169 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Galileo EV96100 board specific pci support.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * This file was derived from Carsten Langgaard's
+ * arch/mips/mips-boards/generic/pci.c
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/delay.h>
+#include <asm/gt64120.h>
+#include <asm/galileo-boards/ev96100.h>
+
+#define PCI_ACCESS_READ  0
+#define PCI_ACCESS_WRITE 1
+
+static int static gt96100_config_access(unsigned char access_type,
+	struct pci_bus *bus, unsigned int devfn, int where, u32 * data)
+{
+	unsigned char bus = bus->number;
+	u32 intr;
+
+	/*
+	 * Because of a bug in the galileo (for slot 31).
+	 */
+	if (bus == 0 && devfn >= PCI_DEVFN(31, 0))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* Clear cause register bits */
+	GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
+				     GT_INTRCAUSE_TARABORT0_BIT));
+
+	/* Setup address */
+	GT_WRITE(GT_PCI0_CFGADDR_OFS,
+		 (bus << GT_PCI0_CFGADDR_BUSNUM_SHF) |
+		 (devfn << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
+		 ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) |
+		 GT_PCI0_CFGADDR_CONFIGEN_BIT);
+	udelay(2);
+
+
+	if (access_type == PCI_ACCESS_WRITE) {
+		if (devfn != 0)
+			*data = le32_to_cpu(*data);
+		GT_WRITE(GT_PCI0_CFGDATA_OFS, *data);
+	} else {
+		*data = GT_READ(GT_PCI0_CFGDATA_OFS);
+		if (devfn != 0)
+			*data = le32_to_cpu(*data);
+	}
+
+	udelay(2);
+
+	/* Check for master or target abort */
+	intr = GT_READ(GT_INTRCAUSE_OFS);
+
+	if (intr & (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT)) {
+		/* Error occured */
+
+		/* Clear bits */
+		GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
+					     GT_INTRCAUSE_TARABORT0_BIT));
+		return -1;
+	}
+	return 0;
+}
+
+/*
+ * We can't address 8 and 16 bit words directly.  Instead we have to
+ * read/write a 32bit word and mask/modify the data we actually want.
+ */
+static int gt96100_pcibios_read(struct pci_bus *bus, unsigned int devfn,
+	int where, int size, u32 * val)
+{
+	u32 data = 0;
+
+	if (gt96100_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	switch (size) {
+	case 1:
+		*val = (data >> ((where & 3) << 3)) & 0xff;
+		break;
+
+	case 2:
+		*val = (data >> ((where & 3) << 3)) & 0xffff;
+		break;
+
+	case 4:
+		*val = data;
+		break;
+	}
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int gt96100_pcibios_write(struct pci_bus *bus, unsigned int devfn,
+	int where, int size, u32 val)
+{
+	u32 data = 0;
+
+	switch (size) {
+	case 1:
+		if (gt96100_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
+			return -1;
+
+		data = (data & ~(0xff << ((where & 3) << 3))) |
+		       (val << ((where & 3) << 3));
+
+		if (gt96100_config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
+			return -1;
+
+		return PCIBIOS_SUCCESSFUL;
+
+	case 2:
+		if (gt96100_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
+			return -1;
+
+		data = (data & ~(0xffff << ((where & 3) << 3))) |
+		       (val << ((where & 3) << 3));
+
+		if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &data))
+			return -1;
+
+
+		return PCIBIOS_SUCCESSFUL;
+
+	case 4:
+		if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &val))
+			return -1;
+
+		return PCIBIOS_SUCCESSFUL;
+	}
+}
+
+struct pci_ops gt96100_pci_ops = {
+	.read	= gt96100_pcibios_read,
+	.write	= gt96100_pcibios_write
+};
diff --git a/arch/mips/pci/ops-it8172.c b/arch/mips/pci/ops-it8172.c
new file mode 100644
index 0000000..b7a8b9a
--- /dev/null
+++ b/arch/mips/pci/ops-it8172.c
@@ -0,0 +1,215 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	IT8172 system controller specific pci support.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/it8172/it8172.h>
+#include <asm/it8172/it8172_pci.h>
+
+#define PCI_ACCESS_READ  0
+#define PCI_ACCESS_WRITE 1
+
+#undef DEBUG
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+static struct resource pci_mem_resource_1;
+
+static struct resource pci_io_resource = {
+	"io pci IO space",
+	0x14018000,
+	0x17FFFFFF,
+	IORESOURCE_IO
+};
+
+static struct resource pci_mem_resource_0 = {
+	"ext pci memory space 0/1",
+	0x10101000,
+	0x13FFFFFF,
+	IORESOURCE_MEM,
+	&pci_mem_resource_0,
+	NULL,
+	&pci_mem_resource_1
+};
+
+static struct resource pci_mem_resource_1 = {
+	"ext pci memory space 2/3",
+	0x1A000000,
+	0x1FBFFFFF,
+	IORESOURCE_MEM,
+	&pci_mem_resource_0,
+	NULL,
+	NULL
+};
+
+extern struct pci_ops it8172_pci_ops;
+
+struct pci_controller it8172_controller = {
+	.pci_ops	= &it8172_pci_ops,
+	.io_resource	= &pci_io_resource,
+	.mem_resource	= &pci_mem_resource_0,
+};
+
+static int it8172_pcibios_config_access(unsigned char access_type,
+					struct pci_bus *bus,
+					unsigned int devfn, int where,
+					u32 * data)
+{
+	/*
+	 * config cycles are on 4 byte boundary only
+	 */
+
+	/* Setup address */
+	IT_WRITE(IT_CONFADDR, (bus->number << IT_BUSNUM_SHF) |
+		 (devfn << IT_FUNCNUM_SHF) | (where & ~0x3));
+
+	if (access_type == PCI_ACCESS_WRITE) {
+		IT_WRITE(IT_CONFDATA, *data);
+	} else {
+		IT_READ(IT_CONFDATA, *data);
+	}
+
+	/*
+	 * Revisit: check for master or target abort.
+	 */
+	return 0;
+}
+
+
+/*
+ * We can't address 8 and 16 bit words directly.  Instead we have to
+ * read/write a 32bit word and mask/modify the data we actually want.
+ */
+static write_config(struct pci_bus *bus, unsigned int devfn, int where,
+		    int size, u32 val)
+{
+	u32 data = 0;
+
+	switch (size) {
+	case 1:
+		if (it8172_pcibios_config_access
+		    (PCI_ACCESS_READ, dev, where, &data))
+			return -1;
+
+		*val = (data >> ((where & 3) << 3)) & 0xff;
+
+		return PCIBIOS_SUCCESSFUL;
+
+	case 2:
+
+		if (where & 1)
+			return PCIBIOS_BAD_REGISTER_NUMBER;
+
+		if (it8172_pcibios_config_access
+		    (PCI_ACCESS_READ, dev, where, &data))
+			return -1;
+
+		*val = (data >> ((where & 3) << 3)) & 0xffff;
+		DBG("cfg read word: bus %d dev_fn %x where %x: val %x\n",
+		    dev->bus->number, dev->devfn, where, *val);
+
+		return PCIBIOS_SUCCESSFUL;
+
+	case 4:
+
+		if (where & 3)
+			return PCIBIOS_BAD_REGISTER_NUMBER;
+
+		if (it8172_pcibios_config_access
+		    (PCI_ACCESS_READ, dev, where, &data))
+			return -1;
+
+		*val = data;
+
+		return PCIBIOS_SUCCESSFUL;
+	}
+}
+
+
+static write_config(struct pci_bus *bus, unsigned int devfn, int where,
+		    int size, u32 val)
+{
+	u32 data = 0;
+
+	switch (size) {
+	case 1:
+		if (it8172_pcibios_config_access
+		    (PCI_ACCESS_READ, dev, where, &data))
+			return -1;
+
+		data = (data & ~(0xff << ((where & 3) << 3))) |
+		    (val << ((where & 3) << 3));
+
+		if (it8172_pcibios_config_access
+		    (PCI_ACCESS_WRITE, dev, where, &data))
+			return -1;
+
+		return PCIBIOS_SUCCESSFUL;
+
+	case 2:
+		if (where & 1)
+			return PCIBIOS_BAD_REGISTER_NUMBER;
+
+		if (it8172_pcibios_config_access
+		    (PCI_ACCESS_READ, dev, where, &data))
+			eturn - 1;
+
+		data = (data & ~(0xffff << ((where & 3) << 3))) |
+		    (val << ((where & 3) << 3));
+
+		if (it8172_pcibios_config_access
+		    (PCI_ACCESS_WRITE, dev, where, &data))
+			return -1;
+
+		return PCIBIOS_SUCCESSFUL;
+
+	case 4:
+		if (where & 3)
+			return PCIBIOS_BAD_REGISTER_NUMBER;
+
+		if (it8172_pcibios_config_access
+		    (PCI_ACCESS_WRITE, dev, where, &val))
+			return -1;
+
+		return PCIBIOS_SUCCESSFUL;
+	}
+}
+
+struct pci_ops it8172_pci_ops = {
+	.read = read_config,
+	.write = write_config,
+};
diff --git a/arch/mips/pci/ops-mace.c b/arch/mips/pci/ops-mace.c
new file mode 100644
index 0000000..8008e31
--- /dev/null
+++ b/arch/mips/pci/ops-mace.c
@@ -0,0 +1,91 @@
+/*
+ * 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) 2000, 2001 Keith M Wesolowski
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <asm/pci.h>
+#include <asm/ip32/mace.h>
+
+#if 0
+# define DPRINTK(args...) printk(args);
+#else
+# define DPRINTK(args...)
+#endif
+
+/*
+ * O2 has up to 5 PCI devices connected into the MACE bridge.  The device
+ * map looks like this:
+ *
+ * 0  aic7xxx 0
+ * 1  aic7xxx 1
+ * 2  expansion slot
+ * 3  N/C
+ * 4  N/C
+ */
+
+#define chkslot(_bus,_devfn)					\
+do {							        \
+	if ((_bus)->number > 0 || PCI_SLOT (_devfn) < 1	\
+	    || PCI_SLOT (_devfn) > 3)			        \
+		return PCIBIOS_DEVICE_NOT_FOUND;		\
+} while (0)
+
+#define mkaddr(_devfn, _reg) \
+((((_devfn) & 0xffUL) << 8) | ((_reg) & 0xfcUL))
+
+static int
+mace_pci_read_config(struct pci_bus *bus, unsigned int devfn,
+		     int reg, int size, u32 *val)
+{
+	chkslot(bus, devfn);
+	mace->pci.config_addr = mkaddr(devfn, reg);
+	switch (size) {
+	case 1:
+		*val = mace->pci.config_data.b[(reg & 3) ^ 3];
+		break;
+	case 2:
+		*val = mace->pci.config_data.w[((reg >> 1) & 1) ^ 1];
+		break;
+	case 4:
+		*val = mace->pci.config_data.l;
+		break;
+	}
+
+	DPRINTK("read%d: reg=%08x,val=%02x\n", size * 8, reg, *val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+mace_pci_write_config(struct pci_bus *bus, unsigned int devfn,
+		      int reg, int size, u32 val)
+{
+	chkslot(bus, devfn);
+	mace->pci.config_addr = mkaddr(devfn, reg);
+	switch (size) {
+	case 1:
+		mace->pci.config_data.b[(reg & 3) ^ 3] = val;
+		break;
+	case 2:
+		mace->pci.config_data.w[((reg >> 1) & 1) ^ 1] = val;
+		break;
+	case 4:
+		mace->pci.config_data.l = val;
+		break;
+	}
+
+	DPRINTK("write%d: reg=%08x,val=%02x\n", size * 8, reg, val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops mace_pci_ops = {
+	.read = mace_pci_read_config,
+	.write = mace_pci_write_config,
+};
diff --git a/arch/mips/pci/ops-marvell.c b/arch/mips/pci/ops-marvell.c
new file mode 100644
index 0000000..1ac5c59
--- /dev/null
+++ b/arch/mips/pci/ops-marvell.c
@@ -0,0 +1,93 @@
+/*
+ * 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) 2003, 2004 Ralf Baechle (ralf@linux-mips.org)
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+
+#include <asm/marvell.h>
+
+static int mv_read_config(struct pci_bus *bus, unsigned int devfn,
+	int where, int size, u32 * val)
+{
+	struct mv_pci_controller *mvbc = bus->sysdata;
+	unsigned long address_reg, data_reg;
+	u32 address;
+
+	address_reg = mvbc->config_addr;
+	data_reg = mvbc->config_vreg;
+
+	/* Accessing device 31 crashes those Marvells.  Since years.
+	   Will they ever make sane controllers ... */
+	if (PCI_SLOT(devfn) == 31)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	address = (bus->number << 16) | (devfn << 8) |
+	          (where & 0xfc) | 0x80000000;
+
+	/* start the configuration cycle */
+	MV_WRITE(address_reg, address);
+
+	switch (size) {
+	case 1:
+		*val = MV_READ_8(data_reg + (where & 0x3));
+		break;
+
+	case 2:
+		*val = MV_READ_16(data_reg + (where & 0x3));
+		break;
+
+	case 4:
+		*val = MV_READ(data_reg);
+		break;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int mv_write_config(struct pci_bus *bus, unsigned int devfn,
+	int where, int size, u32 val)
+{
+	struct mv_pci_controller *mvbc = bus->sysdata;
+	unsigned long address_reg, data_reg;
+	u32 address;
+
+	address_reg = mvbc->config_addr;
+	data_reg = mvbc->config_vreg;
+
+	/* Accessing device 31 crashes those Marvells.  Since years.
+	   Will they ever make sane controllers ... */
+	if (PCI_SLOT(devfn) == 31)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	address = (bus->number << 16) | (devfn << 8) |
+	          (where & 0xfc) | 0x80000000;
+
+	/* start the configuration cycle */
+	MV_WRITE(address_reg, address);
+
+	switch (size) {
+	case 1:
+		MV_WRITE_8(data_reg + (where & 0x3), val);
+		break;
+
+	case 2:
+		MV_WRITE_16(data_reg + (where & 0x3), val);
+		break;
+
+	case 4:
+		MV_WRITE(data_reg, val);
+		break;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops mv_pci_ops = {
+	.read	= mv_read_config,
+	.write	= mv_write_config
+};
diff --git a/arch/mips/pci/ops-msc.c b/arch/mips/pci/ops-msc.c
new file mode 100644
index 0000000..7bc0996
--- /dev/null
+++ b/arch/mips/pci/ops-msc.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 1999, 2000, 2004, 2005  MIPS Technologies, Inc.
+ *    All rights reserved.
+ *    Authors: Carsten Langgaard <carstenl@mips.com>
+ *             Maciej W. Rozycki <macro@mips.com>
+ * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * MIPS boards specific PCI support.
+ *
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/mips-boards/msc01_pci.h>
+
+#define PCI_ACCESS_READ  0
+#define PCI_ACCESS_WRITE 1
+
+/*
+ *  PCI configuration cycle AD bus definition
+ */
+/* Type 0 */
+#define PCI_CFG_TYPE0_REG_SHF           0
+#define PCI_CFG_TYPE0_FUNC_SHF          8
+
+/* Type 1 */
+#define PCI_CFG_TYPE1_REG_SHF           0
+#define PCI_CFG_TYPE1_FUNC_SHF          8
+#define PCI_CFG_TYPE1_DEV_SHF           11
+#define PCI_CFG_TYPE1_BUS_SHF           16
+
+static int msc_pcibios_config_access(unsigned char access_type,
+	struct pci_bus *bus, unsigned int devfn, int where, u32 * data)
+{
+	unsigned char busnum = bus->number;
+	unsigned char type;
+	u32 intr;
+
+#ifdef CONFIG_MIPS_BOARDS_GEN
+	if ((busnum == 0) && (PCI_SLOT(devfn) == 17)) {
+		/* MIPS Core boards have SOCit connected as device 17 */
+		return -1;
+	}
+#endif
+
+	/* Clear status register bits. */
+	MSC_WRITE(MSC01_PCI_INTSTAT,
+		  (MSC01_PCI_INTCFG_MA_BIT | MSC01_PCI_INTCFG_TA_BIT));
+
+	/* Setup address */
+	if (busnum == 0)
+		type = 0;	/* Type 0 */
+	else
+		type = 1;	/* Type 1 */
+
+	MSC_WRITE(MSC01_PCI_CFGADDR,
+		  ((busnum << MSC01_PCI_CFGADDR_BNUM_SHF) |
+		   (PCI_SLOT(devfn) << MSC01_PCI_CFGADDR_DNUM_SHF)
+		   | (PCI_FUNC(devfn) <<
+		      MSC01_PCI_CFGADDR_FNUM_SHF) | ((where /
+						      4) <<
+						     MSC01_PCI_CFGADDR_RNUM_SHF)
+		   | (type)));
+
+	/* Perform access */
+	if (access_type == PCI_ACCESS_WRITE)
+		MSC_WRITE(MSC01_PCI_CFGDATA, *data);
+	else
+		MSC_READ(MSC01_PCI_CFGDATA, *data);
+
+	/* Detect Master/Target abort */
+	MSC_READ(MSC01_PCI_INTSTAT, intr);
+	if (intr & (MSC01_PCI_INTCFG_MA_BIT |
+		    MSC01_PCI_INTCFG_TA_BIT)) {
+		/* Error occurred */
+
+		/* Clear bits */
+		MSC_READ(MSC01_PCI_INTSTAT, intr);
+		MSC_WRITE(MSC01_PCI_INTSTAT,
+			  (MSC01_PCI_INTCFG_MA_BIT |
+			   MSC01_PCI_INTCFG_TA_BIT));
+
+		return -1;
+	}
+
+	return 0;
+}
+
+
+/*
+ * We can't address 8 and 16 bit words directly.  Instead we have to
+ * read/write a 32bit word and mask/modify the data we actually want.
+ */
+static int msc_pcibios_read(struct pci_bus *bus, unsigned int devfn,
+			     int where, int size, u32 * val)
+{
+	u32 data = 0;
+
+	if ((size == 2) && (where & 1))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	else if ((size == 4) && (where & 3))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (msc_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
+	                              &data))
+		return -1;
+
+	if (size == 1)
+		*val = (data >> ((where & 3) << 3)) & 0xff;
+	else if (size == 2)
+		*val = (data >> ((where & 3) << 3)) & 0xffff;
+	else
+		*val = data;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int msc_pcibios_write(struct pci_bus *bus, unsigned int devfn,
+			      int where, int size, u32 val)
+{
+	u32 data = 0;
+
+	if ((size == 2) && (where & 1))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	else if ((size == 4) && (where & 3))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (size == 4)
+		data = val;
+	else {
+		if (msc_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
+		                              where, &data))
+			return -1;
+
+		if (size == 1)
+			data = (data & ~(0xff << ((where & 3) << 3))) |
+				(val << ((where & 3) << 3));
+		else if (size == 2)
+			data = (data & ~(0xffff << ((where & 3) << 3))) |
+				(val << ((where & 3) << 3));
+	}
+
+	if (msc_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, where,
+				       &data))
+		return -1;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops msc_pci_ops = {
+	.read = msc_pcibios_read,
+	.write = msc_pcibios_write
+};
diff --git a/arch/mips/pci/ops-nile4.c b/arch/mips/pci/ops-nile4.c
new file mode 100644
index 0000000..a716992
--- /dev/null
+++ b/arch/mips/pci/ops-nile4.c
@@ -0,0 +1,147 @@
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <asm/bootinfo.h>
+
+#include <asm/lasat/lasat.h>
+#include <asm/gt64120.h>
+#include <asm/nile4.h>
+
+#define PCI_ACCESS_READ  0
+#define PCI_ACCESS_WRITE 1
+
+#define LO(reg) (reg / 4)
+#define HI(reg) (reg / 4 + 1)
+
+volatile unsigned long *const vrc_pciregs = (void *) Vrc5074_BASE;
+
+static spinlock_t nile4_pci_lock;
+
+static int nile4_pcibios_config_access(unsigned char access_type,
+	struct pci_bus *bus, unsigned int devfn, int where, u32 * val)
+{
+	unsigned char busnum = bus->number;
+	u32 adr, mask, err;
+
+	if ((busnum == 0) && (PCI_SLOT(devfn) > 8))
+		/* The addressing scheme chosen leaves room for just
+		 * 8 devices on the first busnum (besides the PCI
+		 * controller itself) */
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	if ((busnum == 0) && (devfn == PCI_DEVFN(0, 0))) {
+		/* Access controller registers directly */
+		if (access_type == PCI_ACCESS_WRITE) {
+			vrc_pciregs[(0x200 + where) >> 2] = *val;
+		} else {
+			*val = vrc_pciregs[(0x200 + where) >> 2];
+		}
+		return PCIBIOS_SUCCESSFUL;
+	}
+
+	/* Temporarily map PCI Window 1 to config space */
+	mask = vrc_pciregs[LO(NILE4_PCIINIT1)];
+	vrc_pciregs[LO(NILE4_PCIINIT1)] = 0x0000001a | (busnum ? 0x200 : 0);
+
+	/* Clear PCI Error register. This also clears the Error Type
+	 * bits in the Control register */
+	vrc_pciregs[LO(NILE4_PCIERR)] = 0;
+	vrc_pciregs[HI(NILE4_PCIERR)] = 0;
+
+	/* Setup address */
+	if (busnum == 0)
+		adr =
+		    KSEG1ADDR(PCI_WINDOW1) +
+		    ((1 << (PCI_SLOT(devfn) + 15)) | (PCI_FUNC(devfn) << 8)
+		     | (where & ~3));
+	else
+		adr = KSEG1ADDR(PCI_WINDOW1) | (busnum << 16) | (devfn << 8) |
+		      (where & ~3);
+
+	if (access_type == PCI_ACCESS_WRITE)
+		*(u32 *) adr = *val;
+	else
+		*val = *(u32 *) adr;
+
+	/* Check for master or target abort */
+	err = (vrc_pciregs[HI(NILE4_PCICTRL)] >> 5) & 0x7;
+
+	/* Restore PCI Window 1 */
+	vrc_pciregs[LO(NILE4_PCIINIT1)] = mask;
+
+	if (err)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn,
+	int where, int size, u32 * val)
+{
+	unsigned long flags;
+	u32 data = 0;
+	int err;
+
+	if ((size == 2) && (where & 1))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	else if ((size == 4) && (where & 3))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	spin_lock_irqsave(&nile4_pci_lock, flags);
+	err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
+					&data);
+	spin_unlock_irqrestore(&nile4_pci_lock, flags);
+
+	if (err)
+		return err;
+
+	if (size == 1)
+		*val = (data >> ((where & 3) << 3)) & 0xff;
+	else if (size == 2)
+		*val = (data >> ((where & 3) << 3)) & 0xffff;
+	else
+		*val = data;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int nile4_pcibios_write(struct pci_bus *bus, unsigned int devfn,
+	int where, int size, u32 val)
+{
+	unsigned long flags;
+	u32 data = 0;
+	int err;
+
+	if ((size == 2) && (where & 1))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	else if ((size == 4) && (where & 3))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	spin_lock_irqsave(&nile4_pci_lock, flags);
+	err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
+	                                  &data);
+	spin_unlock_irqrestore(&nile4_pci_lock, flags);
+
+	if (err)
+		return err;
+
+	if (size == 1)
+		data = (data & ~(0xff << ((where & 3) << 3))) |
+		    (val << ((where & 3) << 3));
+	else if (size == 2)
+		data = (data & ~(0xffff << ((where & 3) << 3))) |
+		    (val << ((where & 3) << 3));
+	else
+		data = val;
+
+	if (nile4_pcibios_config_access
+	    (PCI_ACCESS_WRITE, bus, devfn, where, &data))
+		return -1;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops nile4_pci_ops = {
+	.read = nile4_pcibios_read,
+	.write = nile4_pcibios_write,
+};
diff --git a/arch/mips/pci/ops-sni.c b/arch/mips/pci/ops-sni.c
new file mode 100644
index 0000000..62bdd19
--- /dev/null
+++ b/arch/mips/pci/ops-sni.c
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ *
+ * SNI specific PCI support for RM200/RM300.
+ *
+ * Copyright (C) 1997 - 2000, 2003 Ralf Baechle <ralf@linux-mips.org>
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <asm/sni.h>
+
+/*
+ * It seems that on the RM200 only lower 3 bits of the 5 bit PCI device
+ * address are decoded.  We therefore manually have to reject attempts at
+ * reading outside this range.  Being on the paranoid side we only do this
+ * test for bus 0 and hope forwarding and decoding work properly for any
+ * subordinated busses.
+ *
+ * ASIC PCI only supports type 1 config cycles.
+ */
+static int set_config_address(unsigned int busno, unsigned int devfn, int reg)
+{
+	if ((devfn > 255) || (reg > 255))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (busno == 0 && devfn >= PCI_DEVFN(8, 0))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	*(volatile u32 *)PCIMT_CONFIG_ADDRESS =
+		 ((busno    & 0xff) << 16) |
+	         ((devfn    & 0xff) <<  8) |
+	          (reg      & 0xfc);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pcimt_read(struct pci_bus *bus, unsigned int devfn, int reg,
+		      int size, u32 * val)
+{
+	int res;
+
+	if ((res = set_config_address(bus->number, devfn, reg)))
+		return res;
+
+	switch (size) {
+	case 1:
+		*val = *(volatile  u8 *) (PCIMT_CONFIG_DATA + (reg & 3));
+		break;
+	case 2:
+		*val = *(volatile u16 *) (PCIMT_CONFIG_DATA + (reg & 2));
+		break;
+	case 4:
+		*val = *(volatile u32 *) PCIMT_CONFIG_DATA;
+		break;
+	}
+
+	return 0;
+}
+
+static int pcimt_write(struct pci_bus *bus, unsigned int devfn, int reg,
+		       int size, u32 val)
+{
+	int res;
+
+	if ((res = set_config_address(bus->number, devfn, reg)))
+		return res;
+
+	switch (size) {
+	case 1:
+		*(volatile  u8 *) (PCIMT_CONFIG_DATA + (reg & 3)) = val;
+		break;
+	case 2:
+		*(volatile u16 *) (PCIMT_CONFIG_DATA + (reg & 2)) = val;
+		break;
+	case 4:
+		*(volatile u32 *) PCIMT_CONFIG_DATA = val;
+		break;
+	}
+
+	return 0;
+}
+
+struct pci_ops sni_pci_ops = {
+	.read = pcimt_read,
+	.write = pcimt_write,
+};
diff --git a/arch/mips/pci/ops-titan-ht.c b/arch/mips/pci/ops-titan-ht.c
new file mode 100644
index 0000000..46c636c
--- /dev/null
+++ b/arch/mips/pci/ops-titan-ht.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2003 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+
+#include <asm/titan_dep.h>
+
+static int titan_ht_config_read_dword(struct pci_bus *bus, unsigned int devfn,
+	int offset, u32 * val)
+{
+	volatile uint32_t address;
+	int busno;
+
+	busno = bus->number;
+
+	address = (busno << 16) | (devfn << 8) | (offset & 0xfc) | 0x80000000;
+	if (busno != 0)
+		address |= 1;
+
+	/*
+	 * RM9000 HT Errata: Issue back to back HT config
+	 * transcations. Issue a BIU sync before and
+	 * after the HT cycle
+	 */
+
+	*(volatile int32_t *) 0xfb0000f0 |= 0x2;
+
+	udelay(30);
+
+	*(volatile int32_t *) 0xfb0006f8 = address;
+	*(val) = *(volatile int32_t *) 0xfb0006fc;
+
+	udelay(30);
+
+	* (volatile int32_t *) 0xfb0000f0 |= 0x2;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int titan_ht_config_read(struct pci_bus *bus, unsigned int devfn,
+	int offset, int size, u32 * val)
+{
+	uint32_t dword;
+
+	titan_ht_config_read_dword(bus, devfn, offset, &dword);
+
+	dword >>= ((offset & 3) << 3);
+	dword &= (0xffffffffU >> ((4 - size) << 8));
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static inline int titan_ht_config_write_dword(struct pci_bus *bus,
+	unsigned int devfn, int offset, u32 val)
+{
+	volatile uint32_t address;
+	int busno;
+
+	busno = bus->number;
+
+	address = (busno << 16) | (devfn << 8) | (offset & 0xfc) | 0x80000000;
+	if (busno != 0)
+		address |= 1;
+
+	*(volatile int32_t *) 0xfb0000f0 |= 0x2;
+
+	udelay(30);
+
+	*(volatile int32_t *) 0xfb0006f8 = address;
+	*(volatile int32_t *) 0xfb0006fc = val;
+
+	udelay(30);
+
+	*(volatile int32_t *) 0xfb0000f0 |= 0x2;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int titan_ht_config_write(struct pci_bus *bus, unsigned int devfn,
+	int offset, int size, u32 val)
+{
+	uint32_t val1, val2, mask;
+
+	titan_ht_config_read_dword(bus, devfn, offset, &val2);
+
+	val1 = val << ((offset & 3) << 3);
+	mask = ~(0xffffffffU >> ((4 - size) << 8));
+	val2 &= ~(mask << ((offset & 3) << 8));
+
+	titan_ht_config_write_dword(bus, devfn, offset, val1 | val2);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops titan_ht_pci_ops = {
+	.read	= titan_ht_config_read,
+	.write	= titan_ht_config_write,
+};
diff --git a/arch/mips/pci/ops-titan.c b/arch/mips/pci/ops-titan.c
new file mode 100644
index 0000000..233ec6f
--- /dev/null
+++ b/arch/mips/pci/ops-titan.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2003 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
+ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
+ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+
+#include <asm/titan_dep.h>
+
+static int titan_read_config(struct pci_bus *bus, unsigned int devfn, int reg,
+	int size, u32 * val)
+{
+	uint32_t address, tmp;
+	int dev, busno, func;
+
+	busno = bus->number;
+	dev = PCI_SLOT(devfn);
+	func = PCI_FUNC(devfn);
+
+	address = (busno << 16) | (dev << 11) | (func << 8) |
+	          (reg & 0xfc) | 0x80000000;
+
+
+	/* start the configuration cycle */
+	TITAN_WRITE(TITAN_PCI_0_CONFIG_ADDRESS, address);
+	tmp = TITAN_READ(TITAN_PCI_0_CONFIG_DATA) >> ((reg & 3) << 3);
+
+	switch (size) {
+	case 1:
+		tmp &= 0xff;
+	case 2:
+		tmp &= 0xffff;
+	}
+	*val = tmp;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int titan_write_config(struct pci_bus *bus, unsigned int devfn, int reg,
+	int size, u32 val)
+{
+	uint32_t address;
+	int dev, busno, func;
+
+	busno = bus->number;
+	dev = PCI_SLOT(devfn);
+	func = PCI_FUNC(devfn);
+
+	address = (busno << 16) | (dev << 11) | (func << 8) |
+		(reg & 0xfc) | 0x80000000;
+
+	/* start the configuration cycle */
+	TITAN_WRITE(TITAN_PCI_0_CONFIG_ADDRESS, address);
+
+	/* write the data */
+	switch (size) {
+	case 1:
+		TITAN_WRITE_8(TITAN_PCI_0_CONFIG_DATA + (~reg & 0x3), val);
+		break;
+
+	case 2:
+		TITAN_WRITE_16(TITAN_PCI_0_CONFIG_DATA + (~reg & 0x2), val);
+		break;
+
+	case 4:
+		TITAN_WRITE(TITAN_PCI_0_CONFIG_DATA, val);
+		break;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * Titan PCI structure
+ */
+struct pci_ops titan_pci_ops = {
+	titan_read_config,
+	titan_write_config,
+};
diff --git a/arch/mips/pci/ops-tx3927.c b/arch/mips/pci/ops-tx3927.c
new file mode 100644
index 0000000..0e0daad
--- /dev/null
+++ b/arch/mips/pci/ops-tx3927.c
@@ -0,0 +1,391 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *              ahennessy@mvista.com
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * Based on arch/mips/ddb5xxx/ddb5477/pci_ops.c
+ *
+ *     Define the pci_ops for JMR3927.
+ *
+ * Much of the code is derived from the original DDB5074 port by
+ * Geert Uytterhoeven <geert@sonycom.com>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/addrspace.h>
+#include <asm/jmr3927/jmr3927.h>
+#include <asm/debug.h>
+
+static inline int mkaddr(unsigned char bus, unsigned char dev_fn,
+	unsigned char where)
+{
+	if (bus == 0 && dev_fn >= PCI_DEVFN(TX3927_PCIC_MAX_DEVNU, 0))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	tx3927_pcicptr->ica = ((bus & 0xff) << 0x10) |
+	                      ((dev_fn & 0xff) << 0x08) |
+	                      (where & 0xfc);
+
+	/* clear M_ABORT and Disable M_ABORT Int. */
+	tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT;
+	tx3927_pcicptr->pcistatim &= ~PCI_STATUS_REC_MASTER_ABORT;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static inline int check_abort(void)
+{
+	if (tx3927_pcicptr->pcistat & PCI_STATUS_REC_MASTER_ABORT)
+		tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT;
+		tx3927_pcicptr->pcistatim |= PCI_STATUS_REC_MASTER_ABORT;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int jmr3927_pci_read_config(struct pci_bus *bus, unsigned int devfn,
+	int where, int size, u32 * val)
+{
+	int ret, busno;
+
+	/* check if the bus is top-level */
+	if (bus->parent != NULL)
+		busno = bus->number;
+
+	ret = mkaddr(busno, devfn, where);
+	if (ret)
+		return ret;
+
+	switch (size) {
+	case 1:
+		*val = *(volatile u8 *) ((unsigned long) & tx3927_pcicptr->icd | (where & 3));
+		break;
+
+	case 2:
+		*val = le16_to_cpu(*(volatile u16 *) ((unsigned long) & tx3927_pcicptr->icd | (where & 3)));
+		break;
+
+	case 4:
+		*val = le32_to_cpu(tx3927_pcicptr->icd);
+		break;
+	}
+
+	return check_abort();
+}
+
+static int jmr3927_pci_write_config(struct pci_bus *bus, unsigned int devfn,
+	int where, int size, u32 val)
+{
+	int ret, busno;
+
+	/* check if the bus is top-level */
+	if (bus->parent != NULL)
+		bus = bus->number;
+	else
+		bus = 0;
+
+	ret = mkaddr(busno, devfn, where);
+	if (ret)
+		return ret;
+
+	switch (size) {
+	case 1:
+		*(volatile u8 *) ((unsigned long) & tx3927_pcicptr->icd | (where & 3)) = val;
+		break;
+
+	case 2:
+		*(volatile u16 *) (unsigned longulong) & tx3927_pcicptr->icd | (where & 2)) =
+	    cpu_to_le16(val);
+		break;
+
+	case 4:
+		tx3927_pcicptr->icd = cpu_to_le32(val);
+	}
+
+	if (tx3927_pcicptr->pcistat & PCI_STATUS_REC_MASTER_ABORT)
+		tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT;
+		tx3927_pcicptr->pcistatim |= PCI_STATUS_REC_MASTER_ABORT;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return check_abort();
+}
+
+struct pci_ops jmr3927_pci_ops = {
+	jmr3927_pcibios_read_config,
+	jmr3927_pcibios_write_config,
+};
+
+
+#ifndef JMR3927_INIT_INDIRECT_PCI
+
+inline unsigned long tc_readl(volatile __u32 * addr)
+{
+	return readl(addr);
+}
+
+inline void tc_writel(unsigned long data, volatile __u32 * addr)
+{
+	writel(data, addr);
+}
+#else
+
+unsigned long tc_readl(volatile __u32 * addr)
+{
+	unsigned long val;
+
+	addr = PHYSADDR(addr);
+	*(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr =
+	    (unsigned long) addr;
+	*(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe =
+	    (PCI_IPCIBE_ICMD_MEMREAD << PCI_IPCIBE_ICMD_SHIFT) |
+	    PCI_IPCIBE_IBE_LONG;
+	while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC));
+	val =
+	    le32_to_cpu(*(volatile u32 *) (ulong) & tx3927_pcicptr->
+			ipcidata);
+	/* clear by setting */
+	tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
+	return val;
+}
+
+void tc_writel(unsigned long data, volatile __u32 * addr)
+{
+	addr = PHYSADDR(addr);
+	*(volatile u32 *) (ulong) & tx3927_pcicptr->ipcidata =
+	    cpu_to_le32(data);
+	*(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr =
+	    (unsigned long) addr;
+	*(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe =
+	    (PCI_IPCIBE_ICMD_MEMWRITE << PCI_IPCIBE_ICMD_SHIFT) |
+	    PCI_IPCIBE_IBE_LONG;
+	while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC));
+	/* clear by setting */
+	tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
+}
+
+unsigned char tx_ioinb(unsigned char *addr)
+{
+	unsigned long val;
+	__u32 ioaddr;
+	int offset;
+	int byte;
+
+	ioaddr = (unsigned long) addr;
+	offset = ioaddr & 0x3;
+	if (offset == 0)
+		byte = 0x7;
+	else if (offset == 1)
+		byte = 0xb;
+	else if (offset == 2)
+		byte = 0xd;
+	else if (offset == 3)
+		byte = 0xe;
+	*(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr =
+	    (unsigned long) ioaddr;
+	*(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe =
+	    (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | byte;
+	while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC));
+	val =
+	    le32_to_cpu(*(volatile u32 *) (ulong) & tx3927_pcicptr->
+			ipcidata);
+	val = val & 0xff;
+	/* clear by setting */
+	tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
+	return val;
+}
+
+void tx_iooutb(unsigned long data, unsigned char *addr)
+{
+	__u32 ioaddr;
+	int offset;
+	int byte;
+
+	data = data | (data << 8) | (data << 16) | (data << 24);
+	ioaddr = (unsigned long) addr;
+	offset = ioaddr & 0x3;
+	if (offset == 0)
+		byte = 0x7;
+	else if (offset == 1)
+		byte = 0xb;
+	else if (offset == 2)
+		byte = 0xd;
+	else if (offset == 3)
+		byte = 0xe;
+	*(volatile u32 *) (ulong) & tx3927_pcicptr->ipcidata = data;
+	*(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr =
+	    (unsigned long) ioaddr;
+	*(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe =
+	    (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT) | byte;
+	while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC));
+	/* clear by setting */
+	tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
+}
+
+unsigned short tx_ioinw(unsigned short *addr)
+{
+	unsigned long val;
+	__u32 ioaddr;
+	int offset;
+	int byte;
+
+	ioaddr = (unsigned long) addr;
+	offset = ioaddr & 0x3;
+	if (offset == 0)
+		byte = 0x3;
+	else if (offset == 2)
+		byte = 0xc;
+	*(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr =
+	    (unsigned long) ioaddr;
+	*(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe =
+	    (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | byte;
+	while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC));
+	val =
+	    le32_to_cpu(*(volatile u32 *) (ulong) & tx3927_pcicptr->
+			ipcidata);
+	val = val & 0xffff;
+	/* clear by setting */
+	tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
+	return val;
+
+}
+
+void tx_iooutw(unsigned long data, unsigned short *addr)
+{
+	__u32 ioaddr;
+	int offset;
+	int byte;
+
+	data = data | (data << 16);
+	ioaddr = (unsigned long) addr;
+	offset = ioaddr & 0x3;
+	if (offset == 0)
+		byte = 0x3;
+	else if (offset == 2)
+		byte = 0xc;
+	*(volatile u32 *) (ulong) & tx3927_pcicptr->ipcidata = data;
+	*(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr =
+	    (unsigned long) ioaddr;
+	*(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe =
+	    (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT) | byte;
+	while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC));
+	/* clear by setting */
+	tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
+}
+
+unsigned long tx_ioinl(unsigned int *addr)
+{
+	unsigned long val;
+	__u32 ioaddr;
+
+	ioaddr = (unsigned long) addr;
+	*(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr =
+	    (unsigned long) ioaddr;
+	*(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe =
+	    (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) |
+	    PCI_IPCIBE_IBE_LONG;
+	while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC));
+	val =
+	    le32_to_cpu(*(volatile u32 *) (ulong) & tx3927_pcicptr->
+			ipcidata);
+	/* clear by setting */
+	tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
+	return val;
+}
+
+void tx_iooutl(unsigned long data, unsigned int *addr)
+{
+	__u32 ioaddr;
+
+	ioaddr = (unsigned long) addr;
+	*(volatile u32 *) (ulong) & tx3927_pcicptr->ipcidata =
+	    cpu_to_le32(data);
+	*(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr =
+	    (unsigned long) ioaddr;
+	*(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe =
+	    (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT) |
+	    PCI_IPCIBE_IBE_LONG;
+	while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC));
+	/* clear by setting */
+	tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
+}
+
+void tx_insbyte(unsigned char *addr, void *buffer, unsigned int count)
+{
+	unsigned char *ptr = (unsigned char *) buffer;
+
+	while (count--) {
+		*ptr++ = tx_ioinb(addr);
+	}
+}
+
+void tx_insword(unsigned short *addr, void *buffer, unsigned int count)
+{
+	unsigned short *ptr = (unsigned short *) buffer;
+
+	while (count--) {
+		*ptr++ = tx_ioinw(addr);
+	}
+}
+
+void tx_inslong(unsigned int *addr, void *buffer, unsigned int count)
+{
+	unsigned long *ptr = (unsigned long *) buffer;
+
+	while (count--) {
+		*ptr++ = tx_ioinl(addr);
+	}
+}
+
+void tx_outsbyte(unsigned char *addr, void *buffer, unsigned int count)
+{
+	unsigned char *ptr = (unsigned char *) buffer;
+
+	while (count--) {
+		tx_iooutb(*ptr++, addr);
+	}
+}
+
+void tx_outsword(unsigned short *addr, void *buffer, unsigned int count)
+{
+	unsigned short *ptr = (unsigned short *) buffer;
+
+	while (count--) {
+		tx_iooutw(*ptr++, addr);
+	}
+}
+
+void tx_outslong(unsigned int *addr, void *buffer, unsigned int count)
+{
+	unsigned long *ptr = (unsigned long *) buffer;
+
+	while (count--) {
+		tx_iooutl(*ptr++, addr);
+	}
+}
+#endif
diff --git a/arch/mips/pci/ops-tx4927.c b/arch/mips/pci/ops-tx4927.c
new file mode 100644
index 0000000..2a9d722
--- /dev/null
+++ b/arch/mips/pci/ops-tx4927.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *              ahennessy@mvista.com       
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation 
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * Based on arch/mips/ddb5xxx/ddb5477/pci_ops.c
+ *
+ *     Define the pci_ops for the Toshiba rbtx4927
+ *
+ * Much of the code is derived from the original DDB5074 port by 
+ * Geert Uytterhoeven <geert@sonycom.com>
+ *
+ * Copyright 2004 MontaVista Software Inc.
+ * Author: Manish Lachwani (mlachwani@mvista.com)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/addrspace.h>
+#include <asm/byteorder.h>
+#include <asm/tx4927/tx4927_pci.h>
+
+/* initialize in setup */
+struct resource pci_io_resource = {
+	.name	= "TX4927 PCI IO SPACE",
+	.start	= 0x1000,
+	.end	= (0x1000 + (TX4927_PCIIO_SIZE)) - 1,
+	.flags	= IORESOURCE_IO
+};
+
+/* initialize in setup */
+struct resource pci_mem_resource = {
+	.name	= "TX4927 PCI MEM SPACE",
+	.start	= TX4927_PCIMEM,
+	.end	= TX4927_PCIMEM + TX4927_PCIMEM_SIZE - 1,
+	.flags	= IORESOURCE_MEM
+};
+
+static int mkaddr(int bus, int dev_fn, int where, int *flagsp)
+{
+	if (bus > 0) {
+		/* Type 1 configuration */
+		tx4927_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
+		    ((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1;
+	} else {
+		if (dev_fn >= PCI_DEVFN(TX4927_PCIC_MAX_DEVNU, 0))
+			return -1;
+
+		/* Type 0 configuration */
+		tx4927_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
+		    ((dev_fn & 0xff) << 0x08) | (where & 0xfc);
+	}
+	/* clear M_ABORT and Disable M_ABORT Int. */
+	tx4927_pcicptr->pcistatus =
+	    (tx4927_pcicptr->pcistatus & 0x0000ffff) |
+	    (PCI_STATUS_REC_MASTER_ABORT << 16);
+	tx4927_pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT;
+	return 0;
+}
+
+static int check_abort(int flags)
+{
+	int code = PCIBIOS_SUCCESSFUL;
+	if (tx4927_pcicptr->
+	    pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) {
+		tx4927_pcicptr->pcistatus =
+		    (tx4927_pcicptr->
+		     pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT
+						<< 16);
+		tx4927_pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT;
+		code = PCIBIOS_DEVICE_NOT_FOUND;
+	}
+	return code;
+}
+
+static int tx4927_pcibios_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+		int size, u32 * val)
+{
+	int flags, retval, dev, busno, func;
+
+	busno = bus->number;
+        dev = PCI_SLOT(devfn);
+        func = PCI_FUNC(devfn);
+
+	/* check if the bus is top-level */
+	if (bus->parent != NULL) {
+		busno = bus->number;
+	} else {
+		busno = 0;
+	}
+
+	if (mkaddr(busno, devfn, where, &flags))
+		return -1;
+
+	switch (size) {
+	case 1:
+		*val = *(volatile u8 *) ((ulong) & tx4927_pcicptr->
+                              g2pcfgdata |
+#ifdef __LITTLE_ENDIAN
+						(where & 3));
+#else
+						((where & 0x3) ^ 0x3));
+#endif
+		break;
+	case 2:
+		*val = *(volatile u16 *) ((ulong) & tx4927_pcicptr->
+                               g2pcfgdata |
+#ifdef __LITTLE_ENDIAN
+						(where & 3));
+#else
+						((where & 0x3) ^ 0x2));
+#endif
+		break;
+	case 4:
+		*val = tx4927_pcicptr->g2pcfgdata;
+		break;
+	}
+
+	retval = check_abort(flags);
+	if (retval == PCIBIOS_DEVICE_NOT_FOUND)
+		*val = 0xffffffff;
+
+	return retval;
+}
+
+static int tx4927_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+				int size, u32 val)
+{
+	int flags, dev, busno, func;
+	busno = bus->number;
+        dev = PCI_SLOT(devfn);
+        func = PCI_FUNC(devfn);
+
+	/* check if the bus is top-level */
+	if (bus->parent != NULL) {
+		busno = bus->number;
+	} else {
+		busno = 0;
+	}
+
+	if (mkaddr(busno, devfn, where, &flags))
+		return -1;
+
+	switch (size) {
+	case 1:
+		 *(volatile u8 *) ((ulong) & tx4927_pcicptr->
+                          g2pcfgdata |
+#ifdef __LITTLE_ENDIAN
+					(where & 3)) = val;
+#else
+					((where & 0x3) ^ 0x3)) = val;
+#endif
+		break;
+
+	case 2:
+		*(volatile u16 *) ((ulong) & tx4927_pcicptr->
+                           g2pcfgdata |
+#ifdef __LITTLE_ENDIAN
+					(where & 3)) = val;
+#else
+					((where & 0x3) ^ 0x2)) = val;
+#endif
+		break;
+	case 4:
+		tx4927_pcicptr->g2pcfgdata = val;
+		break;
+	}
+
+	return check_abort(flags);
+}
+
+struct pci_ops tx4927_pci_ops = {
+	tx4927_pcibios_read_config,
+	tx4927_pcibios_write_config
+};
+
+/*
+ * h/w only supports devices 0x00 to 0x14
+ */
+struct pci_controller tx4927_controller = {
+	.pci_ops        = &tx4927_pci_ops,
+	.io_resource    = &pci_io_resource,
+	.mem_resource   = &pci_mem_resource,
+};
diff --git a/arch/mips/pci/ops-vr41xx.c b/arch/mips/pci/ops-vr41xx.c
new file mode 100644
index 0000000..4465460
--- /dev/null
+++ b/arch/mips/pci/ops-vr41xx.c
@@ -0,0 +1,126 @@
+/*
+ *  ops-vr41xx.c, PCI configuration routines for the PCIU of NEC VR4100 series.
+ *
+ *  Copyright (C) 2001-2003 MontaVista Software Inc.
+ *    Author: Yoichi Yuasa <yyuasa@mvista.com or source@mvista.com>
+ *  Copyright (C) 2004  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC VR4122 and VR4131 are supported.
+ */
+#include <linux/pci.h>
+#include <linux/types.h>
+
+#include <asm/io.h>
+
+#define PCICONFDREG	KSEG1ADDR(0x0f000c14)
+#define PCICONFAREG	KSEG1ADDR(0x0f000c18)
+
+static inline int set_pci_configuration_address(unsigned char number,
+                                                unsigned int devfn, int where)
+{
+	if (number == 0) {
+		/*
+		 * Type 0 configuration
+		 */
+		if (PCI_SLOT(devfn) < 11 || where > 0xff)
+			return -EINVAL;
+
+		writel((1U << PCI_SLOT(devfn)) | (PCI_FUNC(devfn) << 8) |
+		       (where & 0xfc), PCICONFAREG);
+	} else {
+		/*
+		 * Type 1 configuration
+		 */
+		if (where > 0xff)
+			return -EINVAL;
+
+		writel(((uint32_t)number << 16) | ((devfn & 0xff) << 8) |
+		       (where & 0xfc) | 1U, PCICONFAREG);
+	}
+
+	return 0;
+}
+
+static int pci_config_read(struct pci_bus *bus, unsigned int devfn, int where,
+                           int size, uint32_t *val)
+{
+	uint32_t data;
+
+	*val = 0xffffffffU;
+	if (set_pci_configuration_address(bus->number, devfn, where) < 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	data = readl(PCICONFDREG);
+
+	switch (size) {
+	case 1:
+		*val = (data >> ((where & 3) << 3)) & 0xffU;
+		break;
+	case 2:
+		*val = (data >> ((where & 2) << 3)) & 0xffffU;
+		break;
+	case 4:
+		*val = data;
+		break;
+	default:
+		return PCIBIOS_FUNC_NOT_SUPPORTED;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_config_write(struct pci_bus *bus, unsigned int devfn, int where,
+                            int size, uint32_t val)
+{
+	uint32_t data;
+	int shift;
+
+	if (set_pci_configuration_address(bus->number, devfn, where) < 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	data = readl(PCICONFDREG);
+
+	switch (size) {
+	case 1:
+		shift = (where & 3) << 3;
+		data &= ~(0xffU << shift);
+		data |= ((val & 0xffU) << shift);
+		break;
+	case 2:
+		shift = (where & 2) << 3;
+		data &= ~(0xffffU << shift);
+		data |= ((val & 0xffffU) << shift);
+		break;
+	case 4:
+		data = val;
+		break;
+	default:
+		return PCIBIOS_FUNC_NOT_SUPPORTED;
+	}
+
+	writel(data, PCICONFDREG);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops vr41xx_pci_ops = {
+	.read	= pci_config_read,
+	.write	= pci_config_write,
+};
diff --git a/arch/mips/pci/pci-ddb5074.c b/arch/mips/pci/pci-ddb5074.c
new file mode 100644
index 0000000..73f9cee
--- /dev/null
+++ b/arch/mips/pci/pci-ddb5074.c
@@ -0,0 +1,79 @@
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+
+#include <asm/debug.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+static struct resource extpci_io_resource = {
+	"pci IO space",
+	0x1000,			/* leave some room for ISA bus */
+	DDB_PCI_IO_SIZE - 1,
+	IORESOURCE_IO
+};
+
+static struct resource extpci_mem_resource = {
+	"pci memory space",
+	DDB_PCI_MEM_BASE + 0x00100000,	/* leave 1 MB for RTC */
+	DDB_PCI_MEM_BASE + DDB_PCI_MEM_SIZE - 1,
+	IORESOURCE_MEM
+};
+
+extern struct pci_ops ddb5476_ext_pci_ops;
+
+struct pci_controller ddb5476_controller = {
+	.pci_ops	= &ddb5476_ext_pci_ops,
+	.io_resource	= &extpci_io_resource,
+	.mem_resource	= &extpci_mem_resource,
+};
+
+#define     PCI_EXT_INTA        8
+#define     PCI_EXT_INTB        9
+#define     PCI_EXT_INTC        10
+#define     PCI_EXT_INTD        11
+#define     PCI_EXT_INTE        12
+
+#define     MAX_SLOT_NUM        14
+
+static unsigned char irq_map[MAX_SLOT_NUM] = {
+  [ 0] = nile4_to_irq(PCI_EXT_INTE),
+  [ 1] = nile4_to_irq(PCI_EXT_INTA),
+  [ 2] = nile4_to_irq(PCI_EXT_INTA),
+  [ 3] = nile4_to_irq(PCI_EXT_INTB),
+  [ 4] = nile4_to_irq(PCI_EXT_INTC),
+  [ 5] = nile4_to_irq(NILE4_INT_UART),
+  [10] = nile4_to_irq(PCI_EXT_INTE),
+  [13] = nile4_to_irq(PCI_EXT_INTE),
+};
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	return irq_map[slot];
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
+
+void __init ddb_pci_reset_bus(void)
+{
+	u32 temp;
+
+	/*
+	 * I am not sure about the "official" procedure, the following
+	 * steps work as far as I know:
+	 * We first set PCI cold reset bit (bit 31) in PCICTRL-H.
+	 * Then we clear the PCI warm reset bit (bit 30) to 0 in PCICTRL-H.
+	 * The same is true for both PCI channels.
+	 */
+	temp = ddb_in32(DDB_PCICTRL + 4);
+	temp |= 0x80000000;
+	ddb_out32(DDB_PCICTRL + 4, temp);
+	temp &= ~0xc0000000;
+	ddb_out32(DDB_PCICTRL + 4, temp);
+
+}
diff --git a/arch/mips/pci/pci-ddb5476.c b/arch/mips/pci/pci-ddb5476.c
new file mode 100644
index 0000000..90dd495
--- /dev/null
+++ b/arch/mips/pci/pci-ddb5476.c
@@ -0,0 +1,93 @@
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+
+#include <asm/debug.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+static struct resource extpci_io_resource = {
+	"pci IO space",
+	0x1000,			/* leave some room for ISA bus */
+	DDB_PCI_IO_SIZE - 1,
+	IORESOURCE_IO
+};
+
+static struct resource extpci_mem_resource = {
+	"pci memory space",
+	DDB_PCI_MEM_BASE + 0x00100000,	/* leave 1 MB for RTC */
+	DDB_PCI_MEM_BASE + DDB_PCI_MEM_SIZE - 1,
+	IORESOURCE_MEM
+};
+
+extern struct pci_ops ddb5476_ext_pci_ops;
+
+struct pci_controller ddb5476_controller = {
+	.pci_ops	= &ddb5476_ext_pci_ops,
+	.io_resource	= &extpci_io_resource,
+	.mem_resource	= &extpci_mem_resource
+};
+
+
+/*
+ * we fix up irqs based on the slot number.
+ * The first entry is at AD:11.
+ *
+ * This does not work for devices on sub-buses yet.
+ */
+
+/*
+ * temporary
+ */
+
+#define		PCI_EXT_INTA		8
+#define		PCI_EXT_INTB		9
+#define		PCI_EXT_INTC		10
+#define		PCI_EXT_INTD		11
+#define		PCI_EXT_INTE		12
+
+/*
+ * based on ddb5477 manual page 11
+ */
+#define		MAX_SLOT_NUM		21
+static unsigned char irq_map[MAX_SLOT_NUM] = {
+ [ 2] = 9,				/* AD:13	USB		*/
+ [ 3] = 10,				/* AD:14	PMU		*/
+ [ 5] = 0,				/* AD:16 	P2P bridge	*/
+ [ 6] = nile4_to_irq(PCI_EXT_INTB),	/* AD:17			*/
+ [ 7] =	nile4_to_irq(PCI_EXT_INTC),	/* AD:18			*/
+ [ 8] = nile4_to_irq(PCI_EXT_INTD),	/* AD:19			*/
+ [ 9] = nile4_to_irq(PCI_EXT_INTA),	/* AD:20			*/
+ [13] = 14,				/* AD:24 HD controller, M5229	*/
+};
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	return irq_map[slot];
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
+
+void __init ddb_pci_reset_bus(void)
+{
+	u32 temp;
+
+	/*
+	 * I am not sure about the "official" procedure, the following
+	 * steps work as far as I know:
+	 * We first set PCI cold reset bit (bit 31) in PCICTRL-H.
+	 * Then we clear the PCI warm reset bit (bit 30) to 0 in PCICTRL-H.
+	 * The same is true for both PCI channels.
+	 */
+	temp = ddb_in32(DDB_PCICTRL + 4);
+	temp |= 0x80000000;
+	ddb_out32(DDB_PCICTRL + 4, temp);
+	temp &= ~0xc0000000;
+	ddb_out32(DDB_PCICTRL + 4, temp);
+
+}
diff --git a/arch/mips/pci/pci-ddb5477.c b/arch/mips/pci/pci-ddb5477.c
new file mode 100644
index 0000000..4ddd53e
--- /dev/null
+++ b/arch/mips/pci/pci-ddb5477.c
@@ -0,0 +1,207 @@
+/*
+ * PCI code for DDB5477.
+ *
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+
+#include <asm/bootinfo.h>
+#include <asm/debug.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+static struct resource extpci_io_resource = {
+	"ext pci IO space",
+	DDB_PCI0_IO_BASE - DDB_PCI_IO_BASE + 0x4000,
+	DDB_PCI0_IO_BASE - DDB_PCI_IO_BASE + DDB_PCI0_IO_SIZE - 1,
+	IORESOURCE_IO
+};
+
+static struct resource extpci_mem_resource = {
+	"ext pci memory space",
+	DDB_PCI0_MEM_BASE + 0x100000,
+	DDB_PCI0_MEM_BASE + DDB_PCI0_MEM_SIZE - 1,
+	IORESOURCE_MEM
+};
+
+static struct resource iopci_io_resource = {
+	"io pci IO space",
+	DDB_PCI1_IO_BASE - DDB_PCI_IO_BASE,
+	DDB_PCI1_IO_BASE - DDB_PCI_IO_BASE + DDB_PCI1_IO_SIZE - 1,
+	IORESOURCE_IO
+};
+
+static struct resource iopci_mem_resource = {
+	"ext pci memory space",
+	DDB_PCI1_MEM_BASE,
+	DDB_PCI1_MEM_BASE + DDB_PCI1_MEM_SIZE - 1,
+	IORESOURCE_MEM
+};
+
+extern struct pci_ops ddb5477_ext_pci_ops;
+extern struct pci_ops ddb5477_io_pci_ops;
+
+struct pci_controller ddb5477_ext_controller = {
+	.pci_ops	= &ddb5477_ext_pci_ops,
+	.io_resource	= &extpci_io_resource,
+	.mem_resource	= &extpci_mem_resource
+};
+
+struct pci_controller ddb5477_io_controller = {
+	.pci_ops	= &ddb5477_io_pci_ops,
+	.io_resource	= &iopci_io_resource,
+	.mem_resource	= &iopci_mem_resource
+};
+
+
+
+/*
+ * we fix up irqs based on the slot number.
+ * The first entry is at AD:11.
+ * Fortunately this works because, although we have two pci buses,
+ * they all have different slot numbers (except for rockhopper slot 20
+ * which is handled below).
+ *
+ */
+
+/*
+ * irq mapping : device -> pci int # -> vrc4377 irq# , 
+ * ddb5477 board manual page 4  and vrc5477 manual page 46
+ */
+
+/*
+ * based on ddb5477 manual page 11
+ */
+#define		MAX_SLOT_NUM		21
+static unsigned char irq_map[MAX_SLOT_NUM] = {
+	/* SLOT:  0, AD:11 */ 0xff,
+	/* SLOT:  1, AD:12 */ 0xff,
+	/* SLOT:  2, AD:13 */ 0xff,
+	/* SLOT:  3, AD:14 */ 0xff,
+	/* SLOT:  4, AD:15 */ VRC5477_IRQ_INTA, /* onboard tulip */
+	/* SLOT:  5, AD:16 */ VRC5477_IRQ_INTB, /* slot 1 */
+	/* SLOT:  6, AD:17 */ VRC5477_IRQ_INTC, /* slot 2 */
+	/* SLOT:  7, AD:18 */ VRC5477_IRQ_INTD, /* slot 3 */
+	/* SLOT:  8, AD:19 */ VRC5477_IRQ_INTE, /* slot 4 */
+	/* SLOT:  9, AD:20 */ 0xff,
+	/* SLOT: 10, AD:21 */ 0xff,
+	/* SLOT: 11, AD:22 */ 0xff,
+	/* SLOT: 12, AD:23 */ 0xff,
+	/* SLOT: 13, AD:24 */ 0xff,
+	/* SLOT: 14, AD:25 */ 0xff,
+	/* SLOT: 15, AD:26 */ 0xff,
+	/* SLOT: 16, AD:27 */ 0xff,
+	/* SLOT: 17, AD:28 */ 0xff,
+	/* SLOT: 18, AD:29 */ VRC5477_IRQ_IOPCI_INTC, /* vrc5477 ac97 */
+	/* SLOT: 19, AD:30 */ VRC5477_IRQ_IOPCI_INTB, /* vrc5477 usb peri */
+	/* SLOT: 20, AD:31 */ VRC5477_IRQ_IOPCI_INTA, /* vrc5477 usb host */
+};
+static unsigned char rockhopperII_irq_map[MAX_SLOT_NUM] = {
+	/* SLOT:  0, AD:11 */ 0xff,
+	/* SLOT:  1, AD:12 */ VRC5477_IRQ_INTB, /* onboard AMD PCNET */
+	/* SLOT:  2, AD:13 */ 0xff,
+	/* SLOT:  3, AD:14 */ 0xff,
+	/* SLOT:  4, AD:15 */ 14, /* M5229 ide ISA irq */
+	/* SLOT:  5, AD:16 */ VRC5477_IRQ_INTD, /* slot 3 */
+	/* SLOT:  6, AD:17 */ VRC5477_IRQ_INTA, /* slot 4 */
+	/* SLOT:  7, AD:18 */ VRC5477_IRQ_INTD, /* slot 5 */
+	/* SLOT:  8, AD:19 */ 0, /* M5457 modem nop */
+	/* SLOT:  9, AD:20 */ VRC5477_IRQ_INTA, /* slot 2 */
+	/* SLOT: 10, AD:21 */ 0xff,
+	/* SLOT: 11, AD:22 */ 0xff,
+	/* SLOT: 12, AD:23 */ 0xff,
+	/* SLOT: 13, AD:24 */ 0xff,
+	/* SLOT: 14, AD:25 */ 0xff,
+	/* SLOT: 15, AD:26 */ 0xff,
+	/* SLOT: 16, AD:27 */ 0xff,
+	/* SLOT: 17, AD:28 */ 0, /* M7101 PMU nop */
+	/* SLOT: 18, AD:29 */ VRC5477_IRQ_IOPCI_INTC, /* vrc5477 ac97 */
+	/* SLOT: 19, AD:30 */ VRC5477_IRQ_IOPCI_INTB, /* vrc5477 usb peri */
+	/* SLOT: 20, AD:31 */ VRC5477_IRQ_IOPCI_INTA, /* vrc5477 usb host */
+};
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	int slot_num;
+	unsigned char *slot_irq_map;
+	unsigned char irq;
+
+	/* 
+	 * We ignore the swizzled slot and pin values.  The original
+	 * pci_fixup_irq() codes largely base irq number on the dev slot 
+	 * numbers because except for one case they are unique even
+	 * though there are multiple pci buses.
+	 */
+
+	if (mips_machtype == MACH_NEC_ROCKHOPPERII)
+		slot_irq_map = rockhopperII_irq_map;
+	else
+		slot_irq_map = irq_map;
+
+	slot_num = PCI_SLOT(dev->devfn);
+	irq = slot_irq_map[slot_num];
+
+	db_assert(slot_num < MAX_SLOT_NUM);
+
+	db_assert(irq != 0xff);
+
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+
+	if (mips_machtype == MACH_NEC_ROCKHOPPERII) {
+		/* hack to distinquish overlapping slot 20s, one
+		 * on bus 0 (ALI USB on the M1535 on the backplane), 
+		 * and one on bus 2 (NEC USB controller on the CPU board)
+		 * Make the M1535 USB - ISA IRQ number 9.
+		 */
+		if (slot_num == 20 && dev->bus->number == 0) {
+			pci_write_config_byte(dev,
+					      PCI_INTERRUPT_LINE,
+					      9);
+			irq = 9;
+		}
+
+	}
+
+	return irq;
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
+
+void ddb_pci_reset_bus(void)
+{
+	u32 temp;
+
+	/*
+	 * I am not sure about the "official" procedure, the following
+	 * steps work as far as I know:
+	 * We first set PCI cold reset bit (bit 31) in PCICTRL-H.
+	 * Then we clear the PCI warm reset bit (bit 30) to 0 in PCICTRL-H.
+	 * The same is true for both PCI channels.
+	 */
+	temp = ddb_in32(DDB_PCICTL0_H);
+	temp |= 0x80000000;
+	ddb_out32(DDB_PCICTL0_H, temp);
+	temp &= ~0xc0000000;
+	ddb_out32(DDB_PCICTL0_H, temp);
+
+	temp = ddb_in32(DDB_PCICTL1_H);
+	temp |= 0x80000000;
+	ddb_out32(DDB_PCICTL1_H, temp);
+	temp &= ~0xc0000000;
+	ddb_out32(DDB_PCICTL1_H, temp);
+}
diff --git a/arch/mips/pci/pci-ev96100.c b/arch/mips/pci/pci-ev96100.c
new file mode 100644
index 0000000..f9457ea
--- /dev/null
+++ b/arch/mips/pci/pci-ev96100.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+static struct resource pci_io_resource = {
+	.name	= "io pci IO space",
+	.start	= 0x10000000,
+	.end	= 0x11ffffff,
+	.flags	= IORESOURCE_IO
+};
+
+static struct resource pci_mem_resource = {
+	.name	= "ext pci memory space",
+	.start	= 0x12000000,
+	.end	= 0x13ffffff,
+	.flags	= IORESOURCE_MEM
+};
+
+extern struct pci_ops gt96100_pci_ops;
+
+struct pci_controller ev96100_controller = {
+	.pci_ops	= &gt96100_pci_ops,
+	.io_resource	= &pci_io_resource,
+	.mem_resource	= &pci_mem_resource,
+};
+
+static void ev96100_pci_init(void)
+{
+	register_pci_controller(&ev96100_controller);
+}
+
+arch_initcall(ev96100_pci_init);
diff --git a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c
new file mode 100644
index 0000000..068e0e5
--- /dev/null
+++ b/arch/mips/pci/pci-ip27.c
@@ -0,0 +1,489 @@
+/*
+ * 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) 2003 Christoph Hellwig (hch@lst.de)
+ * Copyright (C) 1999, 2000, 04 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <asm/sn/arch.h>
+#include <asm/pci/bridge.h>
+#include <asm/paccess.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/sn0/hub.h>
+
+extern unsigned int allocate_irqno(void);
+
+/*
+ * Max #PCI busses we can handle; ie, max #PCI bridges.
+ */
+#define MAX_PCI_BUSSES		40
+
+/*
+ * Max #PCI devices (like scsi controllers) we handle on a bus.
+ */
+#define MAX_DEVICES_PER_PCIBUS	8
+
+/*
+ * XXX: No kmalloc available when we do our crosstalk scan,
+ * 	we should try to move it later in the boot process.
+ */
+static struct bridge_controller bridges[MAX_PCI_BUSSES];
+
+/*
+ * Translate from irq to software PCI bus number and PCI slot.
+ */
+struct bridge_controller *irq_to_bridge[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS];
+int irq_to_slot[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS];
+
+/*
+ * The Bridge ASIC supports both type 0 and type 1 access.  Type 1 is
+ * not really documented, so right now I can't write code which uses it.
+ * Therefore we use type 0 accesses for now even though they won't work
+ * correcly for PCI-to-PCI bridges.
+ *
+ * The function is complicated by the ultimate brokeness of the IOC3 chip
+ * which is used in SGI systems.  The IOC3 can only handle 32-bit PCI
+ * accesses and does only decode parts of it's address space.
+ */
+
+static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn,
+				 int where, int size, u32 * value)
+{
+	struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
+	bridge_t *bridge = bc->base;
+	int slot = PCI_SLOT(devfn);
+	int fn = PCI_FUNC(devfn);
+	volatile void *addr;
+	u32 cf, shift, mask;
+	int res;
+
+	addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID];
+	if (get_dbe(cf, (u32 *) addr))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/*
+	 * IOC3 is fucked fucked beyond believe ...  Don't even give the
+	 * generic PCI code a chance to look at it for real ...
+	 */
+	if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
+		goto oh_my_gawd;
+
+	addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)];
+
+	if (size == 1)
+		res = get_dbe(*value, (u8 *) addr);
+	else if (size == 2)
+		res = get_dbe(*value, (u16 *) addr);
+	else
+		res = get_dbe(*value, (u32 *) addr);
+
+	return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
+
+oh_my_gawd:
+
+	/*
+	 * IOC3 is fucked fucked beyond believe ...  Don't even give the
+	 * generic PCI code a chance to look at the wrong register.
+	 */
+	if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) {
+		*value = 0;
+		return PCIBIOS_SUCCESSFUL;
+	}
+
+	/*
+	 * IOC3 is fucked fucked beyond believe ...  Don't try to access
+	 * anything but 32-bit words ...
+	 */
+	addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
+
+	if (get_dbe(cf, (u32 *) addr))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	shift = ((where & 3) << 3);
+	mask = (0xffffffffU >> ((4 - size) << 3));
+	*value = (cf >> shift) & mask;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn,
+				 int where, int size, u32 * value)
+{
+	struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
+	bridge_t *bridge = bc->base;
+	int busno = bus->number;
+	int slot = PCI_SLOT(devfn);
+	int fn = PCI_FUNC(devfn);
+	volatile void *addr;
+	u32 cf, shift, mask;
+	int res;
+
+	bridge->b_pci_cfg = (busno << 16) | (slot << 11);
+	addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID];
+	if (get_dbe(cf, (u32 *) addr))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/*
+	 * IOC3 is fucked fucked beyond believe ...  Don't even give the
+	 * generic PCI code a chance to look at it for real ...
+	 */
+	if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
+		goto oh_my_gawd;
+
+	bridge->b_pci_cfg = (busno << 16) | (slot << 11);
+	addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))];
+
+	if (size == 1)
+		res = get_dbe(*value, (u8 *) addr);
+	else if (size == 2)
+		res = get_dbe(*value, (u16 *) addr);
+	else
+		res = get_dbe(*value, (u32 *) addr);
+
+	return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
+
+oh_my_gawd:
+
+	/*
+	 * IOC3 is fucked fucked beyond believe ...  Don't even give the
+	 * generic PCI code a chance to look at the wrong register.
+	 */
+	if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) {
+		*value = 0;
+		return PCIBIOS_SUCCESSFUL;
+	}
+
+	/*
+	 * IOC3 is fucked fucked beyond believe ...  Don't try to access
+	 * anything but 32-bit words ...
+	 */
+	bridge->b_pci_cfg = (busno << 16) | (slot << 11);
+	addr = &bridge->b_type1_cfg.c[(fn << 8) | where];
+
+	if (get_dbe(cf, (u32 *) addr))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	shift = ((where & 3) << 3);
+	mask = (0xffffffffU >> ((4 - size) << 3));
+	*value = (cf >> shift) & mask;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_read_config(struct pci_bus *bus, unsigned int devfn,
+			   int where, int size, u32 * value)
+{
+	if (bus->number > 0)
+		return pci_conf1_read_config(bus, devfn, where, size, value);
+
+	return pci_conf0_read_config(bus, devfn, where, size, value);
+}
+
+static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn,
+				  int where, int size, u32 value)
+{
+	struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
+	bridge_t *bridge = bc->base;
+	int slot = PCI_SLOT(devfn);
+	int fn = PCI_FUNC(devfn);
+	volatile void *addr;
+	u32 cf, shift, mask, smask;
+	int res;
+
+	addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID];
+	if (get_dbe(cf, (u32 *) addr))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/*
+	 * IOC3 is fucked fucked beyond believe ...  Don't even give the
+	 * generic PCI code a chance to look at it for real ...
+	 */
+	if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
+		goto oh_my_gawd;
+
+	addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)];
+
+	if (size == 1) {
+		res = put_dbe(value, (u8 *) addr);
+	} else if (size == 2) {
+		res = put_dbe(value, (u16 *) addr);
+	} else {
+		res = put_dbe(value, (u32 *) addr);
+	}
+
+	if (res)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return PCIBIOS_SUCCESSFUL;
+
+oh_my_gawd:
+
+	/*
+	 * IOC3 is fucked fucked beyond believe ...  Don't even give the
+	 * generic PCI code a chance to touch the wrong register.
+	 */
+	if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
+		return PCIBIOS_SUCCESSFUL;
+
+	/*
+	 * IOC3 is fucked fucked beyond believe ...  Don't try to access
+	 * anything but 32-bit words ...
+	 */
+	addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
+
+	if (get_dbe(cf, (u32 *) addr))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	shift = ((where & 3) << 3);
+	mask = (0xffffffffU >> ((4 - size) << 3));
+	smask = mask << shift;
+
+	cf = (cf & ~smask) | ((value & mask) << shift);
+	if (put_dbe(cf, (u32 *) addr))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn,
+				  int where, int size, u32 value)
+{
+	struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
+	bridge_t *bridge = bc->base;
+	int slot = PCI_SLOT(devfn);
+	int fn = PCI_FUNC(devfn);
+	int busno = bus->number;
+	volatile void *addr;
+	u32 cf, shift, mask, smask;
+	int res;
+
+	bridge->b_pci_cfg = (busno << 16) | (slot << 11);
+	addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID];
+	if (get_dbe(cf, (u32 *) addr))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/*
+	 * IOC3 is fucked fucked beyond believe ...  Don't even give the
+	 * generic PCI code a chance to look at it for real ...
+	 */
+	if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
+		goto oh_my_gawd;
+
+	addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))];
+
+	if (size == 1) {
+		res = put_dbe(value, (u8 *) addr);
+	} else if (size == 2) {
+		res = put_dbe(value, (u16 *) addr);
+	} else {
+		res = put_dbe(value, (u32 *) addr);
+	}
+
+	if (res)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return PCIBIOS_SUCCESSFUL;
+
+oh_my_gawd:
+
+	/*
+	 * IOC3 is fucked fucked beyond believe ...  Don't even give the
+	 * generic PCI code a chance to touch the wrong register.
+	 */
+	if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
+		return PCIBIOS_SUCCESSFUL;
+
+	/*
+	 * IOC3 is fucked fucked beyond believe ...  Don't try to access
+	 * anything but 32-bit words ...
+	 */
+	addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
+
+	if (get_dbe(cf, (u32 *) addr))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	shift = ((where & 3) << 3);
+	mask = (0xffffffffU >> ((4 - size) << 3));
+	smask = mask << shift;
+
+	cf = (cf & ~smask) | ((value & mask) << shift);
+	if (put_dbe(cf, (u32 *) addr))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_write_config(struct pci_bus *bus, unsigned int devfn,
+	int where, int size, u32 value)
+{
+	if (bus->number > 0)
+		return pci_conf1_write_config(bus, devfn, where, size, value);
+
+	return pci_conf0_write_config(bus, devfn, where, size, value);
+}
+
+static struct pci_ops bridge_pci_ops = {
+	.read = pci_read_config,
+	.write = pci_write_config,
+};
+
+int __init bridge_probe(nasid_t nasid, int widget_id, int masterwid)
+{
+	unsigned long offset = NODE_OFFSET(nasid);
+	struct bridge_controller *bc;
+	static int num_bridges = 0;
+	bridge_t *bridge;
+	int slot;
+
+	printk("a bridge\n");
+
+	/* XXX: kludge alert.. */
+	if (!num_bridges)
+		ioport_resource.end = ~0UL;
+
+	bc = &bridges[num_bridges];
+
+	bc->pc.pci_ops		= &bridge_pci_ops;
+	bc->pc.mem_resource	= &bc->mem;
+	bc->pc.io_resource	= &bc->io;
+
+	bc->pc.index		= num_bridges;
+
+	bc->mem.name		= "Bridge PCI MEM";
+	bc->pc.mem_offset	= offset;
+	bc->mem.start		= 0;
+	bc->mem.end		= ~0UL;
+	bc->mem.flags		= IORESOURCE_MEM;
+
+	bc->io.name		= "Bridge IO MEM";
+	bc->pc.io_offset	= offset;
+	bc->io.start		= 0UL;
+	bc->io.end		= ~0UL;
+	bc->io.flags		= IORESOURCE_IO;
+
+	bc->irq_cpu = smp_processor_id();
+	bc->widget_id = widget_id;
+	bc->nasid = nasid;
+
+	bc->baddr = (u64)masterwid << 60;
+	bc->baddr |= (1UL << 56);	/* Barrier set */
+
+	/*
+	 * point to this bridge
+	 */
+	bridge = (bridge_t *) RAW_NODE_SWIN_BASE(nasid, widget_id);
+
+	/*
+ 	 * Clear all pending interrupts.
+ 	 */
+	bridge->b_int_rst_stat = BRIDGE_IRR_ALL_CLR;
+
+	/*
+ 	 * Until otherwise set up, assume all interrupts are from slot 0
+ 	 */
+	bridge->b_int_device = 0x0;
+
+	/*
+ 	 * swap pio's to pci mem and io space (big windows)
+ 	 */
+	bridge->b_wid_control |= BRIDGE_CTRL_IO_SWAP |
+	                         BRIDGE_CTRL_MEM_SWAP;
+
+	/*
+	 * Hmm...  IRIX sets additional bits in the address which
+	 * are documented as reserved in the bridge docs.
+	 */
+	bridge->b_wid_int_upper = 0x8000 | (masterwid << 16);
+	bridge->b_wid_int_lower = 0x01800090;	/* PI_INT_PEND_MOD off*/
+	bridge->b_dir_map = (masterwid << 20);	/* DMA */
+	bridge->b_int_enable = 0;
+
+	for (slot = 0; slot < 8; slot ++) {
+		bridge->b_device[slot].reg |= BRIDGE_DEV_SWAP_DIR;
+		bc->pci_int[slot] = -1;
+	}
+	bridge->b_wid_tflush;     /* wait until Bridge PIO complete */
+
+	bc->base = bridge;
+
+	register_pci_controller(&bc->pc);
+
+	num_bridges++;
+
+	return 0;
+}
+
+/*
+ * All observed requests have pin == 1. We could have a global here, that
+ * gets incremented and returned every time - unfortunately, pci_map_irq
+ * may be called on the same device over and over, and need to return the
+ * same value. On O2000, pin can be 0 or 1, and PCI slots can be [0..7].
+ *
+ * A given PCI device, in general, should be able to intr any of the cpus
+ * on any one of the hubs connected to its xbow.
+ */
+int __devinit pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus);
+	int irq = bc->pci_int[slot];
+
+	if (irq == -1) {
+		irq = bc->pci_int[slot] = request_bridge_irq(bc);
+		if (irq < 0)
+			panic("Can't allocate interrupt for PCI device %s\n",
+			      pci_name(dev));
+	}
+
+	irq_to_bridge[irq] = bc;
+	irq_to_slot[irq] = slot;
+
+	return irq;
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
+
+/*
+ * Device might live on a subordinate PCI bus.  XXX Walk up the chain of buses
+ * to find the slot number in sense of the bridge device register.
+ * XXX This also means multiple devices might rely on conflicting bridge
+ * settings.
+ */
+
+static inline void pci_disable_swapping(struct pci_dev *dev)
+{
+	struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus);
+	bridge_t *bridge = bc->base;
+	int slot = PCI_SLOT(dev->devfn);
+
+	/* Turn off byte swapping */
+	bridge->b_device[slot].reg &= ~BRIDGE_DEV_SWAP_DIR;
+	bridge->b_widget.w_tflush;	/* Flush */
+}
+
+static inline void pci_enable_swapping(struct pci_dev *dev)
+{
+	struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus);
+	bridge_t *bridge = bc->base;
+	int slot = PCI_SLOT(dev->devfn);
+
+	/* Turn on byte swapping */
+	bridge->b_device[slot].reg |= BRIDGE_DEV_SWAP_DIR;
+	bridge->b_widget.w_tflush;	/* Flush */
+}
+
+static void __init pci_fixup_ioc3(struct pci_dev *d)
+{
+	pci_disable_swapping(d);
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3,
+	pci_fixup_ioc3);
diff --git a/arch/mips/pci/pci-ip32.c b/arch/mips/pci/pci-ip32.c
new file mode 100644
index 0000000..1faeb03
--- /dev/null
+++ b/arch/mips/pci/pci-ip32.c
@@ -0,0 +1,145 @@
+/*
+ * 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) 2000, 2001 Keith M Wesolowski
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <asm/ip32/mace.h>
+#include <asm/ip32/ip32_ints.h>
+
+#undef DEBUG_MACE_PCI
+
+/*
+ * Handle errors from the bridge.  This includes master and target aborts,
+ * various command and address errors, and the interrupt test.  This gets
+ * registered on the bridge error irq.  It's conceivable that some of these
+ * conditions warrant a panic.  Anybody care to say which ones?
+ */
+static irqreturn_t macepci_error(int irq, void *dev, struct pt_regs *regs)
+{
+	char s;
+	unsigned int flags = mace->pci.error;
+	unsigned int addr = mace->pci.error_addr;
+
+	if (flags & MACEPCI_ERROR_MEMORY_ADDR)
+		s = 'M';
+	else if (flags & MACEPCI_ERROR_CONFIG_ADDR)
+		s = 'C';
+	else
+		s = 'X';
+
+	if (flags & MACEPCI_ERROR_MASTER_ABORT) {
+		printk("MACEPCI: Master abort at 0x%08x (%c)\n", addr, s);
+		flags &= ~MACEPCI_ERROR_MASTER_ABORT;
+	}
+	if (flags & MACEPCI_ERROR_TARGET_ABORT) {
+		printk("MACEPCI: Target abort at 0x%08x (%c)\n", addr, s);
+		flags &= ~MACEPCI_ERROR_TARGET_ABORT;
+	}
+	if (flags & MACEPCI_ERROR_DATA_PARITY_ERR) {
+		printk("MACEPCI: Data parity error at 0x%08x (%c)\n", addr, s);
+		flags &= ~MACEPCI_ERROR_DATA_PARITY_ERR;
+	}
+	if (flags & MACEPCI_ERROR_RETRY_ERR) {
+		printk("MACEPCI: Retry error at 0x%08x (%c)\n", addr, s);
+		flags &= ~MACEPCI_ERROR_RETRY_ERR;
+	}
+	if (flags & MACEPCI_ERROR_ILLEGAL_CMD) {
+		printk("MACEPCI: Illegal command at 0x%08x (%c)\n", addr, s);
+		flags &= ~MACEPCI_ERROR_ILLEGAL_CMD;
+	}
+	if (flags & MACEPCI_ERROR_SYSTEM_ERR) {
+		printk("MACEPCI: System error at 0x%08x (%c)\n", addr, s);
+		flags &= ~MACEPCI_ERROR_SYSTEM_ERR;
+	}
+	if (flags & MACEPCI_ERROR_PARITY_ERR) {
+		printk("MACEPCI: Parity error at 0x%08x (%c)\n", addr, s);
+		flags &= ~MACEPCI_ERROR_PARITY_ERR;
+	}
+	if (flags & MACEPCI_ERROR_OVERRUN) {
+		printk("MACEPCI: Overrun error at 0x%08x (%c)\n", addr, s);
+		flags &= ~MACEPCI_ERROR_OVERRUN;
+	}
+	if (flags & MACEPCI_ERROR_SIG_TABORT) {
+		printk("MACEPCI: Signaled target abort (clearing)\n");
+		flags &= ~MACEPCI_ERROR_SIG_TABORT;
+	}
+	if (flags & MACEPCI_ERROR_INTERRUPT_TEST) {
+		printk("MACEPCI: Interrupt test triggered (clearing)\n");
+		flags &= ~MACEPCI_ERROR_INTERRUPT_TEST;
+	}
+
+	mace->pci.error = flags;
+
+	return IRQ_HANDLED;
+}
+
+
+extern struct pci_ops mace_pci_ops;
+#ifdef CONFIG_MIPS64
+static struct resource mace_pci_mem_resource = {
+	.name	= "SGI O2 PCI MEM",
+	.start	= MACEPCI_HI_MEMORY,
+	.end	= 0x2FFFFFFFFUL,
+	.flags	= IORESOURCE_MEM,
+};
+static struct resource mace_pci_io_resource = {
+	.name	= "SGI O2 PCI IO",
+	.start	= 0x00000000UL,
+	.end	= 0xffffffffUL,
+	.flags	= IORESOURCE_IO,
+};
+#define MACE_PCI_MEM_OFFSET 0x200000000
+#else
+static struct resource mace_pci_mem_resource = {
+	.name	= "SGI O2 PCI MEM",
+	.start	= MACEPCI_LOW_MEMORY,
+	.end	= MACEPCI_LOW_MEMORY + 0x2000000 - 1,
+	.flags	= IORESOURCE_MEM,
+};
+static struct resource mace_pci_io_resource = {
+	.name	= "SGI O2 PCI IO",
+	.start	= 0x00000000,
+	.end	= 0xFFFFFFFF,
+	.flags	= IORESOURCE_IO,
+};
+#define MACE_PCI_MEM_OFFSET (MACEPCI_LOW_MEMORY - 0x80000000)
+#endif
+static struct pci_controller mace_pci_controller = {
+	.pci_ops	= &mace_pci_ops,
+	.mem_resource	= &mace_pci_mem_resource,
+	.io_resource	= &mace_pci_io_resource,
+	.iommu		= 0,
+	.mem_offset	= MACE_PCI_MEM_OFFSET,
+	.io_offset	= 0,
+};
+
+static int __init mace_init(void)
+{
+	PCIBIOS_MIN_IO = 0x1000;
+
+	/* Clear any outstanding errors and enable interrupts */
+	mace->pci.error_addr = 0;
+	mace->pci.error = 0;
+	mace->pci.control = 0xff008500;
+
+	printk("MACE PCI rev %d\n", mace->pci.rev);
+
+	BUG_ON(request_irq(MACE_PCI_BRIDGE_IRQ, macepci_error, 0,
+			   "MACE PCI error", NULL));
+
+	ioport_resource.end = mace_pci_io_resource.end;
+	register_pci_controller(&mace_pci_controller);
+
+	return 0;
+}
+
+arch_initcall(mace_init);
diff --git a/arch/mips/pci/pci-jmr3927.c b/arch/mips/pci/pci-jmr3927.c
new file mode 100644
index 0000000..95a0287
--- /dev/null
+++ b/arch/mips/pci/pci-jmr3927.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *              ahennessy@mvista.com
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/jmr3927/jmr3927.h>
+#include <asm/debug.h>
+
+struct resource pci_io_resource = {
+	"IO MEM",
+	0x1000,			/* reserve regacy I/O space */
+	0x1000 + JMR3927_PCIIO_SIZE - 1,
+	IORESOURCE_IO
+};
+
+struct resource pci_mem_resource = {
+	"PCI MEM",
+	JMR3927_PCIMEM,
+	JMR3927_PCIMEM + JMR3927_PCIMEM_SIZE - 1,
+	IORESOURCE_MEM
+};
+
+extern struct pci_ops jmr3927_pci_ops;
+
+struct pci_controller jmr3927_controller = {
+	.pci_ops	= &jmr3927_pci_ops,
+	.io_resource	= &pci_io_resource,
+	.mem_resource	= &pci_mem_resource,
+	.mem_offset	= JMR3927_PCIMEM;
+};
diff --git a/arch/mips/pci/pci-lasat.c b/arch/mips/pci/pci-lasat.c
new file mode 100644
index 0000000..ae3cc4b
--- /dev/null
+++ b/arch/mips/pci/pci-lasat.c
@@ -0,0 +1,95 @@
+/*
+ * 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) 2000, 2001, 04 Keith M Wesolowski
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <asm/bootinfo.h>
+
+extern struct pci_ops nile4_pci_ops;
+extern struct pci_ops gt64120_pci_ops;
+static struct resource lasat_pci_mem_resource = {
+	.name	= "LASAT PCI MEM",
+	.start	= 0x18000000,
+	.end	= 0x19FFFFFF,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct resource lasat_pci_io_resource = {
+	.name	= "LASAT PCI IO",
+	.start	= 0x1a000000,
+	.end	= 0x1bFFFFFF,
+	.flags	= IORESOURCE_IO,
+};
+
+static struct pci_controller lasat_pci_controller = {
+	.mem_resource	= &lasat_pci_mem_resource,
+	.io_resource	= &lasat_pci_io_resource,
+};
+
+static int __init lasat_pci_setup(void)
+{
+ 	printk("PCI: starting\n");
+
+        switch (mips_machtype) {
+            case MACH_LASAT_100:
+                lasat_pci_controller.pci_ops = &gt64120_pci_ops;
+                break;
+            case MACH_LASAT_200:
+                lasat_pci_controller.pci_ops = &nile4_pci_ops;
+                break;
+            default:
+                panic("pcibios_init: mips_machtype incorrect");
+        }
+
+	register_pci_controller(&lasat_pci_controller);
+        return 0;
+}
+early_initcall(lasat_pci_setup);
+
+#define LASATINT_ETH1   0
+#define LASATINT_ETH0   1
+#define LASATINT_HDC    2
+#define LASATINT_COMP   3
+#define LASATINT_HDLC   4
+#define LASATINT_PCIA   5
+#define LASATINT_PCIB   6
+#define LASATINT_PCIC   7
+#define LASATINT_PCID   8
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+    switch (slot) {
+        case 1:
+            return LASATINT_PCIA;   /* Expansion Module 0 */
+        case 2:
+            return LASATINT_PCIB;   /* Expansion Module 1 */
+        case 3:
+            return LASATINT_PCIC;   /* Expansion Module 2 */
+        case 4:
+            return LASATINT_ETH1;   /* Ethernet 1 (LAN 2) */
+        case 5:
+            return LASATINT_ETH0;   /* Ethernet 0 (LAN 1) */
+        case 6:
+            return LASATINT_HDC;    /* IDE controller */
+        default:
+            return 0xff;            /* Illegal */
+    }
+
+    return -1;
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
diff --git a/arch/mips/pci/pci-ocelot-c.c b/arch/mips/pci/pci-ocelot-c.c
new file mode 100644
index 0000000..1d84d36
--- /dev/null
+++ b/arch/mips/pci/pci-ocelot-c.c
@@ -0,0 +1,143 @@
+/*
+ * 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) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <asm/mv64340.h>
+
+#include <linux/init.h>
+
+/*
+ * We assume the address ranges have already been setup appropriately by
+ * the firmware.  PMON in case of the Ocelot C does that.
+ */
+static struct resource mv_pci_io_mem0_resource = {
+	.name	= "MV64340 PCI0 IO MEM",
+	.flags	= IORESOURCE_IO
+};
+
+static struct resource mv_pci_mem0_resource = {
+	.name	= "MV64340 PCI0 MEM",
+	.flags	= IORESOURCE_MEM
+};
+
+static struct mv_pci_controller mv_bus0_controller = {
+	.pcic = {
+		.pci_ops	= &mv_pci_ops,
+		.mem_resource	= &mv_pci_mem0_resource,
+		.io_resource	= &mv_pci_io_mem0_resource,
+	},
+	.config_addr	= MV64340_PCI_0_CONFIG_ADDR,
+	.config_vreg	= MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG,
+};
+
+static uint32_t mv_io_base, mv_io_size;
+
+static void mv64340_pci0_init(void)
+{
+	uint32_t mem0_base, mem0_size;
+	uint32_t io_base, io_size;
+
+	io_base = MV_READ(MV64340_PCI_0_IO_BASE_ADDR) << 16;
+	io_size = (MV_READ(MV64340_PCI_0_IO_SIZE) + 1) << 16;
+	mem0_base = MV_READ(MV64340_PCI_0_MEMORY0_BASE_ADDR) << 16;
+	mem0_size = (MV_READ(MV64340_PCI_0_MEMORY0_SIZE) + 1) << 16;
+
+	mv_pci_io_mem0_resource.start		= 0;
+	mv_pci_io_mem0_resource.end		= io_size - 1;
+	mv_pci_mem0_resource.start		= mem0_base;
+	mv_pci_mem0_resource.end		= mem0_base + mem0_size - 1;
+	mv_bus0_controller.pcic.mem_offset	= mem0_base;
+	mv_bus0_controller.pcic.io_offset	= 0;
+
+	ioport_resource.end		= io_size - 1;
+
+	register_pci_controller(&mv_bus0_controller.pcic);
+
+	mv_io_base = io_base;
+	mv_io_size = io_size;
+}
+
+static struct resource mv_pci_io_mem1_resource = {
+	.name	= "MV64340 PCI1 IO MEM",
+	.flags	= IORESOURCE_IO
+};
+
+static struct resource mv_pci_mem1_resource = {
+	.name	= "MV64340 PCI1 MEM",
+	.flags	= IORESOURCE_MEM
+};
+
+static struct mv_pci_controller mv_bus1_controller = {
+	.pcic = {
+		.pci_ops	= &mv_pci_ops,
+		.mem_resource	= &mv_pci_mem1_resource,
+		.io_resource	= &mv_pci_io_mem1_resource,
+	},
+	.config_addr	= MV64340_PCI_1_CONFIG_ADDR,
+	.config_vreg	= MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG,
+};
+
+static __init void mv64340_pci1_init(void)
+{
+	uint32_t mem0_base, mem0_size;
+	uint32_t io_base, io_size;
+
+	io_base = MV_READ(MV64340_PCI_1_IO_BASE_ADDR) << 16;
+	io_size = (MV_READ(MV64340_PCI_1_IO_SIZE) + 1) << 16;
+	mem0_base = MV_READ(MV64340_PCI_1_MEMORY0_BASE_ADDR) << 16;
+	mem0_size = (MV_READ(MV64340_PCI_1_MEMORY0_SIZE) + 1) << 16;
+
+	/*
+	 * Here we assume the I/O window of second bus to be contiguous with
+	 * the first.  A gap is no problem but would waste address space for
+	 * remapping the port space.
+	 */
+	mv_pci_io_mem1_resource.start		= mv_io_size;
+	mv_pci_io_mem1_resource.end		= mv_io_size + io_size - 1;
+	mv_pci_mem1_resource.start		= mem0_base;
+	mv_pci_mem1_resource.end		= mem0_base + mem0_size - 1;
+	mv_bus1_controller.pcic.mem_offset	= mem0_base;
+	mv_bus1_controller.pcic.io_offset	= 0;
+
+	ioport_resource.end		= io_base + io_size -mv_io_base - 1;
+
+	register_pci_controller(&mv_bus1_controller.pcic);
+
+	mv_io_size = io_base + io_size - mv_io_base;
+}
+
+static __init int __init ocelot_c_pci_init(void)
+{
+	unsigned long io_v_base;
+	uint32_t enable;
+
+	enable = ~MV_READ(MV64340_BASE_ADDR_ENABLE);
+
+	/*
+	 * We require at least one enabled I/O or PCI memory window or we
+	 * will ignore this PCI bus.  We ignore PCI windows 1, 2 and 3.
+	 */
+	if (enable & (0x01 <<  9) || enable & (0x01 << 10))
+		mv64340_pci0_init();
+
+	if (enable & (0x01 << 14) || enable & (0x01 << 15))
+		mv64340_pci1_init();
+
+	if (mv_io_size) {
+		io_v_base = (unsigned long) ioremap(mv_io_base, mv_io_size);
+		if (!io_v_base)
+			panic("Could not ioremap I/O port range");
+
+		set_io_port_base(io_v_base);
+	}
+
+	return 0;
+}
+
+arch_initcall(ocelot_c_pci_init);
diff --git a/arch/mips/pci/pci-ocelot-g.c b/arch/mips/pci/pci-ocelot-g.c
new file mode 100644
index 0000000..1e34301
--- /dev/null
+++ b/arch/mips/pci/pci-ocelot-g.c
@@ -0,0 +1,97 @@
+/*
+ * 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) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * This doesn't really fly - but I don't have a GT64240 system for testing.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <asm/gt64240.h>
+
+/*
+ * We assume these address ranges have been programmed into the GT-64240 by
+ * the firmware.  PMON in case of the Ocelot G does that.  Note the size of
+ * the I/O range is completly stupid; I/O mappings are limited to at most
+ * 256 bytes by the PCI spec and deprecated; and just to make things worse
+ * apparently many devices don't decode more than 64k of I/O space.
+ */
+
+#define gt_io_size	0x20000000UL
+#define gt_io_base	0xe0000000UL
+
+static struct resource gt_pci_mem0_resource = {
+	.name	= "MV64240 PCI0 MEM",
+	.start	= 0xc0000000UL,
+	.end	= 0xcfffffffUL,
+	.flags	= IORESOURCE_MEM
+};
+
+static struct resource gt_pci_io_mem0_resource = {
+	.name	= "MV64240 PCI0 IO MEM",
+	.start	= 0xe0000000UL,
+	.end	= 0xefffffffUL,
+	.flags	= IORESOURCE_IO
+};
+
+static struct mv_pci_controller gt_bus0_controller = {
+	.pcic = {
+		.pci_ops	= &mv_pci_ops,
+		.mem_resource	= &gt_pci_mem0_resource,
+		.mem_offset	= 0xc0000000UL,
+		.io_resource	= &gt_pci_io_mem0_resource,
+		.io_offset	= 0x00000000UL
+	},
+	.config_addr	= PCI_0CONFIGURATION_ADDRESS,
+	.config_vreg	= PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,
+};
+
+static struct resource gt_pci_mem1_resource = {
+	.name	= "MV64240 PCI1 MEM",
+	.start	= 0xd0000000UL,
+	.end	= 0xdfffffffUL,
+	.flags	= IORESOURCE_MEM
+};
+
+static struct resource gt_pci_io_mem1_resource = {
+	.name	= "MV64240 PCI1 IO MEM",
+	.start	= 0xf0000000UL,
+	.end	= 0xffffffffUL,
+	.flags	= IORESOURCE_IO
+};
+
+static struct mv_pci_controller gt_bus1_controller = {
+	.pcic = {
+		.pci_ops	= &mv_pci_ops,
+		.mem_resource	= &gt_pci_mem1_resource,
+		.mem_offset	= 0xd0000000UL,
+		.io_resource	= &gt_pci_io_mem1_resource,
+		.io_offset	= 0x10000000UL
+	},
+	.config_addr	= PCI_1CONFIGURATION_ADDRESS,
+	.config_vreg	= PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER,
+};
+
+static __init int __init ocelot_g_pci_init(void)
+{
+	unsigned long io_v_base;
+
+	if (gt_io_size) {
+		io_v_base = (unsigned long) ioremap(gt_io_base, gt_io_size);
+		if (!io_v_base)
+			panic("Could not ioremap I/O port range");
+
+		set_io_port_base(io_v_base);
+	}
+
+	register_pci_controller(&gt_bus0_controller.pcic);
+	register_pci_controller(&gt_bus1_controller.pcic);
+
+	return 0;
+}
+
+arch_initcall(ocelot_g_pci_init);
diff --git a/arch/mips/pci/pci-ocelot.c b/arch/mips/pci/pci-ocelot.c
new file mode 100644
index 0000000..3da8a4e
--- /dev/null
+++ b/arch/mips/pci/pci-ocelot.c
@@ -0,0 +1,107 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ * Galileo Evaluation Boards PCI support.
+ *
+ * The general-purpose functions to read/write and configure the GT64120A's
+ * PCI registers (function names start with pci0 or pci1) are either direct
+ * copies of functions written by Galileo Technology, or are modifications
+ * of their functions to work with Linux 2.4 vs Linux 2.2.  These functions
+ * are Copyright - Galileo Technology.
+ *
+ * Other functions are derived from other MIPS PCI implementations, or were
+ * written by RidgeRun, Inc,  Copyright (C) 2000 RidgeRun, Inc.
+ *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/cache.h>
+#include <asm/pci.h>
+#include <asm/io.h>
+#include <asm/gt64120.h>
+
+static inline unsigned int pci0ReadConfigReg(unsigned int offset)
+{
+	unsigned int DataForRegCf8;
+	unsigned int data;
+
+	DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |
+			 (PCI_FUNC(device->devfn) << 8) |
+			 (offset & ~0x3)) | 0x80000000;
+	GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);
+	GT_READ(GT_PCI0_CFGDATA_OFS, &data);
+
+	return data;
+}
+
+static inline void pci0WriteConfigReg(unsigned int offset, unsigned int data)
+{
+	unsigned int DataForRegCf8;
+
+	DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |
+			 (PCI_FUNC(device->devfn) << 8) |
+			 (offset & ~0x3)) | 0x80000000;
+	GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);
+	GT_WRITE(GT_PCI0_CFGDATA_OFS, data);
+}
+
+static struct resource ocelot_mem_resource = {
+	iomem_resource.start = GT_PCI_MEM_BASE;
+	iomem_resource.end = GT_PCI_MEM_BASE + GT_PCI_MEM_BASE - 1;
+};
+
+static struct resource ocelot_io_resource = {
+	ioport_resource.start = GT_PCI_IO_BASE;
+	ioport_resource.end = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1;
+};
+
+static struct pci_controller ocelot_pci_controller = {
+	.pci_ops	= gt64120_pci_ops;
+	.mem_resource	= &ocelot_mem_resource;
+	.io_resource	= &ocelot_io_resource;
+};
+
+static int __init ocelot_pcibios_init(void)
+{
+	u32 tmp;
+
+	GT_READ(GT_PCI0_CMD_OFS, &tmp);
+	GT_READ(GT_PCI0_BARE_OFS, &tmp);
+
+	/*
+	 * You have to enable bus mastering to configure any other
+	 * card on the bus.
+	 */
+	tmp = pci0ReadConfigReg(PCI_COMMAND);
+	tmp |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
+	pci0WriteConfigReg(PCI_COMMAND, tmp);
+
+	register_pci_controller(&ocelot_pci_controller);
+}
+
+arch_initcall(ocelot_pcibios_init);
diff --git a/arch/mips/pci/pci-sb1250.c b/arch/mips/pci/pci-sb1250.c
new file mode 100644
index 0000000..7cca3bd
--- /dev/null
+++ b/arch/mips/pci/pci-sb1250.c
@@ -0,0 +1,292 @@
+/*
+ * Copyright (C) 2001,2002,2003 Broadcom Corporation
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * BCM1250-specific PCI support
+ *
+ * This module provides the glue between Linux's PCI subsystem
+ * and the hardware.  We basically provide glue for accessing
+ * configuration space, and set up the translation for I/O
+ * space accesses.
+ *
+ * To access configuration space, we use ioremap.  In the 32-bit
+ * kernel, this consumes either 4 or 8 page table pages, and 16MB of
+ * kernel mapped memory.  Hopefully neither of these should be a huge
+ * problem.
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/tty.h>
+
+#include <asm/io.h>
+
+#include <asm/sibyte/sb1250_defs.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_scd.h>
+#include <asm/sibyte/board.h>
+
+/*
+ * Macros for calculating offsets into config space given a device
+ * structure or dev/fun/reg
+ */
+#define CFGOFFSET(bus,devfn,where) (((bus)<<16) + ((devfn)<<8) + (where))
+#define CFGADDR(bus,devfn,where)   CFGOFFSET((bus)->number,(devfn),where)
+
+static void *cfg_space;
+
+#define PCI_BUS_ENABLED	1
+#define LDT_BUS_ENABLED	2
+#define PCI_DEVICE_MODE	4
+
+static int sb1250_bus_status = 0;
+
+#define PCI_BRIDGE_DEVICE  0
+#define LDT_BRIDGE_DEVICE  1
+
+#ifdef CONFIG_SIBYTE_HAS_LDT
+/*
+ * HT's level-sensitive interrupts require EOI, which is generated
+ * through a 4MB memory-mapped region
+ */
+unsigned long ldt_eoi_space;
+#endif
+
+/*
+ * Read/write 32-bit values in config space.
+ */
+static inline u32 READCFG32(u32 addr)
+{
+	return *(u32 *) (cfg_space + (addr & ~3));
+}
+
+static inline void WRITECFG32(u32 addr, u32 data)
+{
+	*(u32 *) (cfg_space + (addr & ~3)) = data;
+}
+
+int pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	return dev->irq;
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
+
+/*
+ * Some checks before doing config cycles:
+ * In PCI Device Mode, hide everything on bus 0 except the LDT host
+ * bridge.  Otherwise, access is controlled by bridge MasterEn bits.
+ */
+static int sb1250_pci_can_access(struct pci_bus *bus, int devfn)
+{
+	u32 devno;
+
+	if (!(sb1250_bus_status & (PCI_BUS_ENABLED | PCI_DEVICE_MODE)))
+		return 0;
+
+	if (bus->number == 0) {
+		devno = PCI_SLOT(devfn);
+		if (devno == LDT_BRIDGE_DEVICE)
+			return (sb1250_bus_status & LDT_BUS_ENABLED) != 0;
+		else if (sb1250_bus_status & PCI_DEVICE_MODE)
+			return 0;
+		else
+			return 1;
+	} else
+		return 1;
+}
+
+/*
+ * Read/write access functions for various sizes of values
+ * in config space.  Return all 1's for disallowed accesses
+ * for a kludgy but adequate simulation of master aborts.
+ */
+
+static int sb1250_pcibios_read(struct pci_bus *bus, unsigned int devfn,
+			       int where, int size, u32 * val)
+{
+	u32 data = 0;
+
+	if ((size == 2) && (where & 1))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	else if ((size == 4) && (where & 3))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (sb1250_pci_can_access(bus, devfn))
+		data = READCFG32(CFGADDR(bus, devfn, where));
+	else
+		data = 0xFFFFFFFF;
+
+	if (size == 1)
+		*val = (data >> ((where & 3) << 3)) & 0xff;
+	else if (size == 2)
+		*val = (data >> ((where & 3) << 3)) & 0xffff;
+	else
+		*val = data;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int sb1250_pcibios_write(struct pci_bus *bus, unsigned int devfn,
+				int where, int size, u32 val)
+{
+	u32 cfgaddr = CFGADDR(bus, devfn, where);
+	u32 data = 0;
+
+	if ((size == 2) && (where & 1))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	else if ((size == 4) && (where & 3))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (!sb1250_pci_can_access(bus, devfn))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	data = READCFG32(cfgaddr);
+
+	if (size == 1)
+		data = (data & ~(0xff << ((where & 3) << 3))) |
+		    (val << ((where & 3) << 3));
+	else if (size == 2)
+		data = (data & ~(0xffff << ((where & 3) << 3))) |
+		    (val << ((where & 3) << 3));
+	else
+		data = val;
+
+	WRITECFG32(cfgaddr, data);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops sb1250_pci_ops = {
+	.read	= sb1250_pcibios_read,
+	.write	= sb1250_pcibios_write,
+};
+
+static struct resource sb1250_mem_resource = {
+	.name	= "SB1250 PCI MEM",
+	.start	= 0x40000000UL,
+	.end	= 0x5fffffffUL,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct resource sb1250_io_resource = {
+	.name	= "SB1250 PCI I/O",
+	.start	= 0x00000000UL,
+	.end	= 0x01ffffffUL,
+	.flags	= IORESOURCE_IO,
+};
+
+struct pci_controller sb1250_controller = {
+	.pci_ops	= &sb1250_pci_ops,
+	.mem_resource	= &sb1250_mem_resource,
+	.io_resource	= &sb1250_io_resource,
+};
+
+static int __init sb1250_pcibios_init(void)
+{
+	uint32_t cmdreg;
+	uint64_t reg;
+	extern int pci_probe_only;
+
+	/* CFE will assign PCI resources */
+	pci_probe_only = 1;
+
+	/* Avoid ISA compat ranges.  */
+	PCIBIOS_MIN_IO = 0x00008000UL;
+	PCIBIOS_MIN_MEM = 0x01000000UL;
+
+	/* Set I/O resource limits.  */
+	ioport_resource.end = 0x01ffffffUL;	/* 32MB accessible by sb1250 */
+	iomem_resource.end = 0xffffffffUL;	/* no HT support yet */
+
+	cfg_space =
+	    ioremap(A_PHYS_LDTPCI_CFG_MATCH_BITS, 16 * 1024 * 1024);
+
+	/*
+	 * See if the PCI bus has been configured by the firmware.
+	 */
+	reg = *((volatile uint64_t *) IOADDR(A_SCD_SYSTEM_CFG));
+	if (!(reg & M_SYS_PCI_HOST)) {
+		sb1250_bus_status |= PCI_DEVICE_MODE;
+	} else {
+		cmdreg =
+		    READCFG32(CFGOFFSET
+			      (0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0),
+			       PCI_COMMAND));
+		if (!(cmdreg & PCI_COMMAND_MASTER)) {
+			printk
+			    ("PCI: Skipping PCI probe.  Bus is not initialized.\n");
+			iounmap(cfg_space);
+			return 0;
+		}
+		sb1250_bus_status |= PCI_BUS_ENABLED;
+	}
+
+	/*
+	 * Establish mappings in KSEG2 (kernel virtual) to PCI I/O
+	 * space.  Use "match bytes" policy to make everything look
+	 * little-endian.  So, you need to also set
+	 * CONFIG_SWAP_IO_SPACE, but this is the combination that
+	 * works correctly with most of Linux's drivers.
+	 * XXX ehs: Should this happen in PCI Device mode?
+	 */
+
+	set_io_port_base((unsigned long)
+			 ioremap(A_PHYS_LDTPCI_IO_MATCH_BYTES, 65536));
+	isa_slot_offset = (unsigned long)
+	    ioremap(A_PHYS_LDTPCI_IO_MATCH_BYTES_32, 1024 * 1024);
+
+#ifdef CONFIG_SIBYTE_HAS_LDT
+	/*
+	 * Also check the LDT bridge's enable, just in case we didn't
+	 * initialize that one.
+	 */
+
+	cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(LDT_BRIDGE_DEVICE, 0),
+				     PCI_COMMAND));
+	if (cmdreg & PCI_COMMAND_MASTER) {
+		sb1250_bus_status |= LDT_BUS_ENABLED;
+
+		/*
+		 * Need bits 23:16 to convey vector number.  Note that
+		 * this consumes 4MB of kernel-mapped memory
+		 * (Kseg2/Kseg3) for 32-bit kernel.
+		 */
+		ldt_eoi_space = (unsigned long)
+		    ioremap(A_PHYS_LDT_SPECIAL_MATCH_BYTES,
+			    4 * 1024 * 1024);
+	}
+#endif
+
+	register_pci_controller(&sb1250_controller);
+
+#ifdef CONFIG_VGA_CONSOLE
+	take_over_console(&vga_con, 0, MAX_NR_CONSOLES - 1, 1);
+#endif
+	return 0;
+}
+arch_initcall(sb1250_pcibios_init);
diff --git a/arch/mips/pci/pci-vr41xx.c b/arch/mips/pci/pci-vr41xx.c
new file mode 100644
index 0000000..f3ccbf7
--- /dev/null
+++ b/arch/mips/pci/pci-vr41xx.c
@@ -0,0 +1,291 @@
+/*
+ *  pci-vr41xx.c, PCI Control Unit routines for the NEC VR4100 series.
+ *
+ *  Copyright (C) 2001-2003 MontaVista Software Inc.
+ *    Author: Yoichi Yuasa <yyuasa@mvista.com or source@mvista.com>
+ *  Copyright (C) 2004  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC VR4122 and VR4131 are supported.
+ */
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <asm/vr41xx/vr41xx.h>
+
+#include "pci-vr41xx.h"
+
+extern struct pci_ops vr41xx_pci_ops;
+
+static struct pci_master_address_conversion pci_master_memory1 = {
+	.bus_base_address	= PCI_MASTER_MEM1_BUS_BASE_ADDRESS,
+	.address_mask		= PCI_MASTER_MEM1_ADDRESS_MASK,
+	.pci_base_address	= PCI_MASTER_MEM1_PCI_BASE_ADDRESS,
+};
+
+static struct pci_target_address_conversion pci_target_memory1 = {
+	.address_mask		= PCI_TARGET_MEM1_ADDRESS_MASK,
+	.bus_base_address	= PCI_TARGET_MEM1_BUS_BASE_ADDRESS,
+};
+
+static struct pci_master_address_conversion pci_master_io = {
+	.bus_base_address	= PCI_MASTER_IO_BUS_BASE_ADDRESS,
+	.address_mask		= PCI_MASTER_IO_ADDRESS_MASK,
+	.pci_base_address	= PCI_MASTER_IO_PCI_BASE_ADDRESS,
+};
+
+static struct pci_mailbox_address pci_mailbox = {
+	.base_address		= PCI_MAILBOX_BASE_ADDRESS,
+};
+
+static struct pci_target_address_window pci_target_window1 = {
+	.base_address		= PCI_TARGET_WINDOW1_BASE_ADDRESS,
+};
+
+static struct resource pci_mem_resource = {
+	.name   = "PCI Memory resources",
+	.start  = PCI_MEM_RESOURCE_START,
+	.end    = PCI_MEM_RESOURCE_END,
+	.flags  = IORESOURCE_MEM,
+};
+
+static struct resource pci_io_resource = {
+	.name   = "PCI I/O resources",
+	.start  = PCI_IO_RESOURCE_START,
+	.end    = PCI_IO_RESOURCE_END,
+	.flags  = IORESOURCE_IO,
+};
+
+static struct pci_controller_unit_setup vr41xx_pci_controller_unit_setup = {
+	.master_memory1				= &pci_master_memory1,
+	.target_memory1				= &pci_target_memory1,
+	.master_io				= &pci_master_io,
+	.exclusive_access			= CANNOT_LOCK_FROM_DEVICE,
+	.wait_time_limit_from_irdy_to_trdy	= 0,
+	.mailbox				= &pci_mailbox,
+	.target_window1				= &pci_target_window1,
+	.master_latency_timer			= 0x80,
+	.retry_limit				= 0,
+	.arbiter_priority_control		= PCI_ARBITRATION_MODE_FAIR,
+	.take_away_gnt_mode			= PCI_TAKE_AWAY_GNT_DISABLE,
+};
+
+static struct pci_controller vr41xx_pci_controller = {
+	.pci_ops        = &vr41xx_pci_ops,
+	.mem_resource	= &pci_mem_resource,
+	.io_resource	= &pci_io_resource,
+};
+
+void __init vr41xx_pciu_setup(struct pci_controller_unit_setup *setup)
+{
+	vr41xx_pci_controller_unit_setup = *setup;
+}
+
+static int __init vr41xx_pciu_init(void)
+{
+	struct pci_controller_unit_setup *setup;
+	struct pci_master_address_conversion *master;
+	struct pci_target_address_conversion *target;
+	struct pci_mailbox_address *mailbox;
+	struct pci_target_address_window *window;
+	unsigned long vtclock, pci_clock_max;
+	uint32_t val;
+
+	setup = &vr41xx_pci_controller_unit_setup;
+
+	/* Disable PCI interrupt */
+	vr41xx_disable_pciint();
+
+	/* Supply VTClock to PCIU */
+	vr41xx_supply_clock(PCIU_CLOCK);
+
+	/* Dummy write, waiting for supply of VTClock. */
+	vr41xx_disable_pciint();
+
+	/* Select PCI clock */
+	if (setup->pci_clock_max != 0)
+		pci_clock_max = setup->pci_clock_max;
+	else
+		pci_clock_max = PCI_CLOCK_MAX;
+	vtclock = vr41xx_get_vtclock_frequency();
+	if (vtclock < pci_clock_max)
+		writel(EQUAL_VTCLOCK, PCICLKSELREG);
+	else if ((vtclock / 2) < pci_clock_max)
+		writel(HALF_VTCLOCK, PCICLKSELREG);
+	else if (current_cpu_data.processor_id >= PRID_VR4131_REV2_1 &&
+	         (vtclock / 3) < pci_clock_max)
+		writel(ONE_THIRD_VTCLOCK, PCICLKSELREG);
+	else if ((vtclock / 4) < pci_clock_max)
+		writel(QUARTER_VTCLOCK, PCICLKSELREG);
+	else {
+		printk(KERN_ERR "PCI Clock is over 33MHz.\n");
+		return -EINVAL;
+	}
+
+	/* Supply PCI clock by PCI bus */
+	vr41xx_supply_clock(PCI_CLOCK);
+
+	if (setup->master_memory1 != NULL) {
+		master = setup->master_memory1;
+		val = IBA(master->bus_base_address) |
+		      MASTER_MSK(master->address_mask) |
+		      WINEN |
+		      PCIA(master->pci_base_address);
+		writel(val, PCIMMAW1REG);
+	} else {
+		val = readl(PCIMMAW1REG);
+		val &= ~WINEN;
+		writel(val, PCIMMAW1REG);
+	}
+
+	if (setup->master_memory2 != NULL) {
+		master = setup->master_memory2;
+		val = IBA(master->bus_base_address) |
+		      MASTER_MSK(master->address_mask) |
+		      WINEN |
+		      PCIA(master->pci_base_address);
+		writel(val, PCIMMAW2REG);
+	} else {
+		val = readl(PCIMMAW2REG);
+		val &= ~WINEN;
+		writel(val, PCIMMAW2REG);
+	}
+
+	if (setup->target_memory1 != NULL) {
+		target = setup->target_memory1;
+		val = TARGET_MSK(target->address_mask) |
+		      WINEN |
+		      ITA(target->bus_base_address);
+		writel(val, PCITAW1REG);
+	} else {
+		val = readl(PCITAW1REG);
+		val &= ~WINEN;
+		writel(val, PCITAW1REG);
+	}
+
+	if (setup->target_memory2 != NULL) {
+		target = setup->target_memory2;
+		val = TARGET_MSK(target->address_mask) |
+		      WINEN |
+		      ITA(target->bus_base_address);
+		writel(val, PCITAW2REG);
+	} else {
+		val = readl(PCITAW2REG);
+		val &= ~WINEN;
+		writel(val, PCITAW2REG);
+	}
+
+	if (setup->master_io != NULL) {
+		master = setup->master_io;
+		val = IBA(master->bus_base_address) |
+		      MASTER_MSK(master->address_mask) |
+		      WINEN |
+		      PCIIA(master->pci_base_address);
+		writel(val, PCIMIOAWREG);
+	} else {
+		val = readl(PCIMIOAWREG);
+		val &= ~WINEN;
+		writel(val, PCIMIOAWREG);
+	}
+
+	if (setup->exclusive_access == CANNOT_LOCK_FROM_DEVICE)
+		writel(UNLOCK, PCIEXACCREG);
+	else
+		writel(0, PCIEXACCREG);
+
+	if (current_cpu_data.cputype == CPU_VR4122)
+		writel(TRDYV(setup->wait_time_limit_from_irdy_to_trdy), PCITRDYVREG);
+
+	writel(MLTIM(setup->master_latency_timer), LATTIMEREG);
+
+	if (setup->mailbox != NULL) {
+		mailbox = setup->mailbox;
+		val = MBADD(mailbox->base_address) | TYPE_32BITSPACE |
+		      MSI_MEMORY | PREF_APPROVAL;
+		writel(val, MAILBAREG);
+	}
+
+	if (setup->target_window1) {
+		window = setup->target_window1;
+		val = PMBA(window->base_address) | TYPE_32BITSPACE |
+		      MSI_MEMORY | PREF_APPROVAL;
+		writel(val, PCIMBA1REG);
+	}
+
+	if (setup->target_window2) {
+		window = setup->target_window2;
+		val = PMBA(window->base_address) | TYPE_32BITSPACE |
+		      MSI_MEMORY | PREF_APPROVAL;
+		writel(val, PCIMBA2REG);
+	}
+
+	val = readl(RETVALREG);
+	val &= ~RTYVAL_MASK;
+	val |= RTYVAL(setup->retry_limit);
+	writel(val, RETVALREG);
+
+	val = readl(PCIAPCNTREG);
+	val &= ~(TKYGNT | PAPC);
+
+	switch (setup->arbiter_priority_control) {
+	case PCI_ARBITRATION_MODE_ALTERNATE_0:
+		val |= PAPC_ALTERNATE_0;
+		break;
+	case PCI_ARBITRATION_MODE_ALTERNATE_B:
+		val |= PAPC_ALTERNATE_B;
+		break;
+	default:
+		val |= PAPC_FAIR;
+		break;
+	}
+
+	if (setup->take_away_gnt_mode == PCI_TAKE_AWAY_GNT_ENABLE)
+		val |= TKYGNT_ENABLE;
+
+	writel(val, PCIAPCNTREG);
+
+	writel(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
+	       PCI_COMMAND_PARITY | PCI_COMMAND_SERR, COMMANDREG);
+
+	/* Clear bus error */
+	readl(BUSERRADREG);
+
+	writel(BLOODY_CONFIG_DONE, PCIENREG);
+
+	if (setup->mem_resource != NULL)
+		vr41xx_pci_controller.mem_resource = setup->mem_resource;
+
+	if (setup->io_resource != NULL) {
+		vr41xx_pci_controller.io_resource = setup->io_resource;
+	} else {
+		set_io_port_base(IO_PORT_BASE);
+		ioport_resource.start = IO_PORT_RESOURCE_START;
+		ioport_resource.end = IO_PORT_RESOURCE_END;
+	}
+
+	register_pci_controller(&vr41xx_pci_controller);
+
+	return 0;
+}
+
+arch_initcall(vr41xx_pciu_init);
diff --git a/arch/mips/pci/pci-vr41xx.h b/arch/mips/pci/pci-vr41xx.h
new file mode 100644
index 0000000..23815c8
--- /dev/null
+++ b/arch/mips/pci/pci-vr41xx.h
@@ -0,0 +1,151 @@
+/*
+ *  pci-vr41xx.h, Include file for PCI Control Unit of the NEC VR4100 series.
+ *
+ *  Copyright (C) 2002  MontaVista Software Inc.
+ *    Author: Yoichi Yuasa <yyuasa@mvista.com or source@mvista.com>
+ *  Copyright (C) 2004  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __PCI_VR41XX_H
+#define __PCI_VR41XX_H
+
+#define PCIMMAW1REG		KSEG1ADDR(0x0f000c00)
+#define PCIMMAW2REG		KSEG1ADDR(0x0f000c04)
+#define PCITAW1REG		KSEG1ADDR(0x0f000c08)
+#define PCITAW2REG		KSEG1ADDR(0x0f000c0c)
+#define PCIMIOAWREG		KSEG1ADDR(0x0f000c10)
+ #define IBA(addr)		((addr) & 0xff000000U)
+ #define MASTER_MSK(mask)	(((mask) >> 11) & 0x000fe000U)
+ #define PCIA(addr)		(((addr) >> 24) & 0x000000ffU)
+ #define TARGET_MSK(mask)	(((mask) >> 8) & 0x000fe000U)
+ #define ITA(addr)		(((addr) >> 24) & 0x000000ffU)
+ #define PCIIA(addr)		(((addr) >> 24) & 0x000000ffU)
+ #define WINEN			0x1000U
+#define PCICONFDREG		KSEG1ADDR(0x0f000c14)
+#define PCICONFAREG		KSEG1ADDR(0x0f000c18)
+#define PCIMAILREG		KSEG1ADDR(0x0f000c1c)
+#define BUSERRADREG		KSEG1ADDR(0x0f000c24)
+ #define EA(reg)		((reg) &0xfffffffc)
+
+#define INTCNTSTAREG		KSEG1ADDR(0x0f000c28)
+ #define MABTCLR		0x80000000U
+ #define TRDYCLR		0x40000000U
+ #define PARCLR			0x20000000U
+ #define MBCLR			0x10000000U
+ #define SERRCLR		0x08000000U
+ #define RTYCLR			0x04000000U
+ #define MABCLR			0x02000000U
+ #define TABCLR			0x01000000U
+ /* RFU */
+ #define MABTMSK		0x00008000U
+ #define TRDYMSK		0x00004000U
+ #define PARMSK			0x00002000U
+ #define MBMSK			0x00001000U
+ #define SERRMSK		0x00000800U
+ #define RTYMSK			0x00000400U
+ #define MABMSK			0x00000200U
+ #define TABMSK			0x00000100U
+ #define IBAMABT		0x00000080U
+ #define TRDYRCH		0x00000040U
+ #define PAR			0x00000020U
+ #define MB			0x00000010U
+ #define PCISERR		0x00000008U
+ #define RTYRCH			0x00000004U
+ #define MABORT			0x00000002U
+ #define TABORT			0x00000001U
+
+#define PCIEXACCREG		KSEG1ADDR(0x0f000c2c)
+ #define UNLOCK			0x2U
+ #define EAREQ			0x1U
+#define PCIRECONTREG		KSEG1ADDR(0x0f000c30)
+ #define RTRYCNT(reg)		((reg) & 0x000000ffU)
+#define PCIENREG		KSEG1ADDR(0x0f000c34)
+ #define BLOODY_CONFIG_DONE	0x4U
+#define PCICLKSELREG		KSEG1ADDR(0x0f000c38)
+ #define EQUAL_VTCLOCK		0x2U
+ #define HALF_VTCLOCK		0x0U
+ #define ONE_THIRD_VTCLOCK	0x3U
+ #define QUARTER_VTCLOCK	0x1U
+#define PCITRDYVREG		KSEG1ADDR(0x0f000c3c)
+ #define TRDYV(val)		((uint32_t)(val) & 0xffU)
+#define PCICLKRUNREG		KSEG1ADDR(0x0f000c60)
+
+#define VENDORIDREG		KSEG1ADDR(0x0f000d00)
+#define DEVICEIDREG		KSEG1ADDR(0x0f000d00)
+#define COMMANDREG		KSEG1ADDR(0x0f000d04)
+#define STATUSREG		KSEG1ADDR(0x0f000d04)
+#define REVIDREG		KSEG1ADDR(0x0f000d08)
+#define CLASSREG		KSEG1ADDR(0x0f000d08)
+#define CACHELSREG		KSEG1ADDR(0x0f000d0c)
+#define LATTIMEREG		KSEG1ADDR(0x0f000d0c)
+ #define MLTIM(val)		(((uint32_t)(val) << 7) & 0xff00U)
+#define MAILBAREG		KSEG1ADDR(0x0f000d10)
+#define PCIMBA1REG		KSEG1ADDR(0x0f000d14)
+#define PCIMBA2REG		KSEG1ADDR(0x0f000d18)
+ #define MBADD(base)		((base) & 0xfffff800U)
+ #define PMBA(base)		((base) & 0xffe00000U)
+ #define PREF			0x8U
+ #define PREF_APPROVAL		0x8U
+ #define PREF_DISAPPROVAL	0x0U
+ #define TYPE			0x6U
+ #define TYPE_32BITSPACE	0x0U
+ #define MSI			0x1U
+ #define MSI_MEMORY		0x0U
+#define INTLINEREG		KSEG1ADDR(0x0f000d3c)
+#define INTPINREG		KSEG1ADDR(0x0f000d3c)
+#define RETVALREG		KSEG1ADDR(0x0f000d40)
+#define PCIAPCNTREG		KSEG1ADDR(0x0f000d40)
+ #define TKYGNT			0x04000000U
+ #define TKYGNT_ENABLE		0x04000000U
+ #define TKYGNT_DISABLE		0x00000000U
+ #define PAPC			0x03000000U
+ #define PAPC_ALTERNATE_B	0x02000000U
+ #define PAPC_ALTERNATE_0	0x01000000U
+ #define PAPC_FAIR		0x00000000U
+ #define RTYVAL(val)		(((uint32_t)(val) << 7) & 0xff00U)
+ #define RTYVAL_MASK		0xff00U
+
+#define PCI_CLOCK_MAX		33333333U
+
+/*
+ * Default setup
+ */
+#define PCI_MASTER_MEM1_BUS_BASE_ADDRESS	0x10000000U
+#define PCI_MASTER_MEM1_ADDRESS_MASK		0x7c000000U
+#define PCI_MASTER_MEM1_PCI_BASE_ADDRESS	0x10000000U
+
+#define PCI_TARGET_MEM1_ADDRESS_MASK		0x08000000U
+#define PCI_TARGET_MEM1_BUS_BASE_ADDRESS	0x00000000U
+
+#define PCI_MASTER_IO_BUS_BASE_ADDRESS		0x16000000U
+#define PCI_MASTER_IO_ADDRESS_MASK		0x7e000000U
+#define PCI_MASTER_IO_PCI_BASE_ADDRESS		0x00000000U
+
+#define PCI_MAILBOX_BASE_ADDRESS		0x00000000U
+
+#define PCI_TARGET_WINDOW1_BASE_ADDRESS		0x00000000U
+
+#define IO_PORT_BASE		KSEG1ADDR(PCI_MASTER_IO_BUS_BASE_ADDRESS)
+#define IO_PORT_RESOURCE_START	PCI_MASTER_IO_PCI_BASE_ADDRESS
+#define IO_PORT_RESOURCE_END	(~PCI_MASTER_IO_ADDRESS_MASK & PCI_MASTER_ADDRESS_MASK)
+
+#define PCI_IO_RESOURCE_START	0x01000000UL
+#define PCI_IO_RESOURCE_END	0x01ffffffUL
+
+#define PCI_MEM_RESOURCE_START	0x11000000UL
+#define PCI_MEM_RESOURCE_END	0x13ffffffUL
+
+#endif /* __PCI_VR41XX_H */
diff --git a/arch/mips/pci/pci-yosemite.c b/arch/mips/pci/pci-yosemite.c
new file mode 100644
index 0000000..dac9ed4
--- /dev/null
+++ b/arch/mips/pci/pci-yosemite.c
@@ -0,0 +1,60 @@
+/*
+ * 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) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <asm/titan_dep.h>
+
+extern struct pci_ops titan_pci_ops;
+
+static struct resource py_mem_resource = {
+	"Titan PCI MEM", 0xe0000000UL, 0xe3ffffffUL, IORESOURCE_MEM
+};
+
+/*
+ * PMON really reserves 16MB of I/O port space but that's stupid, nothing
+ * needs that much since allocations are limited to 256 bytes per device
+ * anyway.  So we just claim 64kB here.
+ */
+#define TITAN_IO_SIZE	0x0000ffffUL
+#define TITAN_IO_BASE	0xe8000000UL
+
+static struct resource py_io_resource = {
+	"Titan IO MEM", 0x00001000UL, TITAN_IO_SIZE - 1, IORESOURCE_IO,
+};
+
+static struct pci_controller py_controller = {
+	.pci_ops	= &titan_pci_ops,
+	.mem_resource	= &py_mem_resource,
+	.mem_offset	= 0x00000000UL,
+	.io_resource	= &py_io_resource,
+	.io_offset	= 0x00000000UL
+};
+
+static char ioremap_failed[] __initdata = "Could not ioremap I/O port range";
+
+static int __init pmc_yosemite_setup(void)
+{
+	unsigned long io_v_base;
+
+	io_v_base = (unsigned long) ioremap(TITAN_IO_BASE, TITAN_IO_SIZE);
+	if (!io_v_base)
+		panic(ioremap_failed);
+
+	set_io_port_base(io_v_base);
+	TITAN_WRITE(RM9000x2_OCD_LKM7, TITAN_READ(RM9000x2_OCD_LKM7) | 1);
+
+	ioport_resource.end = TITAN_IO_SIZE - 1;
+
+	register_pci_controller(&py_controller);
+
+	return 0;
+}
+
+arch_initcall(pmc_yosemite_setup);
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
new file mode 100644
index 0000000..8141dff
--- /dev/null
+++ b/arch/mips/pci/pci.c
@@ -0,0 +1,304 @@
+/*
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Copyright (C) 2003, 04 Ralf Baechle (ralf@linux-mips.org)
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+
+/*
+ * Indicate whether we respect the PCI setup left by the firmware.
+ *
+ * Make this long-lived  so that we know when shutting down
+ * whether we probed only or not.
+ */
+int pci_probe_only;
+
+#define PCI_ASSIGN_ALL_BUSSES	1
+
+unsigned int pci_probe = PCI_ASSIGN_ALL_BUSSES;
+
+/*
+ * The PCI controller list.
+ */
+
+struct pci_controller *hose_head, **hose_tail = &hose_head;
+struct pci_controller *pci_isa_hose;
+
+unsigned long PCIBIOS_MIN_IO	= 0x0000;
+unsigned long PCIBIOS_MIN_MEM	= 0;
+
+/*
+ * We need to avoid collisions with `mirrored' VGA ports
+ * and other strange ISA hardware, so we always want the
+ * addresses to be allocated in the 0x000-0x0ff region
+ * modulo 0x400.
+ *
+ * Why? Because some silly external IO cards only decode
+ * the low 10 bits of the IO address. The 0x00-0xff region
+ * is reserved for motherboard devices that decode all 16
+ * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
+ * but we want to try to avoid allocating at 0x2900-0x2bff
+ * which might have be mirrored at 0x0100-0x03ff..
+ */
+void
+pcibios_align_resource(void *data, struct resource *res,
+		       unsigned long size, unsigned long align)
+{
+	struct pci_dev *dev = data;
+	struct pci_controller *hose = dev->sysdata;
+	unsigned long start = res->start;
+
+	if (res->flags & IORESOURCE_IO) {
+		/* Make sure we start at our min on all hoses */
+		if (start < PCIBIOS_MIN_IO + hose->io_resource->start)
+			start = PCIBIOS_MIN_IO + hose->io_resource->start;
+
+		/*
+		 * Put everything into 0x00-0xff region modulo 0x400
+		 */
+		if (start & 0x300)
+			start = (start + 0x3ff) & ~0x3ff;
+	} else if (res->flags & IORESOURCE_MEM) {
+		/* Make sure we start at our min on all hoses */
+		if (start < PCIBIOS_MIN_MEM + hose->mem_resource->start)
+			start = PCIBIOS_MIN_MEM + hose->mem_resource->start;
+	}
+
+	res->start = start;
+}
+
+struct pci_controller * __init alloc_pci_controller(void)
+{
+	return alloc_bootmem(sizeof(struct pci_controller));
+}
+
+void __init register_pci_controller(struct pci_controller *hose)
+{
+	*hose_tail = hose;
+	hose_tail = &hose->next;
+}
+
+/* Most MIPS systems have straight-forward swizzling needs.  */
+
+static inline u8 bridge_swizzle(u8 pin, u8 slot)
+{
+	return (((pin - 1) + slot) % 4) + 1;
+}
+
+static u8 __init common_swizzle(struct pci_dev *dev, u8 *pinp)
+{
+	u8 pin = *pinp;
+
+	while (dev->bus->parent) {
+		pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
+		/* Move up the chain of bridges. */
+		dev = dev->bus->self;
+        }
+	*pinp = pin;
+
+	/* The slot is the slot of the last bridge. */
+	return PCI_SLOT(dev->devfn);
+}
+
+static int __init pcibios_init(void)
+{
+	struct pci_controller *hose;
+	struct pci_bus *bus;
+	int next_busno;
+	int need_domain_info = 0;
+
+	/* Scan all of the recorded PCI controllers.  */
+	for (next_busno = 0, hose = hose_head; hose; hose = hose->next) {
+
+		if (request_resource(&iomem_resource, hose->mem_resource) < 0)
+			goto out;
+		if (request_resource(&ioport_resource, hose->io_resource) < 0)
+			goto out_free_mem_resource;
+
+		if (!hose->iommu)
+			PCI_DMA_BUS_IS_PHYS = 1;
+
+		bus = pci_scan_bus(next_busno, hose->pci_ops, hose);
+		hose->bus = bus;
+		hose->need_domain_info = need_domain_info;
+		next_busno = bus->subordinate + 1;
+		/* Don't allow 8-bit bus number overflow inside the hose -
+		   reserve some space for bridges. */ 
+		if (next_busno > 224) {
+			next_busno = 0;
+			need_domain_info = 1;
+		}
+		continue;
+
+out_free_mem_resource:
+		release_resource(hose->mem_resource);
+
+out:
+		printk(KERN_WARNING
+		       "Skipping PCI bus scan due to resource conflict\n");
+	}
+
+	if (!pci_probe_only)
+		pci_assign_unassigned_resources();
+	pci_fixup_irqs(common_swizzle, pcibios_map_irq);
+
+	return 0;
+}
+
+subsys_initcall(pcibios_init);
+
+static int pcibios_enable_resources(struct pci_dev *dev, int mask)
+{
+	u16 cmd, old_cmd;
+	int idx;
+	struct resource *r;
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	old_cmd = cmd;
+	for(idx=0; idx<6; idx++) {
+		/* Only set up the requested stuff */
+		if (!(mask & (1<<idx)))
+			continue;
+
+		r = &dev->resource[idx];
+		if (!r->start && r->end) {
+			printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev));
+			return -EINVAL;
+		}
+		if (r->flags & IORESOURCE_IO)
+			cmd |= PCI_COMMAND_IO;
+		if (r->flags & IORESOURCE_MEM)
+			cmd |= PCI_COMMAND_MEMORY;
+	}
+	if (dev->resource[PCI_ROM_RESOURCE].start)
+		cmd |= PCI_COMMAND_MEMORY;
+	if (cmd != old_cmd) {
+		printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd);
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+	return 0;
+}
+
+/*
+ *  If we set up a device for bus mastering, we need to check the latency
+ *  timer as certain crappy BIOSes forget to set it properly.
+ */
+unsigned int pcibios_max_latency = 255;
+
+void pcibios_set_master(struct pci_dev *dev)
+{
+	u8 lat;
+	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+	if (lat < 16)
+		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
+	else if (lat > pcibios_max_latency)
+		lat = pcibios_max_latency;
+	else
+		return;
+	printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n",
+	       pci_name(dev), lat);
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
+}
+
+unsigned int pcibios_assign_all_busses(void)
+{
+	return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
+}
+
+int pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+	int err;
+
+	if ((err = pcibios_enable_resources(dev, mask)) < 0)
+		return err;
+
+	return pcibios_plat_dev_init(dev);
+}
+
+static void __init pcibios_fixup_device_resources(struct pci_dev *dev,
+	struct pci_bus *bus)
+{
+	/* Update device resources.  */
+	struct pci_controller *hose = (struct pci_controller *)bus->sysdata;
+	unsigned long offset = 0;
+	int i;
+
+	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+		if (!dev->resource[i].start)
+			continue;
+		if (dev->resource[i].flags & IORESOURCE_IO)
+			offset = hose->io_offset;
+		else if (dev->resource[i].flags & IORESOURCE_MEM)
+			offset = hose->mem_offset;
+
+		dev->resource[i].start += offset;
+		dev->resource[i].end += offset;
+	}
+}
+
+void __devinit pcibios_fixup_bus(struct pci_bus *bus)
+{
+	/* Propagate hose info into the subordinate devices.  */
+
+	struct pci_controller *hose = bus->sysdata;
+	struct list_head *ln;
+	struct pci_dev *dev = bus->self;
+
+	if (!dev) {
+		bus->resource[0] = hose->io_resource;
+		bus->resource[1] = hose->mem_resource;
+	} else if (pci_probe_only &&
+		   (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
+		pci_read_bridge_bases(bus);
+		pcibios_fixup_device_resources(dev, bus);
+	} 
+
+	for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
+		struct pci_dev *dev = pci_dev_b(ln);
+
+		if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
+			pcibios_fixup_device_resources(dev, bus);
+	}
+}
+
+void __init
+pcibios_update_irq(struct pci_dev *dev, int irq)
+{
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+}
+
+void __devinit
+pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
+			 struct resource *res)
+{
+	struct pci_controller *hose = (struct pci_controller *)dev->sysdata;
+	unsigned long offset = 0;
+
+	if (res->flags & IORESOURCE_IO)
+		offset = hose->io_offset;
+	else if (res->flags & IORESOURCE_MEM)
+		offset = hose->mem_offset;
+
+	region->start = res->start - offset;
+	region->end = res->end - offset;
+}
+
+#ifdef CONFIG_HOTPLUG
+EXPORT_SYMBOL(pcibios_resource_to_bus);
+EXPORT_SYMBOL(PCIBIOS_MIN_IO);
+EXPORT_SYMBOL(PCIBIOS_MIN_MEM);
+#endif
+
+char *pcibios_setup(char *str)
+{
+	return str;
+}
diff --git a/arch/mips/pmc-sierra/yosemite/Makefile b/arch/mips/pmc-sierra/yosemite/Makefile
new file mode 100644
index 0000000..ae96a71
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the PMC-Sierra Titan
+#
+
+obj-y    += irq-handler.o irq.o i2c-yosemite.o prom.o py-console.o setup.o
+
+obj-$(CONFIG_KGDB)		+= dbg_io.o
+obj-$(CONFIG_SMP)		+= smp.o
diff --git a/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c b/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c
new file mode 100644
index 0000000..b067988
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c
@@ -0,0 +1,171 @@
+/*
+ *  arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c
+ *
+ *  Copyright (C) 2003 PMC-Sierra Inc.
+ *  Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Description:
+ *
+ * This code reads the ATMEL 24CXX EEPROM. The PMC-Sierra Yosemite board uses the ATMEL
+ * 24C32/24C64 which uses two byte addressing as compared to 24C16. Note that this program
+ * uses the serial port like /dev/ttyS0, to communicate with the EEPROM. Hence, you are 
+ * expected to have a connectivity from the EEPROM to the serial port. This program does
+ * __not__ communicate using the I2C protocol
+ */
+
+#include "atmel_read_eeprom.h"
+
+static void delay(int delay)
+{
+	while (delay--);
+}
+
+static void send_bit(unsigned char bit)
+{
+	scl_lo;
+	delay(TXX);
+	if (bit)
+		sda_hi;
+	else
+		sda_lo;
+
+	delay(TXX);
+	scl_hi;
+	delay(TXX);
+}
+
+static void send_ack(void)
+{
+	send_bit(0);
+}
+
+static void send_byte(unsigned char byte)
+{
+	int	i = 0;
+	
+	for (i = 7; i >= 0; i--) 
+		send_bit((byte >> i) & 0x01);
+}
+	
+static void send_start(void)
+{
+	sda_hi; 
+	delay(TXX);
+	scl_hi;
+	delay(TXX);
+	sda_lo;
+	delay(TXX);
+}
+
+static void send_stop(void)
+{
+	sda_lo;
+	delay(TXX);
+	scl_hi;
+	delay(TXX);
+	sda_hi;
+	delay(TXX);
+}
+
+static void do_idle(void)
+{
+	sda_hi;
+	scl_hi;
+	vcc_off;
+}
+
+static int recv_bit(void)
+{
+	int	status;
+
+	scl_lo;
+	delay(TXX);
+	sda_hi;
+	delay(TXX);
+	scl_hi;
+	delay(TXX);
+
+	return 1;
+}
+
+static unsigned char recv_byte(void) {
+        int i;
+        unsigned char byte=0;
+
+        for (i=7;i>=0;i--)                             
+                byte |= (recv_bit() << i);
+ 
+        return byte;
+}
+
+static int recv_ack(void)
+{
+	unsigned int	ack;
+
+	ack = (unsigned int)recv_bit();
+	scl_lo;
+
+	if (ack) {
+		do_idle();
+		printk(KERN_ERR "Error reading the Atmel 24C32/24C64 EEPROM \n");
+		return -1;
+	}
+
+	return ack;
+}
+
+/*
+ * This function does the actual read of the EEPROM. It needs the buffer into which the
+ * read data is copied, the size of the EEPROM being read and the buffer size
+ */
+int read_eeprom(char *buffer, int eeprom_size, int size)
+{
+	int	i = 0, err;
+
+	send_start();
+	send_byte(W_HEADER);
+	recv_ack();
+
+	/* EEPROM with size of more then 2K need two byte addressing */
+	if (eeprom_size > 2048) {
+		send_byte(0x00);
+		recv_ack();
+	}
+
+	send_start();
+	send_byte(R_HEADER);
+	err = recv_ack();
+	if (err == -1)
+		return err;
+
+	for (i = 0; i < size; i++) {
+		*buffer++ = recv_byte();
+		send_ack();
+	}
+
+	/* Note : We should do some check if the buffer contains correct information */
+
+	send_stop();
+}
diff --git a/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h b/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h
new file mode 100644
index 0000000..d27566d
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h
@@ -0,0 +1,69 @@
+/*
+ *  arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c
+ *
+ *  Copyright (C) 2003 PMC-Sierra Inc.
+ *  Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *  Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Header file for atmel_read_eeprom.c 
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include <asm/pci.h>
+#include <asm/io.h>
+#include <linux/init.h>
+#include <asm/termios.h>
+#include <asm/ioctls.h>
+#include <linux/ioctl.h>
+#include <linux/fcntl.h>
+
+#define	DEFAULT_PORT 	"/dev/ttyS0"	/* Port to open */
+#define	TXX		0 		/* Dummy loop for spinning */
+
+#define	BLOCK_SEL	0x00		
+#define	SLAVE_ADDR	0xa0
+#define	READ_BIT	0x01
+#define	WRITE_BIT	0x00
+#define	R_HEADER	SLAVE_ADDR + BLOCK_SEL + READ_BIT
+#define	W_HEADER	SLAVE_ADDR + BLOCK_SEL + WRITE_BIT
+
+/*
+ * Clock, Voltages and Data
+ */
+#define	vcc_off		(ioctl(fd, TIOCSBRK, 0))
+#define	vcc_on		(ioctl(fd, TIOCCBRK, 0))
+#define	sda_hi		(ioctl(fd, TIOCMBIS, &dtr))
+#define	sda_lo		(ioctl(fd, TIOCMBIC, &dtr))
+#define	scl_lo		(ioctl(fd, TIOCMBIC, &rts))
+#define	scl_hi		(ioctl(fd, TIOCMBIS, &rts))
+
+const char rts = TIOCM_RTS;
+const char dtr = TIOCM_DTR;
+int fd;
+
diff --git a/arch/mips/pmc-sierra/yosemite/dbg_io.c b/arch/mips/pmc-sierra/yosemite/dbg_io.c
new file mode 100644
index 0000000..0f659c9
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/dbg_io.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright 2003 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Support for KGDB for the Yosemite board. We make use of single serial
+ * port to be used for KGDB as well as console. The second serial port
+ * seems to be having a problem. Single IRQ is allocated for both the
+ * ports. Hence, the interrupt routing code needs to figure out whether
+ * the interrupt came from channel A or B.
+ */
+
+#include <asm/serial.h>
+
+/*
+ * Baud rate, Parity, Data and Stop bit settings for the
+ * serial port on the Yosemite. Note that the Early printk
+ * patch has been added. So, we should be all set to go
+ */
+#define	YOSEMITE_BAUD_2400	2400
+#define	YOSEMITE_BAUD_4800	4800
+#define	YOSEMITE_BAUD_9600	9600
+#define	YOSEMITE_BAUD_19200	19200
+#define	YOSEMITE_BAUD_38400	38400
+#define	YOSEMITE_BAUD_57600	57600
+#define	YOSEMITE_BAUD_115200	115200
+
+#define	YOSEMITE_PARITY_NONE	0
+#define	YOSEMITE_PARITY_ODD	0x08
+#define	YOSEMITE_PARITY_EVEN	0x18
+#define	YOSEMITE_PARITY_MARK	0x28
+#define	YOSEMITE_PARITY_SPACE	0x38
+
+#define	YOSEMITE_DATA_5BIT	0x0
+#define	YOSEMITE_DATA_6BIT	0x1
+#define	YOSEMITE_DATA_7BIT	0x2
+#define	YOSEMITE_DATA_8BIT	0x3
+
+#define	YOSEMITE_STOP_1BIT	0x0
+#define	YOSEMITE_STOP_2BIT	0x4
+
+/* This is crucial */
+#define	SERIAL_REG_OFS		0x1
+
+#define	SERIAL_RCV_BUFFER	0x0
+#define	SERIAL_TRANS_HOLD	0x0
+#define	SERIAL_SEND_BUFFER	0x0
+#define	SERIAL_INTR_ENABLE	(1 * SERIAL_REG_OFS)
+#define	SERIAL_INTR_ID		(2 * SERIAL_REG_OFS)
+#define	SERIAL_DATA_FORMAT	(3 * SERIAL_REG_OFS)
+#define	SERIAL_LINE_CONTROL	(3 * SERIAL_REG_OFS)
+#define	SERIAL_MODEM_CONTROL	(4 * SERIAL_REG_OFS)
+#define	SERIAL_RS232_OUTPUT	(4 * SERIAL_REG_OFS)
+#define	SERIAL_LINE_STATUS	(5 * SERIAL_REG_OFS)
+#define	SERIAL_MODEM_STATUS	(6 * SERIAL_REG_OFS)
+#define	SERIAL_RS232_INPUT	(6 * SERIAL_REG_OFS)
+#define	SERIAL_SCRATCH_PAD	(7 * SERIAL_REG_OFS)
+
+#define	SERIAL_DIVISOR_LSB	(0 * SERIAL_REG_OFS)
+#define	SERIAL_DIVISOR_MSB	(1 * SERIAL_REG_OFS)
+
+/*
+ * Functions to READ and WRITE to serial port 0
+ */
+#define	SERIAL_READ(ofs)		(*((volatile unsigned char*)	\
+					(TITAN_SERIAL_BASE + ofs)))
+
+#define	SERIAL_WRITE(ofs, val)		((*((volatile unsigned char*)	\
+					(TITAN_SERIAL_BASE + ofs))) = val)
+
+/*
+ * Functions to READ and WRITE to serial port 1
+ */
+#define	SERIAL_READ_1(ofs)		(*((volatile unsigned char*)	\
+					(TITAN_SERIAL_BASE_1 + ofs)
+
+#define	SERIAL_WRITE_1(ofs, val)	((*((volatile unsigned char*)	\
+					(TITAN_SERIAL_BASE_1 + ofs))) = val)
+
+/*
+ * Second serial port initialization
+ */
+void init_second_port(void)
+{
+	/* Disable Interrupts */
+	SERIAL_WRITE_1(SERIAL_LINE_CONTROL, 0x0);
+	SERIAL_WRITE_1(SERIAL_INTR_ENABLE, 0x0);
+
+	{
+		unsigned int divisor;
+
+		SERIAL_WRITE_1(SERIAL_LINE_CONTROL, 0x80);
+		divisor = TITAN_SERIAL_BASE_BAUD / YOSEMITE_BAUD_115200;
+		SERIAL_WRITE_1(SERIAL_DIVISOR_LSB, divisor & 0xff);
+
+		SERIAL_WRITE_1(SERIAL_DIVISOR_MSB,
+			       (divisor & 0xff00) >> 8);
+		SERIAL_WRITE_1(SERIAL_LINE_CONTROL, 0x0);
+	}
+
+	SERIAL_WRITE_1(SERIAL_DATA_FORMAT, YOSEMITE_DATA_8BIT |
+		       YOSEMITE_PARITY_NONE | YOSEMITE_STOP_1BIT);
+
+	/* Enable Interrupts */
+	SERIAL_WRITE_1(SERIAL_INTR_ENABLE, 0xf);
+}
+
+/* Initialize the serial port for KGDB debugging */
+void debugInit(unsigned int baud, unsigned char data, unsigned char parity,
+	       unsigned char stop)
+{
+	/* Disable Interrupts */
+	SERIAL_WRITE(SERIAL_LINE_CONTROL, 0x0);
+	SERIAL_WRITE(SERIAL_INTR_ENABLE, 0x0);
+
+	{
+		unsigned int divisor;
+
+		SERIAL_WRITE(SERIAL_LINE_CONTROL, 0x80);
+
+		divisor = TITAN_SERIAL_BASE_BAUD / baud;
+		SERIAL_WRITE(SERIAL_DIVISOR_LSB, divisor & 0xff);
+
+		SERIAL_WRITE(SERIAL_DIVISOR_MSB, (divisor & 0xff00) >> 8);
+		SERIAL_WRITE(SERIAL_LINE_CONTROL, 0x0);
+	}
+
+	SERIAL_WRITE(SERIAL_DATA_FORMAT, data | parity | stop);
+}
+
+static int remoteDebugInitialized = 0;
+
+unsigned char getDebugChar(void)
+{
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(YOSEMITE_BAUD_115200,
+			  YOSEMITE_DATA_8BIT,
+			  YOSEMITE_PARITY_NONE, YOSEMITE_STOP_1BIT);
+	}
+
+	while ((SERIAL_READ(SERIAL_LINE_STATUS) & 0x1) == 0);
+	return SERIAL_READ(SERIAL_RCV_BUFFER);
+}
+
+int putDebugChar(unsigned char byte)
+{
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(YOSEMITE_BAUD_115200,
+			  YOSEMITE_DATA_8BIT,
+			  YOSEMITE_PARITY_NONE, YOSEMITE_STOP_1BIT);
+	}
+
+	while ((SERIAL_READ(SERIAL_LINE_STATUS) & 0x20) == 0);
+	SERIAL_WRITE(SERIAL_SEND_BUFFER, byte);
+
+	return 1;
+}
diff --git a/arch/mips/pmc-sierra/yosemite/ht-irq.c b/arch/mips/pmc-sierra/yosemite/ht-irq.c
new file mode 100644
index 0000000..d22c9ff
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/ht-irq.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2003 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <asm/pci.h>
+
+/*
+ * HT Bus fixup for the Titan
+ * XXX IRQ values need to change based on the board layout
+ */
+void __init titan_ht_pcibios_fixup_bus(struct pci_bus *bus)
+{
+        struct pci_bus *current_bus = bus;
+        struct pci_dev *devices;
+        struct list_head *devices_link;
+
+	list_for_each(devices_link, &(current_bus->devices)) {
+                devices = pci_dev_b(devices_link);
+                if (devices == NULL)
+                        continue;
+	}
+
+	/*
+	 * PLX and SPKT related changes go here
+	 */
+
+}
diff --git a/arch/mips/pmc-sierra/yosemite/ht.c b/arch/mips/pmc-sierra/yosemite/ht.c
new file mode 100644
index 0000000..dad228d
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/ht.c
@@ -0,0 +1,454 @@
+/*
+ * Copyright 2003 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include <asm/pci.h>
+#include <asm/io.h>
+
+#include <linux/init.h>
+#include <asm/titan_dep.h>
+
+#ifdef CONFIG_HYPERTRANSPORT
+
+
+/*
+ * This function check if the Hypertransport Link Initialization completed. If
+ * it did, then proceed further with scanning bus #2
+ */
+static __inline__ int check_titan_htlink(void)
+{
+        u32 val;
+
+        val = *(volatile uint32_t *)(RM9000x2_HTLINK_REG);
+        if (val & 0x00000020)
+                /* HT Link Initialization completed */
+                return 1;
+        else
+                return 0;
+}
+
+static int titan_ht_config_read_dword(struct pci_dev *device,
+                                             int offset, u32* val)
+{
+        int dev, bus, func;
+        uint32_t address_reg, data_reg;
+        uint32_t address;
+
+        bus = device->bus->number;
+        dev = PCI_SLOT(device->devfn);
+        func = PCI_FUNC(device->devfn);
+
+	/* XXX Need to change the Bus # */
+        if (bus > 2)
+                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
+                                                        0x80000000 | 0x1;
+        else
+                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+
+        address_reg = RM9000x2_OCD_HTCFGA;
+        data_reg =  RM9000x2_OCD_HTCFGD;
+
+        RM9K_WRITE(address_reg, address);
+        RM9K_READ(data_reg, val);
+
+        return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int titan_ht_config_read_word(struct pci_dev *device,
+                                             int offset, u16* val)
+{
+        int dev, bus, func;
+        uint32_t address_reg, data_reg;
+        uint32_t address;
+
+        bus = device->bus->number;
+        dev = PCI_SLOT(device->devfn);
+        func = PCI_FUNC(device->devfn);
+
+	/* XXX Need to change the Bus # */
+        if (bus > 2)
+                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
+                                                0x80000000 | 0x1;
+        else
+                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+
+        address_reg = RM9000x2_OCD_HTCFGA;
+        data_reg =  RM9000x2_OCD_HTCFGD;
+
+        if ((offset & 0x3) == 0)
+                offset = 0x2;
+        else
+                offset = 0x0;
+
+        RM9K_WRITE(address_reg, address);
+        RM9K_READ_16(data_reg + offset, val);
+
+        return PCIBIOS_SUCCESSFUL;
+}
+
+
+u32 longswap(unsigned long l)
+{
+        unsigned char b1,b2,b3,b4;
+
+        b1 = l&255;
+        b2 = (l>>8)&255;
+        b3 = (l>>16)&255;
+        b4 = (l>>24)&255;
+
+        return ((b1<<24) + (b2<<16) + (b3<<8) + b4);
+}
+
+
+static int titan_ht_config_read_byte(struct pci_dev *device,
+                                             int offset, u8* val)
+{
+        int dev, bus, func;
+        uint32_t address_reg, data_reg;
+        uint32_t address;
+        int offset1;
+
+        bus = device->bus->number;
+        dev = PCI_SLOT(device->devfn);
+        func = PCI_FUNC(device->devfn);
+
+	/* XXX Need to change the Bus # */
+        if (bus > 2)
+                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
+                                                        0x80000000 | 0x1;
+        else
+                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+
+        address_reg = RM9000x2_OCD_HTCFGA;
+        data_reg =  RM9000x2_OCD_HTCFGD;
+
+        RM9K_WRITE(address_reg, address);
+
+        if ((offset & 0x3) == 0) {
+                offset1 = 0x3;
+        }
+        if ((offset & 0x3) == 1) {
+                offset1 = 0x2;
+        }
+        if ((offset & 0x3) == 2) {
+                offset1 = 0x1;
+        }
+        if ((offset & 0x3) == 3) {
+                offset1 = 0x0;
+        }
+        RM9K_READ_8(data_reg + offset1, val);
+
+        return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int titan_ht_config_write_dword(struct pci_dev *device,
+                                             int offset, u8 val)
+{
+        int dev, bus, func;
+        uint32_t address_reg, data_reg;
+        uint32_t address;
+
+        bus = device->bus->number;
+        dev = PCI_SLOT(device->devfn);
+        func = PCI_FUNC(device->devfn);
+
+	/* XXX Need to change the Bus # */
+        if (bus > 2)
+                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
+                                                        0x80000000 | 0x1;
+        else
+              address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+
+        address_reg = RM9000x2_OCD_HTCFGA;
+        data_reg =  RM9000x2_OCD_HTCFGD;
+
+        RM9K_WRITE(address_reg, address);
+        RM9K_WRITE(data_reg, val);
+
+        return PCIBIOS_SUCCESSFUL;
+}
+
+static int titan_ht_config_write_word(struct pci_dev *device,
+                                             int offset, u8 val)
+{
+        int dev, bus, func;
+        uint32_t address_reg, data_reg;
+        uint32_t address;
+
+        bus = device->bus->number;
+        dev = PCI_SLOT(device->devfn);
+        func = PCI_FUNC(device->devfn);
+
+	/* XXX Need to change the Bus # */
+        if (bus > 2)
+                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
+                                0x80000000 | 0x1;
+        else
+                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+
+        address_reg = RM9000x2_OCD_HTCFGA;
+        data_reg =  RM9000x2_OCD_HTCFGD;
+
+        if ((offset & 0x3) == 0)
+                offset = 0x2;
+        else
+                offset = 0x0;
+
+        RM9K_WRITE(address_reg, address);
+        RM9K_WRITE_16(data_reg + offset, val);
+
+        return PCIBIOS_SUCCESSFUL;
+}
+
+static int titan_ht_config_write_byte(struct pci_dev *device,
+                                             int offset, u8 val)
+{
+        int dev, bus, func;
+        uint32_t address_reg, data_reg;
+        uint32_t address;
+        int offset1;
+
+        bus = device->bus->number;
+        dev = PCI_SLOT(device->devfn);
+        func = PCI_FUNC(device->devfn);
+
+	/* XXX Need to change the Bus # */
+        if (bus > 2)
+                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
+                                0x80000000 | 0x1;
+        else
+                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+
+        address_reg = RM9000x2_OCD_HTCFGA;
+        data_reg =  RM9000x2_OCD_HTCFGD;
+
+        RM9K_WRITE(address_reg, address);
+
+        if ((offset & 0x3) == 0) {
+             offset1 = 0x3;
+        }
+        if ((offset & 0x3) == 1) {
+             offset1 = 0x2;
+        }
+        if ((offset & 0x3) == 2) {
+             offset1 = 0x1;
+        }
+        if ((offset & 0x3) == 3) {
+            offset1 = 0x0;
+        }
+
+        RM9K_WRITE_8(data_reg + offset1, val);
+        return PCIBIOS_SUCCESSFUL;
+}
+
+
+static void titan_pcibios_set_master(struct pci_dev *dev)
+{
+        u16 cmd;
+        int bus = dev->bus->number;
+
+	if (check_titan_htlink())
+            titan_ht_config_read_word(dev, PCI_COMMAND, &cmd);
+
+	cmd |= PCI_COMMAND_MASTER;
+
+	if (check_titan_htlink())
+            titan_ht_config_write_word(dev, PCI_COMMAND, cmd);
+}
+
+
+int pcibios_enable_resources(struct pci_dev *dev)
+{
+        u16 cmd, old_cmd;
+        u8 tmp1;
+        int idx;
+        struct resource *r;
+        int bus = dev->bus->number;
+
+	if (check_titan_htlink())
+            titan_ht_config_read_word(dev, PCI_COMMAND, &cmd);
+
+	old_cmd = cmd;
+        for (idx = 0; idx < 6; idx++) {
+                r = &dev->resource[idx];
+                if (!r->start && r->end) {
+                        printk(KERN_ERR
+                               "PCI: Device %s not available because of "
+                               "resource collisions\n", pci_name(dev));
+                        return -EINVAL;
+                }
+                if (r->flags & IORESOURCE_IO)
+                        cmd |= PCI_COMMAND_IO;
+                if (r->flags & IORESOURCE_MEM)
+                        cmd |= PCI_COMMAND_MEMORY;
+        }
+        if (cmd != old_cmd) {
+		if (check_titan_htlink())
+                   titan_ht_config_write_word(dev, PCI_COMMAND, cmd);
+	}
+
+	if (check_titan_htlink())
+		titan_ht_config_read_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1);
+
+	if (tmp1 != 8) {
+                printk(KERN_WARNING "PCI setting cache line size to 8 from "
+                       "%d\n", tmp1);
+	}
+
+	if (check_titan_htlink())
+		titan_ht_config_write_byte(dev, PCI_CACHE_LINE_SIZE, 8);
+
+	if (check_titan_htlink())
+		titan_ht_config_read_byte(dev, PCI_LATENCY_TIMER, &tmp1);
+
+	if (tmp1 < 32 || tmp1 == 0xff) {
+                printk(KERN_WARNING "PCI setting latency timer to 32 from %d\n",
+                       tmp1);
+	}
+
+	if (check_titan_htlink())
+		titan_ht_config_write_byte(dev, PCI_LATENCY_TIMER, 32);
+
+	return 0;
+}
+
+
+int pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+        return pcibios_enable_resources(dev);
+}
+
+
+
+void pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+                             struct resource *res, int resource)
+{
+        u32 new, check;
+        int reg;
+
+        return;
+
+        new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
+        if (resource < 6) {
+                reg = PCI_BASE_ADDRESS_0 + 4 * resource;
+        } else if (resource == PCI_ROM_RESOURCE) {
+		res->flags |= IORESOURCE_ROM_ENABLE;
+                reg = dev->rom_base_reg;
+        } else {
+                /*
+                 * Somebody might have asked allocation of a non-standard
+                 * resource
+                 */
+                return;
+        }
+
+        pci_write_config_dword(dev, reg, new);
+        pci_read_config_dword(dev, reg, &check);
+        if ((new ^ check) &
+            ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK :
+             PCI_BASE_ADDRESS_MEM_MASK)) {
+                printk(KERN_ERR "PCI: Error while updating region "
+                       "%s/%d (%08x != %08x)\n", pci_name(dev), resource,
+                       new, check);
+        }
+}
+
+
+void pcibios_align_resource(void *data, struct resource *res,
+                            unsigned long size, unsigned long align)
+{
+        struct pci_dev *dev = data;
+
+        if (res->flags & IORESOURCE_IO) {
+                unsigned long start = res->start;
+
+                /* We need to avoid collisions with `mirrored' VGA ports
+                   and other strange ISA hardware, so we always want the
+                   addresses kilobyte aligned.  */
+                if (size > 0x100) {
+                        printk(KERN_ERR "PCI: I/O Region %s/%d too large"
+                               " (%ld bytes)\n", pci_name(dev),
+                                dev->resource - res, size);
+                }
+
+                start = (start + 1024 - 1) & ~(1024 - 1);
+                res->start = start;
+        }
+}
+
+struct pci_ops titan_pci_ops = {
+        titan_ht_config_read_byte,
+        titan_ht_config_read_word,
+        titan_ht_config_read_dword,
+        titan_ht_config_write_byte,
+        titan_ht_config_write_word,
+        titan_ht_config_write_dword
+};
+
+void __init pcibios_fixup_bus(struct pci_bus *c)
+{
+        titan_ht_pcibios_fixup_bus(c);
+}
+
+void __init pcibios_init(void)
+{
+
+        /* Reset PCI I/O and PCI MEM values */
+	/* XXX Need to add the proper values here */
+        ioport_resource.start = 0xe0000000;
+        ioport_resource.end   = 0xe0000000 + 0x20000000 - 1;
+        iomem_resource.start  = 0xc0000000;
+        iomem_resource.end    = 0xc0000000 + 0x20000000 - 1;
+
+	/* XXX Need to add bus values */
+        pci_scan_bus(2, &titan_pci_ops, NULL);
+        pci_scan_bus(3, &titan_pci_ops, NULL);
+}
+
+/*
+ * for parsing "pci=" kernel boot arguments.
+ */
+char *pcibios_setup(char *str)
+{
+        printk(KERN_INFO "rr: pcibios_setup\n");
+        /* Nothing to do for now.  */
+
+        return str;
+}
+
+unsigned __init int pcibios_assign_all_busses(void)
+{
+        /* We want to use the PCI bus detection done by PMON */
+        return 0;
+}
+
+#endif /* CONFIG_HYPERTRANSPORT */
diff --git a/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c b/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c
new file mode 100644
index 0000000..416da22
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c
@@ -0,0 +1,188 @@
+/*
+ *  Copyright (C) 2003 PMC-Sierra Inc.
+ *  Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Detailed Description:
+ *
+ * This block implements the I2C interface to the slave devices like the
+ * Atmel 24C32 EEPROM and the MAX 1619 Sensors device. The I2C Master interface
+ * can be controlled by the SCMB block. And the SCMB block kicks in only when
+ * using the Ethernet Mode of operation and __not__ the SysAD mode
+ *
+ * The SCMB controls the two modes: MDIO and the I2C. The MDIO mode is used to
+ * communicate with the Quad-PHY from Marvel. The I2C is used to communicate
+ * with the I2C slave devices.  It seems that the driver does not explicitly
+ * deal with the control of SDA and SCL serial lines. So, the driver will set
+ * the slave address, drive the command and then the data.  The SCMB will then
+ * control the two serial lines as required.
+ *
+ * It seems the documents are very unclear abt this. Hence, I took some time
+ * out to write the desciption to have an idea of how the I2C can actually
+ * work. Currently, this Linux driver wont be integrated into the generic Linux
+ * I2C framework. And finally, the I2C interface is also known as the 2BI
+ * interface. 2BI means 2-bit interface referring to SDA and SCL serial lines
+ * respectively.
+ *
+ * - Manish Lachwani (12/09/2003)
+ */
+
+#include "i2c-yosemite.h"
+
+/*
+ * Poll the I2C interface for the BUSY bit.
+ */
+static int titan_i2c_poll(void)
+{
+	int i = 0;
+	unsigned long val = 0;
+
+	for (i = 0; i < TITAN_I2C_MAX_POLL; i++) {
+		val = TITAN_I2C_READ(TITAN_I2C_COMMAND);
+
+		if (!(val & 0x8000))
+			return 0;
+	}
+
+	return TITAN_I2C_ERR_TIMEOUT;
+}
+
+/*
+ * Execute the I2C command
+ */
+int titan_i2c_xfer(unsigned int slave_addr, titan_i2c_command * cmd,
+		   int size, unsigned int *addr)
+{
+	int loop = 0, bytes, i;
+	unsigned int *write_data, data, *read_data;
+	unsigned long reg_val, val;
+
+	write_data = cmd->data;
+	read_data = addr;
+
+	TITAN_I2C_WRITE(TITAN_I2C_SLAVE_ADDRESS, slave_addr);
+
+	if (cmd->type == TITAN_I2C_CMD_WRITE)
+		loop = cmd->write_size;
+	else
+		loop = size;
+
+	while (loop > 0) {
+		if ((cmd->type == TITAN_I2C_CMD_WRITE) ||
+		    (cmd->type == TITAN_I2C_CMD_READ_WRITE)) {
+
+			reg_val = TITAN_I2C_DATA;
+			for (i = 0; i < TITAN_I2C_MAX_WORDS_PER_RW;
+			     ++i, write_data += 2, reg_val += 4) {
+				if (bytes < cmd->write_size) {
+					data = write_data[0];
+					++data;
+				}
+
+				if (bytes < cmd->write_size) {
+					data = write_data[1];
+					++data;
+				}
+
+				TITAN_I2C_WRITE(reg_val, data);
+			}
+		}
+
+		TITAN_I2C_WRITE(TITAN_I2C_COMMAND,
+				(unsigned int) (cmd->type << 13));
+		if (titan_i2c_poll() != TITAN_I2C_ERR_OK)
+			return TITAN_I2C_ERR_TIMEOUT;
+
+		if ((cmd->type == TITAN_I2C_CMD_READ) ||
+		    (cmd->type == TITAN_I2C_CMD_READ_WRITE)) {
+
+			reg_val = TITAN_I2C_DATA;
+			for (i = 0; i < TITAN_I2C_MAX_WORDS_PER_RW;
+			     ++i, read_data += 2, reg_val += 4) {
+				data = TITAN_I2C_READ(reg_val);
+
+				if (bytes < size) {
+					read_data[0] = data & 0xff;
+					++bytes;
+				}
+
+				if (bytes < size) {
+					read_data[1] =
+					    ((data >> 8) & 0xff);
+					++bytes;
+				}
+			}
+		}
+
+		loop -= (TITAN_I2C_MAX_WORDS_PER_RW * 2);
+	}
+
+	/*
+	 * Read the Interrupt status and then return the appropriate error code
+	 */
+
+	val = TITAN_I2C_READ(TITAN_I2C_INTERRUPTS);
+	if (val & 0x0020)
+		return TITAN_I2C_ERR_ARB_LOST;
+
+	if (val & 0x0040)
+		return TITAN_I2C_ERR_NO_RESP;
+
+	if (val & 0x0080)
+		return TITAN_I2C_ERR_DATA_COLLISION;
+
+	return TITAN_I2C_ERR_OK;
+}
+
+/*
+ * Init the I2C subsystem of the PMC-Sierra Yosemite board
+ */
+int titan_i2c_init(titan_i2c_config * config)
+{
+	unsigned int val;
+
+	/*
+	 * Reset the SCMB and program into the I2C mode
+	 */
+	TITAN_I2C_WRITE(TITAN_I2C_SCMB_CONTROL, 0xA000);
+	TITAN_I2C_WRITE(TITAN_I2C_SCMB_CONTROL, 0x2000);
+
+	/*
+	 * Configure the filtera and clka values
+	 */
+	val = TITAN_I2C_READ(TITAN_I2C_SCMB_CLOCK_A);
+	val |= ((val & ~(0xF000)) | ((config->filtera << 12) & 0xF000));
+	val |= ((val & ~(0x03FF)) | (config->clka & 0x03FF));
+	TITAN_I2C_WRITE(TITAN_I2C_SCMB_CLOCK_A, val);
+
+	/*
+	 * Configure the filterb and clkb values
+	 */
+	val = TITAN_I2C_READ(TITAN_I2C_SCMB_CLOCK_B);
+	val |= ((val & ~(0xF000)) | ((config->filterb << 12) & 0xF000));
+	val |= ((val & ~(0x03FF)) | (config->clkb & 0x03FF));
+	TITAN_I2C_WRITE(TITAN_I2C_SCMB_CLOCK_B, val);
+
+	return TITAN_I2C_ERR_OK;
+}
diff --git a/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h b/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h
new file mode 100644
index 0000000..31c5523
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h
@@ -0,0 +1,96 @@
+/*
+ *  arch/mips/pmc-sierra/yosemite/i2c-yosemite.h
+ *
+ *  Copyright (C) 2003 PMC-Sierra Inc.
+ *  Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __I2C_YOSEMITE_H
+#define __I2C_YOSEMITE_H
+
+/* Read and Write operations to the chip */
+
+#define TITAN_I2C_BASE			0xbb000000	/* XXX Needs to change */
+
+#define	TITAN_I2C_WRITE(offset, data)	\
+					*(volatile unsigned long *)(TITAN_I2C_BASE + offset) = data
+
+#define	TITAN_I2C_READ(offset) *(volatile unsigned long *)(TITAN_I2C_BASE + offset)
+
+
+/* Local constansts*/
+#define TITAN_I2C_MAX_FILTER            15
+#define TITAN_I2C_MAX_CLK               1023
+#define TITAN_I2C_MAX_ARBF              15
+#define TITAN_I2C_MAX_NAK               15
+#define TITAN_I2C_MAX_MASTERCODE        7
+#define TITAN_I2C_MAX_WORDS_PER_RW      4
+#define TITAN_I2C_MAX_POLL		100
+
+/* Registers used for I2C work */
+#define TITAN_I2C_SCMB_CONTROL		0x0180	/* SCMB Control */
+#define TITAN_I2C_SCMB_CLOCK_A		0x0184	/* SCMB Clock A */
+#define TITAN_I2C_SCMB_CLOCK_B		0x0188	/* SCMB Clock B */
+#define	TITAN_I2C_CONFIG		0x01A0	/* I2C Config */
+#define TITAN_I2C_COMMAND		0x01A4	/* I2C Command */
+#define	TITAN_I2C_SLAVE_ADDRESS		0x01A8	/* I2C Slave Address */
+#define TITAN_I2C_DATA			0x01AC	/* I2C Data [15:0] */
+#define TITAN_I2C_INTERRUPTS		0x01BC	/* I2C Interrupts */
+
+/* Error */
+#define	TITAN_I2C_ERR_ARB_LOST		(-9220)
+#define	TITAN_I2C_ERR_NO_RESP		(-9221)
+#define	TITAN_I2C_ERR_DATA_COLLISION	(-9222)
+#define	TITAN_I2C_ERR_TIMEOUT		(-9223)
+#define	TITAN_I2C_ERR_OK		0
+
+/* I2C Command Type */
+typedef enum {
+	TITAN_I2C_CMD_WRITE = 0,
+	TITAN_I2C_CMD_READ = 1,
+	TITAN_I2C_CMD_READ_WRITE = 2
+} titan_i2c_cmd_type;
+
+/* I2C structures */
+typedef struct {
+	int filtera;		/* Register 0x0184, bits 15 - 12 */
+	int clka;		/* Register 0x0184, bits 9 - 0 */
+	int filterb;		/* Register 0x0188, bits 15 - 12 */
+	int clkb;		/* Register 0x0188, bits 9 - 0 */
+} titan_i2c_config;
+
+/* I2C command type */
+typedef struct {
+	titan_i2c_cmd_type type;	/* Type of command */
+	int num_arb;		/* Register 0x01a0, bits 15 - 12 */
+	int num_nak;		/* Register 0x01a0, bits 11 - 8 */
+	int addr_size;		/* Register 0x01a0, bit 7 */
+	int mst_code;		/* Register 0x01a0, bits 6 - 4 */
+	int arb_en;		/* Register 0x01a0, bit 1 */
+	int speed;		/* Register 0x01a0, bit 0 */
+	int slave_addr;		/* Register 0x01a8 */
+	int write_size;		/* Register 0x01a4, bits 10 - 8 */
+	unsigned int *data;	/* Register 0x01ac */
+} titan_i2c_command;
+
+#endif				/* __I2C_YOSEMITE_H */
diff --git a/arch/mips/pmc-sierra/yosemite/irq-handler.S b/arch/mips/pmc-sierra/yosemite/irq-handler.S
new file mode 100644
index 0000000..33b9c40
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/irq-handler.S
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2003, 04 PMC-Sierra Inc.
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com
+ * Copyright 2004 Ralf Baechle (ralf@linux-mips.org)
+ *
+ * First-level interrupt router for the PMC-Sierra Titan board
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Titan supports Hypertransport or PCI but not both. Hence, one interrupt
+ * line is shared between the PCI slot A and Hypertransport. This is the
+ * Processor INTB #0.
+ */
+
+#include <linux/config.h>
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+		.align	5
+		NESTED(titan_handle_int, PT_SIZE, sp)
+		SAVE_ALL
+		CLI
+		.set	at
+		.set	noreorder
+		la	ra, ret_from_irq
+		mfc0	t0, CP0_CAUSE
+		mfc0	t2, CP0_STATUS
+
+		and	t0, t2
+
+		andi	t2, t0, STATUSF_IP7	/* INTB5 hardware line */
+		bnez	t2, ll_timer_irq	/* Timer */
+		andi	t1, t0, STATUSF_IP2	/* INTB0 hardware line */
+		bnez	t1, ll_pcia_irq		/* 64-bit PCI */
+		andi	t2, t0, STATUSF_IP3	/* INTB1 hardware line */
+		bnez	t2, ll_pcib_irq		/* second 64-bit PCI slot */
+		andi	t1, t0, STATUSF_IP4	/* INTB2 hardware line */
+		bnez	t1, ll_duart_irq	/* UART	*/
+		andi    t2, t0, STATUSF_IP5	/* SMP inter-core interrupts */
+		bnez    t2, ll_smp_irq
+		andi	t1, t0, STATUSF_IP6
+		bnez	t1, ll_ht_irq		/* Hypertransport */
+
+		move	a0, sp
+		j	do_extended_irq
+		END(titan_handle_int)
+
+		.set	reorder
+		.align	5
+
+ll_pcia_irq:
+		li	a0, 2
+		move	a1, sp
+#ifdef CONFIG_HYPERTRANSPORT
+		j	ll_ht_smp_irq_handler
+#else
+		j	do_IRQ
+#endif
+
+ll_pcib_irq:
+		li	a0, 3
+		move	a1, sp
+		j	do_IRQ
+
+ll_duart_irq:
+		li	a0, 4
+		move	a1, sp
+		j	do_IRQ
+
+ll_smp_irq:
+		li	a0, 5
+		move	a1, sp
+#ifdef CONFIG_SMP
+		j	titan_mailbox_irq
+#else
+		j	do_IRQ
+#endif
+
+ll_ht_irq:
+		li	a0, 6
+		move	a1, sp
+		j	ll_ht_smp_irq_handler
+
+ll_timer_irq:
+		li	a0, 7
+		move	a1, sp
+		j	do_IRQ
diff --git a/arch/mips/pmc-sierra/yosemite/irq.c b/arch/mips/pmc-sierra/yosemite/irq.c
new file mode 100644
index 0000000..f4e2897
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/irq.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2003 PMC-Sierra Inc.
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Second level Interrupt handlers for the PMC-Sierra Titan/Yosemite board
+ */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/titan_dep.h>
+
+/* Hypertransport specific */
+#define IRQ_ACK_BITS            0x00000000	/* Ack bits */
+
+#define HYPERTRANSPORT_INTA     0x78		/* INTA# */
+#define HYPERTRANSPORT_INTB     0x79		/* INTB# */
+#define HYPERTRANSPORT_INTC     0x7a		/* INTC# */
+#define HYPERTRANSPORT_INTD     0x7b		/* INTD# */
+
+extern asmlinkage void titan_handle_int(void);
+extern void jaguar_mailbox_irq(struct pt_regs *);
+
+/*
+ * Handle hypertransport & SMP interrupts. The interrupt lines are scarce.
+ * For interprocessor interrupts, the best thing to do is to use the INTMSG
+ * register. We use the same external interrupt line, i.e. INTB3 and monitor
+ * another status bit
+ */
+asmlinkage void ll_ht_smp_irq_handler(int irq, struct pt_regs *regs)
+{
+	u32 status = OCD_READ(RM9000x2_OCD_INTP0STATUS4);
+
+	/* Ack all the bits that correspond to the interrupt sources */
+	if (status != 0)
+		OCD_WRITE(RM9000x2_OCD_INTP0STATUS4, IRQ_ACK_BITS);
+
+	status = OCD_READ(RM9000x2_OCD_INTP1STATUS4);
+	if (status != 0)
+		OCD_WRITE(RM9000x2_OCD_INTP1STATUS4, IRQ_ACK_BITS);
+
+#ifdef CONFIG_HT_LEVEL_TRIGGER
+	/*
+	 * Level Trigger Mode only. Send the HT EOI message back to the source.
+	 */
+	switch (status) {
+	case 0x1000000:
+		OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTA);
+		break;
+	case 0x2000000:
+		OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTB);
+		break;
+	case 0x4000000:
+		OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTC);
+		break;
+	case 0x8000000:
+		OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTD);
+		break;
+	case 0x0000001:
+		/* PLX */
+		OCD_WRITE(RM9000x2_OCD_HTEOI, 0x20);
+		OCD_WRITE(IRQ_CLEAR_REG, IRQ_ACK_BITS);
+		break;
+	case 0xf000000:
+		OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTA);
+		OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTB);
+		OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTC);
+		OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTD);
+		break;
+	}
+#endif /* CONFIG_HT_LEVEL_TRIGGER */
+
+	do_IRQ(irq, regs);
+}
+
+asmlinkage void do_extended_irq(struct pt_regs *regs)
+{
+	unsigned int intcontrol = read_c0_intcontrol();
+	unsigned int cause = read_c0_cause();
+	unsigned int status = read_c0_status();
+	unsigned int pending_sr, pending_ic;
+
+	pending_sr = status & cause & 0xff00;
+	pending_ic = (cause >> 8) & intcontrol & 0xff00;
+
+	if (pending_ic & (1 << 13))
+		do_IRQ(13, regs);
+
+}
+
+#ifdef CONFIG_KGDB
+extern void init_second_port(void);
+#endif
+
+/*
+ * Initialize the next level interrupt handler
+ */
+void __init arch_init_irq(void)
+{
+	clear_c0_status(ST0_IM);
+
+	set_except_vector(0, titan_handle_int);
+	mips_cpu_irq_init(0);
+	rm7k_cpu_irq_init(8);
+	rm9k_cpu_irq_init(12);
+
+#ifdef CONFIG_KGDB
+	/* At this point, initialize the second serial port */
+	init_second_port();
+#endif
+
+#ifdef CONFIG_GDB_CONSOLE
+	register_gdb_console();
+#endif
+}
+
+#ifdef CONFIG_KGDB
+/*
+ * The 16550 DUART has two ports, but is allocated one IRQ
+ * for the serial console. Hence, a generic framework for
+ * serial IRQ routing in place. Currently, just calls the
+ * do_IRQ fuction. But, going in the future, need to check
+ * DUART registers for channel A and B, then decide the
+ * appropriate action
+ */
+asmlinkage void yosemite_kgdb_irq(int irq, struct pt_regs *regs)
+{
+	do_IRQ(irq, regs);
+}
+#endif
diff --git a/arch/mips/pmc-sierra/yosemite/prom.c b/arch/mips/pmc-sierra/yosemite/prom.c
new file mode 100644
index 0000000..1fb3e69
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/prom.c
@@ -0,0 +1,141 @@
+/*
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Copyright (C) 2003, 2004 PMC-Sierra Inc.
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ * Copyright (C) 2004 Ralf Baechle
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/smp.h>
+
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <asm/bootinfo.h>
+#include <asm/pmon.h>
+
+#ifdef CONFIG_SMP
+extern void prom_grab_secondary(void);
+#else
+#define prom_grab_secondary() do { } while (0)
+#endif
+
+#include "setup.h"
+
+struct callvectors *debug_vectors;
+
+extern unsigned long yosemite_base;
+extern unsigned long cpu_clock;
+
+const char *get_system_type(void)
+{
+	return "PMC-Sierra Yosemite";
+}
+
+static void prom_cpu0_exit(void *arg)
+{
+	void *nvram = (void *) YOSEMITE_RTC_BASE;
+
+	/* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */
+	writeb(0x84, nvram + 0xff7);
+
+	/* wait for the watchdog to go off */
+	mdelay(100 + (1000 / 16));
+
+	/* if the watchdog fails for some reason, let people know */
+	printk(KERN_NOTICE "Watchdog reset failed\n");
+}
+
+/*
+ * Reset the NVRAM over the local bus
+ */
+static void prom_exit(void)
+{
+#ifdef CONFIG_SMP
+	if (smp_processor_id())
+		/* CPU 1 */
+		smp_call_function(prom_cpu0_exit, NULL, 1, 1);
+#endif
+	prom_cpu0_exit(NULL);
+}
+
+/*
+ * Halt the system
+ */
+static void prom_halt(void)
+{
+	printk(KERN_NOTICE "\n** You can safely turn off the power\n");
+	while (1)
+		__asm__(".set\tmips3\n\t" "wait\n\t" ".set\tmips0");
+}
+
+/*
+ * Init routine which accepts the variables from PMON
+ */
+void __init prom_init(void)
+{
+	int argc = fw_arg0;
+	char **arg = (char **) fw_arg1;
+	char **env = (char **) fw_arg2;
+	struct callvectors *cv = (struct callvectors *) fw_arg3;
+	int i = 0;
+
+	/* Callbacks for halt, restart */
+	_machine_restart = (void (*)(char *)) prom_exit;
+	_machine_halt = prom_halt;
+	_machine_power_off = prom_halt;
+
+	debug_vectors = cv;
+	arcs_cmdline[0] = '\0';
+
+	/* Get the boot parameters */
+	for (i = 1; i < argc; i++) {
+		if (strlen(arcs_cmdline) + strlen(arg[i] + 1) >=
+		    sizeof(arcs_cmdline))
+			break;
+
+		strcat(arcs_cmdline, arg[i]);
+		strcat(arcs_cmdline, " ");
+	}
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+	if ((strstr(arcs_cmdline, "console=ttyS")) == NULL)
+		strcat(arcs_cmdline, "console=ttyS0,115200");
+#endif
+
+	while (*env) {
+		if (strncmp("ocd_base", *env, strlen("ocd_base")) == 0)
+			yosemite_base =
+			    simple_strtol(*env + strlen("ocd_base="), NULL,
+					  16);
+
+		if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0)
+			cpu_clock =
+			    simple_strtol(*env + strlen("cpuclock="), NULL,
+					  10);
+
+		env++;
+	}
+
+	mips_machgroup = MACH_GROUP_TITAN;
+	mips_machtype = MACH_TITAN_YOSEMITE;
+
+	prom_grab_secondary();
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
+{
+}
diff --git a/arch/mips/pmc-sierra/yosemite/py-console.c b/arch/mips/pmc-sierra/yosemite/py-console.c
new file mode 100644
index 0000000..757e605
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/py-console.c
@@ -0,0 +1,114 @@
+/*
+ * 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) 2001, 2002, 2004 Ralf Baechle
+ */
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/kdev_t.h>
+#include <linux/major.h>
+#include <linux/termios.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <asm/serial.h>
+#include <asm/io.h>
+
+/* SUPERIO uart register map */
+struct yo_uartregs {
+	union {
+		volatile u8	rbr;	/* read only, DLAB == 0 */
+		volatile u8	thr;	/* write only, DLAB == 0 */
+		volatile u8	dll;	/* DLAB == 1 */
+	} u1;
+	union {
+		volatile u8	ier;	/* DLAB == 0 */
+		volatile u8	dlm;	/* DLAB == 1 */
+	} u2;
+	union {
+		volatile u8	iir;	/* read only */
+		volatile u8	fcr;	/* write only */
+	} u3;
+	volatile u8	iu_lcr;
+	volatile u8	iu_mcr;
+	volatile u8	iu_lsr;
+	volatile u8	iu_msr;
+	volatile u8	iu_scr;
+} yo_uregs_t;
+
+#define iu_rbr u1.rbr
+#define iu_thr u1.thr
+#define iu_dll u1.dll
+#define iu_ier u2.ier
+#define iu_dlm u2.dlm
+#define iu_iir u3.iir
+#define iu_fcr u3.fcr
+
+#define ssnop()		__asm__ __volatile__("sll	$0, $0, 1\n");
+#define ssnop_4()	do { ssnop(); ssnop(); ssnop(); ssnop(); } while (0)
+
+#define IO_BASE_64	0x9000000000000000ULL
+
+static unsigned char readb_outer_space(unsigned long long phys)
+{
+	unsigned long long vaddr = IO_BASE_64 | phys;
+	unsigned char res;
+	unsigned int sr;
+
+	sr = read_c0_status();
+	write_c0_status((sr | ST0_KX) & ~ ST0_IE);
+	ssnop_4();
+
+	__asm__ __volatile__ (
+	"	.set	mips3		\n"
+	"	ld	%0, %1		\n"
+	"	lbu	%0, (%0)	\n"
+	"	.set	mips0		\n"
+	: "=r" (res)
+	: "m" (vaddr));
+
+	write_c0_status(sr);
+	ssnop_4();
+
+	return res;
+}
+
+static void writeb_outer_space(unsigned long long phys, unsigned char c)
+{
+	unsigned long long vaddr = IO_BASE_64 | phys;
+	unsigned long tmp;
+	unsigned int sr;
+
+	sr = read_c0_status();
+	write_c0_status((sr | ST0_KX) & ~ ST0_IE);
+	ssnop_4();
+
+	__asm__ __volatile__ (
+	"	.set	mips3		\n"
+	"	ld	%0, %1		\n"
+	"	sb	%2, (%0)	\n"
+	"	.set	mips0		\n"
+	: "=&r" (tmp)
+	: "m" (vaddr), "r" (c));
+
+	write_c0_status(sr);
+	ssnop_4();
+}
+
+void prom_putchar(char c)
+{
+	unsigned long lsr = 0xfd000008ULL + offsetof(struct yo_uartregs, iu_lsr);
+	unsigned long thr = 0xfd000008ULL + offsetof(struct yo_uartregs, iu_thr);
+
+	while ((readb_outer_space(lsr) & 0x20) == 0);
+	writeb_outer_space(thr, c);
+}
+
+char __init prom_getchar(void)
+{
+	return 0;
+}
diff --git a/arch/mips/pmc-sierra/yosemite/setup.c b/arch/mips/pmc-sierra/yosemite/setup.c
new file mode 100644
index 0000000..7225bbf
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/setup.c
@@ -0,0 +1,235 @@
+/*
+ *  Copyright (C) 2003 PMC-Sierra Inc.
+ *  Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/bcd.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/swap.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/termios.h>
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+
+#include <asm/time.h>
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/reboot.h>
+#include <asm/serial.h>
+#include <asm/titan_dep.h>
+#include <asm/m48t37.h>
+
+#include "setup.h"
+
+unsigned char titan_ge_mac_addr_base[6] = {
+	// 0x00, 0x03, 0xcc, 0x1d, 0x22, 0x00
+	0x00, 0xe0, 0x04, 0x00, 0x00, 0x21
+};
+
+unsigned long cpu_clock;
+unsigned long yosemite_base;
+
+static struct m48t37_rtc *m48t37_base;
+
+void __init bus_error_init(void)
+{
+	/* Do nothing */
+}
+
+
+unsigned long m48t37y_get_time(void)
+{
+	unsigned int year, month, day, hour, min, sec;
+
+	/* Stop the update to the time */
+	m48t37_base->control = 0x40;
+
+	year = BCD2BIN(m48t37_base->year);
+	year += BCD2BIN(m48t37_base->century) * 100;
+
+	month = BCD2BIN(m48t37_base->month);
+	day = BCD2BIN(m48t37_base->date);
+	hour = BCD2BIN(m48t37_base->hour);
+	min = BCD2BIN(m48t37_base->min);
+	sec = BCD2BIN(m48t37_base->sec);
+
+	/* Start the update to the time again */
+	m48t37_base->control = 0x00;
+
+	return mktime(year, month, day, hour, min, sec);
+}
+
+int m48t37y_set_time(unsigned long sec)
+{
+	struct rtc_time tm;
+
+	/* convert to a more useful format -- note months count from 0 */
+	to_tm(sec, &tm);
+	tm.tm_mon += 1;
+
+	/* enable writing */
+	m48t37_base->control = 0x80;
+
+	/* year */
+	m48t37_base->year = BIN2BCD(tm.tm_year % 100);
+	m48t37_base->century = BIN2BCD(tm.tm_year / 100);
+
+	/* month */
+	m48t37_base->month = BIN2BCD(tm.tm_mon);
+
+	/* day */
+	m48t37_base->date = BIN2BCD(tm.tm_mday);
+
+	/* hour/min/sec */
+	m48t37_base->hour = BIN2BCD(tm.tm_hour);
+	m48t37_base->min = BIN2BCD(tm.tm_min);
+	m48t37_base->sec = BIN2BCD(tm.tm_sec);
+
+	/* day of week -- not really used, but let's keep it up-to-date */
+	m48t37_base->day = BIN2BCD(tm.tm_wday + 1);
+
+	/* disable writing */
+	m48t37_base->control = 0x00;
+
+	return 0;
+}
+
+void yosemite_timer_setup(struct irqaction *irq)
+{
+	setup_irq(7, irq);
+}
+
+void yosemite_time_init(void)
+{
+	board_timer_setup = yosemite_timer_setup;
+	mips_hpt_frequency = cpu_clock / 2;
+mips_hpt_frequency = 33000000 * 3 * 5;
+}
+
+/* No other usable initialization hook than this ...  */
+extern void (*late_time_init)(void);
+
+unsigned long ocd_base;
+
+EXPORT_SYMBOL(ocd_base);
+
+/*
+ * Common setup before any secondaries are started
+ */
+
+#define TITAN_UART_CLK		3686400
+#define TITAN_SERIAL_BASE_BAUD	(TITAN_UART_CLK / 16)
+#define TITAN_SERIAL_IRQ	4
+#define TITAN_SERIAL_BASE	0xfd000008UL
+
+static void __init py_map_ocd(void)
+{
+	ocd_base = (unsigned long) ioremap(OCD_BASE, OCD_SIZE);
+	if (!ocd_base)
+		panic("Mapping OCD failed - game over.  Your score is 0.");
+
+	/* Kludge for PMON bug ... */
+	OCD_WRITE(0x0710, 0x0ffff029);
+}
+
+static void __init py_uart_setup(void)
+{
+	struct uart_port up;
+
+	/*
+	 * Register to interrupt zero because we share the interrupt with
+	 * the serial driver which we don't properly support yet.
+	 */
+	memset(&up, 0, sizeof(up));
+	up.membase      = (unsigned char *) ioremap(TITAN_SERIAL_BASE, 8);
+	up.irq          = TITAN_SERIAL_IRQ;
+	up.uartclk      = TITAN_UART_CLK;
+	up.regshift     = 0;
+	up.iotype       = UPIO_MEM;
+	up.flags        = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+	up.line         = 0;
+
+	if (early_serial_setup(&up))
+		printk(KERN_ERR "Early serial init of port 0 failed\n");
+}
+
+static void __init py_rtc_setup(void)
+{
+	m48t37_base = ioremap(YOSEMITE_RTC_BASE, YOSEMITE_RTC_SIZE);
+	if (!m48t37_base)
+		printk(KERN_ERR "Mapping the RTC failed\n");
+
+	rtc_get_time = m48t37y_get_time;
+	rtc_set_time = m48t37y_set_time;
+
+	write_seqlock(&xtime_lock);
+	xtime.tv_sec = m48t37y_get_time();
+	xtime.tv_nsec = 0;
+
+	set_normalized_timespec(&wall_to_monotonic,
+	                        -xtime.tv_sec, -xtime.tv_nsec);
+	write_sequnlock(&xtime_lock);
+}
+
+/* Not only time init but that's what the hook it's called through is named */
+static void __init py_late_time_init(void)
+{
+	py_map_ocd();
+	py_uart_setup();
+	py_rtc_setup();
+}
+
+static int __init pmc_yosemite_setup(void)
+{
+	board_time_init = yosemite_time_init;
+	late_time_init = py_late_time_init;
+
+	/* Add memory regions */
+	add_memory_region(0x00000000, 0x10000000, BOOT_MEM_RAM);
+
+#if 0 /* XXX Crash ...  */
+	OCD_WRITE(RM9000x2_OCD_HTSC,
+	          OCD_READ(RM9000x2_OCD_HTSC) | HYPERTRANSPORT_ENABLE);
+
+	/* Set the BAR. Shifted mode */
+	OCD_WRITE(RM9000x2_OCD_HTBAR0, HYPERTRANSPORT_BAR0_ADDR);
+	OCD_WRITE(RM9000x2_OCD_HTMASK0, HYPERTRANSPORT_SIZE0);
+#endif
+
+	return 0;
+}
+
+early_initcall(pmc_yosemite_setup);
diff --git a/arch/mips/pmc-sierra/yosemite/setup.h b/arch/mips/pmc-sierra/yosemite/setup.h
new file mode 100644
index 0000000..1a01abf
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/setup.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2003, 04 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ * Copyright 2004 Ralf Baechle <ralf@linux-mips.org>
+ *
+ * Board specific definititions for the PMC-Sierra Yosemite
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#ifndef __SETUP_H__
+#define __SETUP_H__
+
+/* M48T37 RTC + NVRAM */
+#define	YOSEMITE_RTC_BASE		0xfc800000
+#define	YOSEMITE_RTC_SIZE		0x00800000
+
+#define HYPERTRANSPORT_BAR0_ADDR        0x00000006
+#define HYPERTRANSPORT_SIZE0            0x0fffffff
+#define HYPERTRANSPORT_BAR0_ATTR        0x00002000
+
+#define HYPERTRANSPORT_ENABLE           0x6
+
+/*
+ * EEPROM Size
+ */
+#define	TITAN_ATMEL_24C32_SIZE		32768
+#define	TITAN_ATMEL_24C64_SIZE		65536
+
+#endif /* __SETUP_H__ */
diff --git a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c
new file mode 100644
index 0000000..1d3b073
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/smp.c
@@ -0,0 +1,172 @@
+#include <linux/linkage.h>
+#include <linux/sched.h>
+
+#include <asm/pmon.h>
+#include <asm/titan_dep.h>
+
+extern unsigned int (*mips_hpt_read)(void);
+extern void (*mips_hpt_init)(unsigned int);
+
+#define LAUNCHSTACK_SIZE 256
+
+static spinlock_t launch_lock __initdata;
+
+static unsigned long secondary_sp __initdata;
+static unsigned long secondary_gp __initdata;
+
+static unsigned char launchstack[LAUNCHSTACK_SIZE] __initdata
+	__attribute__((aligned(2 * sizeof(long))));
+
+static void __init prom_smp_bootstrap(void)
+{
+	local_irq_disable();
+
+	while (spin_is_locked(&launch_lock));
+
+	__asm__ __volatile__(
+	"	move	$sp, %0		\n"
+	"	move	$gp, %1		\n"
+	"	j	smp_bootstrap	\n"
+	:
+	: "r" (secondary_sp), "r" (secondary_gp));
+}
+
+/*
+ * PMON is a fragile beast.  It'll blow up once the mappings it's littering
+ * right into the middle of KSEG3 are blown away so we have to grab the slave
+ * core early and keep it in a waiting loop.
+ */
+void __init prom_grab_secondary(void)
+{
+	spin_lock(&launch_lock);
+
+	pmon_cpustart(1, &prom_smp_bootstrap,
+	              launchstack + LAUNCHSTACK_SIZE, 0);
+}
+
+/*
+ * Detect available CPUs, populate phys_cpu_present_map before smp_init
+ *
+ * We don't want to start the secondary CPU yet nor do we have a nice probing
+ * feature in PMON so we just assume presence of the secondary core.
+ */
+static char maxcpus_string[] __initdata =
+	KERN_WARNING "max_cpus set to 0; using 1 instead\n";
+
+void __init prom_prepare_cpus(unsigned int max_cpus)
+{
+	int enabled = 0, i;
+
+	if (max_cpus == 0) {
+		printk(maxcpus_string);
+		max_cpus = 1;
+	}
+
+	cpus_clear(phys_cpu_present_map);
+
+	for (i = 0; i < 2; i++) {
+		if (i == max_cpus)
+			break;
+
+		/*
+		 * The boot CPU
+		 */
+		cpu_set(i, phys_cpu_present_map);
+		__cpu_number_map[i]	= i;
+		__cpu_logical_map[i]	= i;
+		enabled++;
+	}
+
+	/*
+	 * Be paranoid.  Enable the IPI only if we're really about to go SMP.
+	 */
+	if (enabled > 1)
+		set_c0_status(STATUSF_IP5);
+}
+
+/*
+ * Firmware CPU startup hook
+ * Complicated by PMON's weird interface which tries to minimic the UNIX fork.
+ * It launches the next * available CPU and copies some information on the
+ * stack so the first thing we do is throw away that stuff and load useful
+ * values into the registers ...
+ */
+void prom_boot_secondary(int cpu, struct task_struct *idle)
+{
+	unsigned long gp = (unsigned long) idle->thread_info;
+	unsigned long sp = gp + THREAD_SIZE - 32;
+
+	secondary_sp = sp;
+	secondary_gp = gp;
+
+	spin_unlock(&launch_lock);
+}
+
+/* Hook for after all CPUs are online */
+void prom_cpus_done(void)
+{
+}
+
+/*
+ *  After we've done initial boot, this function is called to allow the
+ *  board code to clean up state, if needed
+ */
+void prom_init_secondary(void)
+{
+	mips_hpt_init(mips_hpt_read());
+
+	set_c0_status(ST0_CO | ST0_IE | ST0_IM);
+}
+
+void prom_smp_finish(void)
+{
+}
+
+asmlinkage void titan_mailbox_irq(struct pt_regs *regs)
+{
+	int cpu = smp_processor_id();
+	unsigned long status;
+
+	if (cpu == 0) {
+		status = OCD_READ(RM9000x2_OCD_INTP0STATUS3);
+		OCD_WRITE(RM9000x2_OCD_INTP0CLEAR3, status);
+	}
+
+	if (cpu == 1) {
+		status = OCD_READ(RM9000x2_OCD_INTP1STATUS3);
+		OCD_WRITE(RM9000x2_OCD_INTP1CLEAR3, status);
+	}
+
+	if (status & 0x2)
+		smp_call_function_interrupt();
+}
+
+/*
+ * Send inter-processor interrupt
+ */
+void core_send_ipi(int cpu, unsigned int action)
+{
+	/*
+	 * Generate an INTMSG so that it can be sent over to the
+	 * destination CPU. The INTMSG will put the STATUS bits
+	 * based on the action desired. An alternative strategy
+	 * is to write to the Interrupt Set register, read the
+	 * Interrupt Status register and clear the Interrupt
+	 * Clear register. The latter is preffered.
+	 */
+	switch (action) {
+	case SMP_RESCHEDULE_YOURSELF:
+		if (cpu == 1)
+			OCD_WRITE(RM9000x2_OCD_INTP1SET3, 4);
+		else
+			OCD_WRITE(RM9000x2_OCD_INTP0SET3, 4);
+		break;
+
+	case SMP_CALL_FUNCTION:
+		if (cpu == 1)
+			OCD_WRITE(RM9000x2_OCD_INTP1SET3, 2);
+		else
+			OCD_WRITE(RM9000x2_OCD_INTP0SET3, 2);
+		break;
+	}
+}
diff --git a/arch/mips/sgi-ip22/Makefile b/arch/mips/sgi-ip22/Makefile
new file mode 100644
index 0000000..eb0820f
--- /dev/null
+++ b/arch/mips/sgi-ip22/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for the SGI specific kernel interface routines
+# under Linux.
+#
+
+obj-y	+= ip22-mc.o ip22-hpc.o ip22-int.o ip22-irq.o ip22-berr.o \
+	   ip22-time.o ip22-nvram.o ip22-reset.o ip22-setup.o
+
+obj-$(CONFIG_EISA)	+= ip22-eisa.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/sgi-ip22/ip22-berr.c b/arch/mips/sgi-ip22/ip22-berr.c
new file mode 100644
index 0000000..a28dc78
--- /dev/null
+++ b/arch/mips/sgi-ip22/ip22-berr.c
@@ -0,0 +1,114 @@
+/*
+ * ip22-berr.c: Bus error handling.
+ *
+ * Copyright (C) 2002, 2003 Ladislav Michl (ladis@linux-mips.org)
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/addrspace.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/branch.h>
+#include <asm/sgi/mc.h>
+#include <asm/sgi/hpc3.h>
+#include <asm/sgi/ioc.h>
+#include <asm/sgi/ip22.h>
+
+
+static unsigned int cpu_err_stat;	/* Status reg for CPU */
+static unsigned int gio_err_stat;	/* Status reg for GIO */
+static unsigned int cpu_err_addr;	/* Error address reg for CPU */
+static unsigned int gio_err_addr;	/* Error address reg for GIO */
+static unsigned int extio_stat;
+static unsigned int hpc3_berr_stat;	/* Bus error interrupt status */
+
+static void save_and_clear_buserr(void)
+{
+	/* save status registers */
+	cpu_err_addr = sgimc->cerr;
+	cpu_err_stat = sgimc->cstat;
+	gio_err_addr = sgimc->gerr;
+	gio_err_stat = sgimc->gstat;
+	extio_stat = ip22_is_fullhouse() ? sgioc->extio : (sgint->errstat << 4);
+	hpc3_berr_stat = hpc3c0->bestat;
+
+	sgimc->cstat = sgimc->gstat = 0;
+}
+
+#define GIO_ERRMASK	0xff00
+#define CPU_ERRMASK	0x3f00
+
+static void print_buserr(void)
+{
+	if (extio_stat & EXTIO_MC_BUSERR)
+		printk(KERN_ERR "MC Bus Error\n");
+	if (extio_stat & EXTIO_HPC3_BUSERR)
+		printk(KERN_ERR "HPC3 Bus Error 0x%x:<id=0x%x,%s,lane=0x%x>\n",
+			hpc3_berr_stat,
+			(hpc3_berr_stat & HPC3_BESTAT_PIDMASK) >>
+					  HPC3_BESTAT_PIDSHIFT,
+			(hpc3_berr_stat & HPC3_BESTAT_CTYPE) ? "PIO" : "DMA",
+			hpc3_berr_stat & HPC3_BESTAT_BLMASK);
+	if (extio_stat & EXTIO_EISA_BUSERR)
+		printk(KERN_ERR "EISA Bus Error\n");
+	if (cpu_err_stat & CPU_ERRMASK)
+		printk(KERN_ERR "CPU error 0x%x<%s%s%s%s%s%s> @ 0x%08x\n",
+			cpu_err_stat,
+			cpu_err_stat & SGIMC_CSTAT_RD ? "RD " : "",
+			cpu_err_stat & SGIMC_CSTAT_PAR ? "PAR " : "",
+			cpu_err_stat & SGIMC_CSTAT_ADDR ? "ADDR " : "",
+			cpu_err_stat & SGIMC_CSTAT_SYSAD_PAR ? "SYSAD " : "",
+			cpu_err_stat & SGIMC_CSTAT_SYSCMD_PAR ? "SYSCMD " : "",
+			cpu_err_stat & SGIMC_CSTAT_BAD_DATA ? "BAD_DATA " : "",
+			cpu_err_addr);
+	if (gio_err_stat & GIO_ERRMASK)
+		printk(KERN_ERR "GIO error 0x%x:<%s%s%s%s%s%s%s%s> @ 0x%08x\n",
+			gio_err_stat,
+			gio_err_stat & SGIMC_GSTAT_RD ? "RD " : "",
+			gio_err_stat & SGIMC_GSTAT_WR ? "WR " : "",
+			gio_err_stat & SGIMC_GSTAT_TIME ? "TIME " : "",
+			gio_err_stat & SGIMC_GSTAT_PROM ? "PROM " : "",
+			gio_err_stat & SGIMC_GSTAT_ADDR ? "ADDR " : "",
+			gio_err_stat & SGIMC_GSTAT_BC ? "BC " : "",
+			gio_err_stat & SGIMC_GSTAT_PIO_RD ? "PIO_RD " : "",
+			gio_err_stat & SGIMC_GSTAT_PIO_WR ? "PIO_WR " : "",
+			gio_err_addr);
+}
+
+/*
+ * MC sends an interrupt whenever bus or parity errors occur. In addition,
+ * if the error happened during a CPU read, it also asserts the bus error
+ * pin on the R4K. Code in bus error handler save the MC bus error registers
+ * and then clear the interrupt when this happens.
+ */
+
+void ip22_be_interrupt(int irq, struct pt_regs *regs)
+{
+	const int field = 2 * sizeof(unsigned long);
+
+	save_and_clear_buserr();
+	print_buserr();
+	printk(KERN_ALERT "%s bus error, epc == %0*lx, ra == %0*lx\n",
+	       (regs->cp0_cause & 4) ? "Data" : "Instruction",
+	       field, regs->cp0_epc, field, regs->regs[31]);
+	/* Assume it would be too dangerous to continue ... */
+	die_if_kernel("Oops", regs);
+	force_sig(SIGBUS, current);
+}
+
+static int ip22_be_handler(struct pt_regs *regs, int is_fixup)
+{
+	save_and_clear_buserr();
+	if (is_fixup)
+		return MIPS_BE_FIXUP;
+	print_buserr();
+	return MIPS_BE_FATAL;
+}
+
+void __init ip22_be_init(void)
+{
+	board_be_handler = ip22_be_handler;
+}
diff --git a/arch/mips/sgi-ip22/ip22-eisa.c b/arch/mips/sgi-ip22/ip22-eisa.c
new file mode 100644
index 0000000..0ab4abf
--- /dev/null
+++ b/arch/mips/sgi-ip22/ip22-eisa.c
@@ -0,0 +1,308 @@
+/*
+ * Basic EISA bus support for the SGI Indigo-2.
+ *
+ * (C) 2002 Pascal Dameme <netinet@freesurf.fr>
+ *      and Marc Zyngier <mzyngier@freesurf.fr>
+ *
+ * This code is released under both the GPL version 2 and BSD
+ * licenses.  Either license may be used.
+ *
+ * This code offers a very basic support for this EISA bus present in
+ * the SGI Indigo-2. It currently only supports PIO (forget about DMA
+ * for the time being). This is enough for a low-end ethernet card,
+ * but forget about your favorite SCSI card...
+ *
+ * TODO :
+ * - Fix bugs...
+ * - Add ISA support
+ * - Add DMA (yeah, right...).
+ * - Fix more bugs.
+ */
+
+#include <linux/config.h>
+#include <linux/eisa.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel_stat.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/processor.h>
+#include <asm/sgi/ioc.h>
+#include <asm/sgi/mc.h>
+#include <asm/sgi/ip22.h>
+
+#define EISA_MAX_SLOTS		  4
+#define EISA_MAX_IRQ             16
+
+#define EISA_TO_PHYS(x)  (0x00080000 | (x))
+#define EISA_TO_KSEG1(x) ((void *) KSEG1ADDR(EISA_TO_PHYS((x))))
+
+#define EIU_MODE_REG     0x0009ffc0
+#define EIU_STAT_REG     0x0009ffc4
+#define EIU_PREMPT_REG   0x0009ffc8
+#define EIU_QUIET_REG    0x0009ffcc
+#define EIU_INTRPT_ACK   0x00090004
+
+#define EISA_DMA1_STATUS            8
+#define EISA_INT1_CTRL           0x20
+#define EISA_INT1_MASK           0x21
+#define EISA_INT2_CTRL           0xA0
+#define EISA_INT2_MASK           0xA1
+#define EISA_DMA2_STATUS         0xD0
+#define EISA_DMA2_WRITE_SINGLE   0xD4
+#define EISA_EXT_NMI_RESET_CTRL 0x461
+#define EISA_INT1_EDGE_LEVEL    0x4D0
+#define EISA_INT2_EDGE_LEVEL    0x4D1
+#define EISA_VENDOR_ID_OFFSET   0xC80
+
+#define EIU_WRITE_32(x,y) { *((u32 *) KSEG1ADDR(x)) = (u32) (y); mb(); }
+#define EIU_READ_8(x) *((u8 *) KSEG1ADDR(x))
+#define EISA_WRITE_8(x,y) { *((u8 *) EISA_TO_KSEG1(x)) = (u8) (y); mb(); }
+#define EISA_READ_8(x) *((u8 *) EISA_TO_KSEG1(x))
+
+static char *decode_eisa_sig(u8 * sig)
+{
+	static char sig_str[8];
+	u16 rev;
+
+	if (sig[0] & 0x80)
+		return NULL;
+
+	sig_str[0] = ((sig[0] >> 2) & 0x1f) + ('A' - 1);
+	sig_str[1] = (((sig[0] & 3) << 3) | (sig[1] >> 5)) + ('A' - 1);
+	sig_str[2] = (sig[1] & 0x1f) + ('A' - 1);
+	rev = (sig[2] << 8) | sig[3];
+	sprintf(sig_str + 3, "%04X", rev);
+
+	return sig_str;
+}
+
+static void ip22_eisa_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	u8 eisa_irq;
+	u8 dma1, dma2;
+
+	eisa_irq = EIU_READ_8(EIU_INTRPT_ACK);
+	dma1 = EISA_READ_8(EISA_DMA1_STATUS);
+	dma2 = EISA_READ_8(EISA_DMA2_STATUS);
+
+	if (eisa_irq >= EISA_MAX_IRQ) {
+		/* Oops, Bad Stuff Happened... */
+		printk(KERN_ERR "eisa_irq %d out of bound\n", eisa_irq);
+
+		EISA_WRITE_8(EISA_INT2_CTRL, 0x20);
+		EISA_WRITE_8(EISA_INT1_CTRL, 0x20);
+	} else
+		do_IRQ(eisa_irq, regs);
+}
+
+static void enable_eisa1_irq(unsigned int irq)
+{
+	unsigned long flags;
+	u8 mask;
+
+	local_irq_save(flags);
+
+	mask = EISA_READ_8(EISA_INT1_MASK);
+	mask &= ~((u8) (1 << irq));
+	EISA_WRITE_8(EISA_INT1_MASK, mask);
+
+	local_irq_restore(flags);
+}
+
+static unsigned int startup_eisa1_irq(unsigned int irq)
+{
+	u8 edge;
+
+	/* Only use edge interrupts for EISA */
+
+	edge = EISA_READ_8(EISA_INT1_EDGE_LEVEL);
+	edge &= ~((u8) (1 << irq));
+	EISA_WRITE_8(EISA_INT1_EDGE_LEVEL, edge);
+
+	enable_eisa1_irq(irq);
+	return 0;
+}
+
+static void disable_eisa1_irq(unsigned int irq)
+{
+	u8 mask;
+
+	mask = EISA_READ_8(EISA_INT1_MASK);
+	mask |= ((u8) (1 << irq));
+	EISA_WRITE_8(EISA_INT1_MASK, mask);
+}
+
+#define shutdown_eisa1_irq	disable_eisa1_irq
+
+static void mask_and_ack_eisa1_irq(unsigned int irq)
+{
+	disable_eisa1_irq(irq);
+
+	EISA_WRITE_8(EISA_INT1_CTRL, 0x20);
+}
+
+static void end_eisa1_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		enable_eisa1_irq(irq);
+}
+
+static struct hw_interrupt_type ip22_eisa1_irq_type = {
+	.typename	= "IP22 EISA",
+	.startup	= startup_eisa1_irq,
+	.shutdown	= shutdown_eisa1_irq,
+	.enable		= enable_eisa1_irq,
+	.disable	= disable_eisa1_irq,
+	.ack		= mask_and_ack_eisa1_irq,
+	.end		= end_eisa1_irq,
+};
+
+static void enable_eisa2_irq(unsigned int irq)
+{
+	unsigned long flags;
+	u8 mask;
+
+	local_irq_save(flags);
+
+	mask = EISA_READ_8(EISA_INT2_MASK);
+	mask &= ~((u8) (1 << (irq - 8)));
+	EISA_WRITE_8(EISA_INT2_MASK, mask);
+
+	local_irq_restore(flags);
+}
+
+static unsigned int startup_eisa2_irq(unsigned int irq)
+{
+	u8 edge;
+
+	/* Only use edge interrupts for EISA */
+
+	edge = EISA_READ_8(EISA_INT2_EDGE_LEVEL);
+	edge &= ~((u8) (1 << (irq - 8)));
+	EISA_WRITE_8(EISA_INT2_EDGE_LEVEL, edge);
+
+	enable_eisa2_irq(irq);
+	return 0;
+}
+
+static void disable_eisa2_irq(unsigned int irq)
+{
+	u8 mask;
+
+	mask = EISA_READ_8(EISA_INT2_MASK);
+	mask |= ((u8) (1 << (irq - 8)));
+	EISA_WRITE_8(EISA_INT2_MASK, mask);
+}
+
+#define shutdown_eisa2_irq	disable_eisa2_irq
+
+static void mask_and_ack_eisa2_irq(unsigned int irq)
+{
+	disable_eisa2_irq(irq);
+
+	EISA_WRITE_8(EISA_INT2_CTRL, 0x20);
+	EISA_WRITE_8(EISA_INT1_CTRL, 0x20);
+}
+
+static void end_eisa2_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		enable_eisa2_irq(irq);
+}
+
+static struct hw_interrupt_type ip22_eisa2_irq_type = {
+	.typename	= "IP22 EISA",
+	.startup	= startup_eisa2_irq,
+	.shutdown	= shutdown_eisa2_irq,
+	.enable		= enable_eisa2_irq,
+	.disable	= disable_eisa2_irq,
+	.ack		= mask_and_ack_eisa2_irq,
+	.end		= end_eisa2_irq,
+};
+
+static struct irqaction eisa_action = {
+	.handler	= ip22_eisa_intr,
+	.name		= "EISA",
+};
+
+static struct irqaction cascade_action = {
+	.handler	= no_action,
+	.name		= "EISA cascade",
+};
+
+int __init ip22_eisa_init(void)
+{
+	int i, c;
+	char *str;
+	u8 *slot_addr;
+	
+	if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) {
+		printk(KERN_INFO "EISA: bus not present.\n");
+		return 1;
+	}
+
+	printk(KERN_INFO "EISA: Probing bus...\n");
+	for (c = 0, i = 1; i <= EISA_MAX_SLOTS; i++) {
+		slot_addr =
+		    (u8 *) EISA_TO_KSEG1((0x1000 * i) +
+					 EISA_VENDOR_ID_OFFSET);
+		if ((str = decode_eisa_sig(slot_addr))) {
+			printk(KERN_INFO "EISA: slot %d : %s detected.\n",
+			       i, str);
+			c++;
+		}
+	}
+	printk(KERN_INFO "EISA: Detected %d card%s.\n", c, c < 2 ? "" : "s");
+#ifdef CONFIG_ISA
+	printk(KERN_INFO "ISA support compiled in.\n");
+#endif
+
+	/* Warning : BlackMagicAhead(tm).
+	   Please wave your favorite dead chicken over the busses */
+
+	/* First say hello to the EIU */
+	EIU_WRITE_32(EIU_PREMPT_REG, 0x0000FFFF);
+	EIU_WRITE_32(EIU_QUIET_REG, 1);
+	EIU_WRITE_32(EIU_MODE_REG, 0x40f3c07F);
+
+	/* Now be nice to the EISA chipset */
+	EISA_WRITE_8(EISA_EXT_NMI_RESET_CTRL, 1);
+	for (i = 0; i < 10000; i++);	/* Wait long enough for the dust to settle */
+	EISA_WRITE_8(EISA_EXT_NMI_RESET_CTRL, 0);
+	EISA_WRITE_8(EISA_INT1_CTRL, 0x11);
+	EISA_WRITE_8(EISA_INT2_CTRL, 0x11);
+	EISA_WRITE_8(EISA_INT1_MASK, 0);
+	EISA_WRITE_8(EISA_INT2_MASK, 8);
+	EISA_WRITE_8(EISA_INT1_MASK, 4);
+	EISA_WRITE_8(EISA_INT2_MASK, 2);
+	EISA_WRITE_8(EISA_INT1_MASK, 1);
+	EISA_WRITE_8(EISA_INT2_MASK, 1);
+	EISA_WRITE_8(EISA_INT1_MASK, 0xfb);
+	EISA_WRITE_8(EISA_INT2_MASK, 0xff);
+	EISA_WRITE_8(EISA_DMA2_WRITE_SINGLE, 0);
+
+	for (i = SGINT_EISA; i < (SGINT_EISA + EISA_MAX_IRQ); i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = 0;
+		irq_desc[i].depth = 1;
+		if (i < (SGINT_EISA + 8))
+			irq_desc[i].handler = &ip22_eisa1_irq_type;
+		else
+			irq_desc[i].handler = &ip22_eisa2_irq_type;
+	}
+
+	/* Cannot use request_irq because of kmalloc not being ready at such
+	 * an early stage. Yes, I've been bitten... */
+	setup_irq(SGI_EISA_IRQ, &eisa_action);
+	setup_irq(SGINT_EISA + 2, &cascade_action);
+
+	EISA_bus = 1;
+	return 0;
+}
diff --git a/arch/mips/sgi-ip22/ip22-hpc.c b/arch/mips/sgi-ip22/ip22-hpc.c
new file mode 100644
index 0000000..c0afecc
--- /dev/null
+++ b/arch/mips/sgi-ip22/ip22-hpc.c
@@ -0,0 +1,63 @@
+/*
+ * ip22-hpc.c: Routines for generic manipulation of the HPC controllers.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1998 Ralf Baechle
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+
+#include <asm/io.h>
+#include <asm/sgi/hpc3.h>
+#include <asm/sgi/ioc.h>
+#include <asm/sgi/ip22.h>
+
+struct hpc3_regs *hpc3c0, *hpc3c1;
+
+EXPORT_SYMBOL(hpc3c0);
+EXPORT_SYMBOL(hpc3c1);
+
+struct sgioc_regs *sgioc;
+
+EXPORT_SYMBOL(sgioc);
+
+/* We need software copies of these because they are write only. */
+u8 sgi_ioc_reset, sgi_ioc_write;
+
+extern char *system_type;
+
+void __init sgihpc_init(void)
+{
+	/* ioremap can't fail */
+	hpc3c0 = (struct hpc3_regs *)
+		 ioremap(HPC3_CHIP0_BASE, sizeof(struct hpc3_regs));
+	hpc3c1 = (struct hpc3_regs *)
+		 ioremap(HPC3_CHIP1_BASE, sizeof(struct hpc3_regs));
+	/* IOC lives in PBUS PIO channel 6 */
+	sgioc = (struct sgioc_regs *)hpc3c0->pbus_extregs[6];
+
+	hpc3c0->pbus_piocfg[6][0] |= HPC3_PIOCFG_DS16;
+	if (ip22_is_fullhouse()) {
+		/* Full House comes with INT2 which lives in PBUS PIO
+		 * channel 4 */
+		sgint = (struct sgint_regs *)hpc3c0->pbus_extregs[4];
+		system_type = "SGI Indigo2";
+	} else {
+		/* Guiness comes with INT3 which is part of IOC */
+		sgint = &sgioc->int3;
+		system_type = "SGI Indy";
+	}
+	
+	sgi_ioc_reset = (SGIOC_RESET_PPORT | SGIOC_RESET_KBDMOUSE |
+			 SGIOC_RESET_EISA | SGIOC_RESET_ISDN |
+			 SGIOC_RESET_LC0OFF);
+
+	sgi_ioc_write = (SGIOC_WRITE_EASEL | SGIOC_WRITE_NTHRESH |
+			 SGIOC_WRITE_TPSPEED | SGIOC_WRITE_EPSEL |
+			 SGIOC_WRITE_U0AMODE | SGIOC_WRITE_U1AMODE);
+
+	sgioc->reset = sgi_ioc_reset;
+	sgioc->write = sgi_ioc_write;
+}
diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c
new file mode 100644
index 0000000..ea2844d
--- /dev/null
+++ b/arch/mips/sgi-ip22/ip22-int.c
@@ -0,0 +1,410 @@
+/*
+ * ip22-int.c: Routines for generic manipulation of the INT[23] ASIC
+ *             found on INDY and Indigo2 workstations.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu)
+ *                    - Indigo2 changes
+ *                    - Interrupt handling fixes
+ * Copyright (C) 2001, 2003 Ladislav Michl (ladis@linux-mips.org)
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+
+#include <asm/sgi/ioc.h>
+#include <asm/sgi/hpc3.h>
+#include <asm/sgi/ip22.h>
+
+/* #define DEBUG_SGINT */
+
+/* So far nothing hangs here */
+#undef USE_LIO3_IRQ 
+
+struct sgint_regs *sgint;
+
+static char lc0msk_to_irqnr[256];
+static char lc1msk_to_irqnr[256];
+static char lc2msk_to_irqnr[256];
+static char lc3msk_to_irqnr[256];
+
+extern asmlinkage void indyIRQ(void);
+extern int ip22_eisa_init(void);
+
+static void enable_local0_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	/* don't allow mappable interrupt to be enabled from setup_irq,
+	 * we have our own way to do so */
+	if (irq != SGI_MAP_0_IRQ)
+		sgint->imask0 |= (1 << (irq - SGINT_LOCAL0));
+	local_irq_restore(flags);
+}
+
+static unsigned int startup_local0_irq(unsigned int irq)
+{
+	enable_local0_irq(irq);
+	return 0;		/* Never anything pending  */
+}
+
+static void disable_local0_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	sgint->imask0 &= ~(1 << (irq - SGINT_LOCAL0));
+	local_irq_restore(flags);
+}
+
+#define shutdown_local0_irq	disable_local0_irq
+#define mask_and_ack_local0_irq	disable_local0_irq
+
+static void end_local0_irq (unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_local0_irq(irq);
+}
+
+static struct hw_interrupt_type ip22_local0_irq_type = {
+	.typename	= "IP22 local 0",
+	.startup	= startup_local0_irq,
+	.shutdown	= shutdown_local0_irq,
+	.enable		= enable_local0_irq,
+	.disable	= disable_local0_irq,
+	.ack		= mask_and_ack_local0_irq,
+	.end		= end_local0_irq,
+};
+
+static void enable_local1_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	/* don't allow mappable interrupt to be enabled from setup_irq,
+	 * we have our own way to do so */
+	if (irq != SGI_MAP_1_IRQ)
+		sgint->imask1 |= (1 << (irq - SGINT_LOCAL1));
+	local_irq_restore(flags);
+}
+
+static unsigned int startup_local1_irq(unsigned int irq)
+{
+	enable_local1_irq(irq);
+	return 0;		/* Never anything pending  */
+}
+
+void disable_local1_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	sgint->imask1 &= ~(1 << (irq - SGINT_LOCAL1));
+	local_irq_restore(flags);
+}
+
+#define shutdown_local1_irq	disable_local1_irq
+#define mask_and_ack_local1_irq	disable_local1_irq
+
+static void end_local1_irq (unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_local1_irq(irq);
+}
+
+static struct hw_interrupt_type ip22_local1_irq_type = {
+	.typename	= "IP22 local 1",
+	.startup	= startup_local1_irq,
+	.shutdown	= shutdown_local1_irq,
+	.enable		= enable_local1_irq,
+	.disable	= disable_local1_irq,
+	.ack		= mask_and_ack_local1_irq,
+	.end		= end_local1_irq,
+};
+
+static void enable_local2_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	sgint->imask0 |= (1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0));
+	sgint->cmeimask0 |= (1 << (irq - SGINT_LOCAL2));
+	local_irq_restore(flags);
+}
+
+static unsigned int startup_local2_irq(unsigned int irq)
+{
+	enable_local2_irq(irq);
+	return 0;		/* Never anything pending  */
+}
+
+void disable_local2_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	sgint->cmeimask0 &= ~(1 << (irq - SGINT_LOCAL2));
+	if (!sgint->cmeimask0)
+		sgint->imask0 &= ~(1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0));
+	local_irq_restore(flags);
+}
+
+#define shutdown_local2_irq disable_local2_irq
+#define mask_and_ack_local2_irq	disable_local2_irq
+
+static void end_local2_irq (unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_local2_irq(irq);
+}
+
+static struct hw_interrupt_type ip22_local2_irq_type = {
+	.typename	= "IP22 local 2",
+	.startup	= startup_local2_irq,
+	.shutdown	= shutdown_local2_irq,
+	.enable		= enable_local2_irq,
+	.disable	= disable_local2_irq,
+	.ack		= mask_and_ack_local2_irq,
+	.end		= end_local2_irq,
+};
+
+static void enable_local3_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	sgint->imask1 |= (1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1));
+	sgint->cmeimask1 |= (1 << (irq - SGINT_LOCAL3));
+	local_irq_restore(flags);
+}
+
+static unsigned int startup_local3_irq(unsigned int irq)
+{
+	enable_local3_irq(irq);
+	return 0;		/* Never anything pending  */
+}
+
+void disable_local3_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	sgint->cmeimask1 &= ~(1 << (irq - SGINT_LOCAL3));
+	if (!sgint->cmeimask1)
+		sgint->imask1 &= ~(1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1));
+	local_irq_restore(flags);
+}
+
+#define shutdown_local3_irq disable_local3_irq
+#define mask_and_ack_local3_irq	disable_local3_irq
+
+static void end_local3_irq (unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_local3_irq(irq);
+}
+
+static struct hw_interrupt_type ip22_local3_irq_type = {
+	.typename	= "IP22 local 3",
+	.startup	= startup_local3_irq,
+	.shutdown	= shutdown_local3_irq,
+	.enable		= enable_local3_irq,
+	.disable	= disable_local3_irq,
+	.ack		= mask_and_ack_local3_irq,
+	.end		= end_local3_irq,
+};
+
+void indy_local0_irqdispatch(struct pt_regs *regs)
+{
+	u8 mask = sgint->istat0 & sgint->imask0;
+	u8 mask2;
+	int irq;
+
+	if (mask & SGINT_ISTAT0_LIO2) {
+		mask2 = sgint->vmeistat & sgint->cmeimask0;
+		irq = lc2msk_to_irqnr[mask2];
+	} else
+		irq = lc0msk_to_irqnr[mask];
+
+	/* if irq == 0, then the interrupt has already been cleared */
+	if (irq)
+		do_IRQ(irq, regs);
+	return;
+}
+
+void indy_local1_irqdispatch(struct pt_regs *regs)
+{
+	u8 mask = sgint->istat1 & sgint->imask1;
+	u8 mask2;
+	int irq;
+
+	if (mask & SGINT_ISTAT1_LIO3) {
+		mask2 = sgint->vmeistat & sgint->cmeimask1;
+		irq = lc3msk_to_irqnr[mask2];
+	} else
+		irq = lc1msk_to_irqnr[mask];
+
+	/* if irq == 0, then the interrupt has already been cleared */
+	if (irq)
+		do_IRQ(irq, regs);
+	return;
+}
+
+extern void ip22_be_interrupt(int irq, struct pt_regs *regs);
+
+void indy_buserror_irq(struct pt_regs *regs)
+{
+	int irq = SGI_BUSERR_IRQ;
+
+	irq_enter();
+	kstat_this_cpu.irqs[irq]++;
+	ip22_be_interrupt(irq, regs);
+	irq_exit();
+}
+
+static struct irqaction local0_cascade = { 
+	.handler	= no_action,
+	.flags		= SA_INTERRUPT,
+	.name		= "local0 cascade",
+};
+
+static struct irqaction local1_cascade = { 
+	.handler	= no_action,
+	.flags		= SA_INTERRUPT,
+	.name		= "local1 cascade",
+};
+
+static struct irqaction buserr = { 
+	.handler	= no_action,
+	.flags		= SA_INTERRUPT,
+	.name		= "Bus Error",
+};
+
+static struct irqaction map0_cascade = { 
+	.handler	= no_action,
+	.flags		= SA_INTERRUPT,
+	.name		= "mapable0 cascade",
+};
+
+#ifdef USE_LIO3_IRQ
+static struct irqaction map1_cascade = { 
+	.handler	= no_action,
+	.flags		= SA_INTERRUPT,
+	.name		= "mapable1 cascade",
+};
+#define SGI_INTERRUPTS	SGINT_END
+#else
+#define SGI_INTERRUPTS	SGINT_LOCAL3
+#endif
+
+extern void mips_cpu_irq_init(unsigned int irq_base);
+
+void __init arch_init_irq(void)
+{
+	int i;
+
+	/* Init local mask --> irq tables. */
+	for (i = 0; i < 256; i++) {
+		if (i & 0x80) {
+			lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 7;
+			lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 7;
+			lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 7;
+			lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 7;
+		} else if (i & 0x40) {
+			lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 6;
+			lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 6;
+			lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 6;
+			lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 6;
+		} else if (i & 0x20) {
+			lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 5;
+			lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 5;
+			lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 5;
+			lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 5;
+		} else if (i & 0x10) {
+			lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 4;
+			lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 4;
+			lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 4;
+			lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 4;
+		} else if (i & 0x08) {
+			lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 3;
+			lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 3;
+			lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 3;
+			lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 3;
+		} else if (i & 0x04) {
+			lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 2;
+			lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 2;
+			lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 2;
+			lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 2;
+		} else if (i & 0x02) {
+			lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 1;
+			lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 1;
+			lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 1;
+			lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 1;
+		} else if (i & 0x01) {
+			lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 0;
+			lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 0;
+			lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 0;
+			lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 0;
+		} else {
+			lc0msk_to_irqnr[i] = 0;
+			lc1msk_to_irqnr[i] = 0;
+			lc2msk_to_irqnr[i] = 0;
+			lc3msk_to_irqnr[i] = 0;
+		}
+	}
+
+	/* Mask out all interrupts. */
+	sgint->imask0 = 0;
+	sgint->imask1 = 0;
+	sgint->cmeimask0 = 0;
+	sgint->cmeimask1 = 0;
+
+	set_except_vector(0, indyIRQ);
+
+	/* init CPU irqs */
+	mips_cpu_irq_init(SGINT_CPU);
+
+	for (i = SGINT_LOCAL0; i < SGI_INTERRUPTS; i++) {
+		hw_irq_controller *handler;
+
+		if (i < SGINT_LOCAL1)
+			handler		= &ip22_local0_irq_type;
+		else if (i < SGINT_LOCAL2)
+			handler		= &ip22_local1_irq_type;
+		else if (i < SGINT_LOCAL3)
+			handler		= &ip22_local2_irq_type;
+		else
+			handler		= &ip22_local3_irq_type;
+
+		irq_desc[i].status	= IRQ_DISABLED;
+		irq_desc[i].action	= 0;
+		irq_desc[i].depth	= 1;
+		irq_desc[i].handler	= handler;
+	}
+
+	/* vector handler. this register the IRQ as non-sharable */
+	setup_irq(SGI_LOCAL_0_IRQ, &local0_cascade);
+	setup_irq(SGI_LOCAL_1_IRQ, &local1_cascade);
+	setup_irq(SGI_BUSERR_IRQ, &buserr);
+
+	/* cascade in cascade. i love Indy ;-) */
+	setup_irq(SGI_MAP_0_IRQ, &map0_cascade);
+#ifdef USE_LIO3_IRQ
+	setup_irq(SGI_MAP_1_IRQ, &map1_cascade);
+#endif
+
+#ifdef CONFIG_EISA
+	if (ip22_is_fullhouse())	/* Only Indigo-2 has EISA stuff */
+	        ip22_eisa_init ();
+#endif
+}
diff --git a/arch/mips/sgi-ip22/ip22-irq.S b/arch/mips/sgi-ip22/ip22-irq.S
new file mode 100644
index 0000000..6ccbd9e
--- /dev/null
+++ b/arch/mips/sgi-ip22/ip22-irq.S
@@ -0,0 +1,118 @@
+/*
+ * ip22-irq.S: Interrupt exception dispatch code for FullHouse and
+ *             Guiness.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ */
+
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/* A lot of complication here is taken away because:
+ *
+ * 1) We handle one interrupt and return, sitting in a loop and moving across
+ *    all the pending IRQ bits in the cause register is _NOT_ the answer, the
+ *    common case is one pending IRQ so optimize in that direction.
+ *
+ * 2) We need not check against bits in the status register IRQ mask, that
+ *    would make this routine slow as hell.
+ *
+ * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
+ *    between like BSD spl() brain-damage.
+ *
+ * Furthermore, the IRQs on the INDY look basically (barring software IRQs
+ * which we don't use at all) like:
+ *
+ *	MIPS IRQ	Source
+ *      --------        ------
+ *             0	Software (ignored)
+ *             1        Software (ignored)
+ *             2        Local IRQ level zero
+ *             3        Local IRQ level one
+ *             4        8254 Timer zero
+ *             5        8254 Timer one
+ *             6        Bus Error
+ *             7        R4k timer (what we use)
+ *
+ * We handle the IRQ according to _our_ priority which is:
+ *
+ * Highest ----     R4k Timer
+ *                  Local IRQ zero
+ *                  Local IRQ one
+ *                  Bus Error
+ *                  8254 Timer zero
+ * Lowest  ----     8254 Timer one
+ *
+ * then we just return, if multiple IRQs are pending then we will just take
+ * another exception, big deal.
+ */
+
+	.text
+	.set	noreorder
+	.set	noat
+	.align	5
+	NESTED(indyIRQ, PT_SIZE, sp)
+	SAVE_ALL
+	CLI
+	.set	at
+	mfc0	s0, CP0_CAUSE		# get irq mask
+
+	/* First we check for r4k counter/timer IRQ. */
+	andi	a0, s0, CAUSEF_IP7
+	beq	a0, zero, 1f
+	 andi	a0, s0, CAUSEF_IP2	# delay slot, check local level zero
+
+	/* Wheee, a timer interrupt. */
+	jal	indy_r4k_timer_interrupt
+	 move	a0, sp			# delay slot
+	j	ret_from_irq
+	 nop				# delay slot
+
+1:
+	beq	a0, zero, 1f
+	 andi	a0, s0, CAUSEF_IP3	# delay slot, check local level one
+
+	/* Wheee, local level zero interrupt. */
+	jal	indy_local0_irqdispatch
+	 move	a0, sp			# delay slot
+
+	j	ret_from_irq
+	 nop				# delay slot
+
+1:
+	beq	a0, zero, 1f
+	 andi	a0, s0, CAUSEF_IP6	# delay slot, check bus error
+
+	/* Wheee, local level one interrupt. */
+	jal	indy_local1_irqdispatch
+	 move	a0, sp			# delay slot
+	j	ret_from_irq
+	 nop				# delay slot
+
+1:
+	beq	a0, zero, 1f
+	 andi	a0, s0, (CAUSEF_IP4 | CAUSEF_IP5)	# delay slot
+
+	/* Wheee, an asynchronous bus error... */
+	jal	indy_buserror_irq
+	 move	a0, sp			# delay slot
+	j	ret_from_irq
+	 nop				# delay slot
+
+1:
+	/* Here by mistake? It is possible, that by the time we take
+	 * the exception the IRQ pin goes low, so just leave if this
+	 * is the case.
+	 */
+	beq	a0, zero, 1f
+	 nop			  	# delay slot
+
+	/* Must be one of the 8254 timers... */
+	jal	indy_8254timer_irq
+	 move	a0, sp			# delay slot
+1:
+	j	ret_from_irq
+	 nop				# delay slot
+	END(indyIRQ)
diff --git a/arch/mips/sgi-ip22/ip22-mc.c b/arch/mips/sgi-ip22/ip22-mc.c
new file mode 100644
index 0000000..b58bd52
--- /dev/null
+++ b/arch/mips/sgi-ip22/ip22-mc.c
@@ -0,0 +1,208 @@
+/*
+ * ip22-mc.c: Routines for manipulating SGI Memory Controller.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - Indigo2 changes
+ * Copyright (C) 2003 Ladislav Michl  (ladis@linux-mips.org)
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+#include <asm/io.h>
+#include <asm/bootinfo.h>
+#include <asm/sgialib.h>
+#include <asm/sgi/mc.h>
+#include <asm/sgi/hpc3.h>
+#include <asm/sgi/ip22.h>
+
+struct sgimc_regs *sgimc;
+
+EXPORT_SYMBOL(sgimc);
+
+static inline unsigned long get_bank_addr(unsigned int memconfig)
+{
+	return ((memconfig & SGIMC_MCONFIG_BASEADDR) <<
+		((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 24 : 22));
+}
+
+static inline unsigned long get_bank_size(unsigned int memconfig)
+{
+	return ((memconfig & SGIMC_MCONFIG_RMASK) + 0x0100) <<
+		((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 16 : 14);
+}
+
+static inline unsigned int get_bank_config(int bank)
+{
+	unsigned int res = bank > 1 ? sgimc->mconfig1 : sgimc->mconfig0;
+	return bank % 2 ? res & 0xffff : res >> 16;
+}
+
+struct mem {
+	unsigned long addr;
+	unsigned long size;
+};
+
+/*
+ * Detect installed memory, do some sanity checks and notify kernel about it
+ */
+static void probe_memory(void)
+{
+	int i, j, found, cnt = 0;
+	struct mem bank[4];
+	struct mem space[2] = {{SGIMC_SEG0_BADDR, 0}, {SGIMC_SEG1_BADDR, 0}};
+
+	printk(KERN_INFO "MC: Probing memory configuration:\n");
+	for (i = 0; i < ARRAY_SIZE(bank); i++) {
+		unsigned int tmp = get_bank_config(i);
+		if (!(tmp & SGIMC_MCONFIG_BVALID))
+			continue;
+
+		bank[cnt].size = get_bank_size(tmp);
+		bank[cnt].addr = get_bank_addr(tmp);
+		printk(KERN_INFO " bank%d: %3ldM @ %08lx\n",
+			i, bank[cnt].size / 1024 / 1024, bank[cnt].addr);
+		cnt++;
+	}
+
+	/* And you thought bubble sort is dead algorithm... */
+	do {
+		unsigned long addr, size;
+
+		found = 0;
+		for (i = 1; i < cnt; i++)
+			if (bank[i-1].addr > bank[i].addr) {
+				addr = bank[i].addr;
+				size = bank[i].size;
+				bank[i].addr = bank[i-1].addr;
+				bank[i].size = bank[i-1].size;
+				bank[i-1].addr = addr;
+				bank[i-1].size = size;
+				found = 1;
+			}
+	} while (found);
+
+	/* Figure out how are memory banks mapped into spaces */
+	for (i = 0; i < cnt; i++) {
+		found = 0;
+		for (j = 0; j < ARRAY_SIZE(space) && !found; j++)
+			if (space[j].addr + space[j].size == bank[i].addr) {
+				space[j].size += bank[i].size;
+				found = 1;
+			}
+		/* There is either hole or overlapping memory */
+		if (!found)
+			printk(KERN_CRIT "MC: Memory configuration mismatch "
+					 "(%08lx), expect Bus Error soon\n",
+					 bank[i].addr);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(space); i++)
+		if (space[i].size)
+			add_memory_region(space[i].addr, space[i].size,
+					  BOOT_MEM_RAM);
+}
+
+void __init sgimc_init(void)
+{
+	u32 tmp;
+
+	/* ioremap can't fail */
+	sgimc = (struct sgimc_regs *)
+		ioremap(SGIMC_BASE, sizeof(struct sgimc_regs));
+
+	printk(KERN_INFO "MC: SGI memory controller Revision %d\n",
+	       (int) sgimc->systemid & SGIMC_SYSID_MASKREV);
+
+	/* Place the MC into a known state.  This must be done before
+	 * interrupts are first enabled etc.
+	 */
+
+	/* Step 0: Make sure we turn off the watchdog in case it's
+	 *         still running (which might be the case after a
+	 *         soft reboot).
+	 */
+	tmp = sgimc->cpuctrl0;
+	tmp &= ~SGIMC_CCTRL0_WDOG;
+	sgimc->cpuctrl0 = tmp;
+
+	/* Step 1: The CPU/GIO error status registers will not latch
+	 *         up a new error status until the register has been
+	 *         cleared by the cpu.  These status registers are
+	 *         cleared by writing any value to them.
+	 */
+	sgimc->cstat = sgimc->gstat = 0;
+
+	/* Step 2: Enable all parity checking in cpu control register
+	 *         zero.
+	 */
+	tmp = sgimc->cpuctrl0;
+	tmp |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM |
+		SGIMC_CCTRL0_R4KNOCHKPARR);
+	sgimc->cpuctrl0 = tmp;
+
+	/* Step 3: Setup the MC write buffer depth, this is controlled
+	 *         in cpu control register 1 in the lower 4 bits.
+	 */
+	tmp = sgimc->cpuctrl1;
+	tmp &= ~0xf;
+	tmp |= 0xd;
+	sgimc->cpuctrl1 = tmp;
+
+	/* Step 4: Initialize the RPSS divider register to run as fast
+	 *         as it can correctly operate.  The register is laid
+	 *         out as follows:
+	 *
+	 *         ----------------------------------------
+	 *         |  RESERVED  |   INCREMENT   | DIVIDER |
+	 *         ----------------------------------------
+	 *          31        16 15            8 7       0
+	 *
+	 *         DIVIDER determines how often a 'tick' happens,
+	 *         INCREMENT determines by how the RPSS increment
+	 *         registers value increases at each 'tick'. Thus,
+	 *         for IP22 we get INCREMENT=1, DIVIDER=1 == 0x101
+	 */
+	sgimc->divider = 0x101;
+
+	/* Step 5: Initialize GIO64 arbitrator configuration register.
+	 *
+	 * NOTE: HPC init code in sgihpc_init() must run before us because
+	 *       we need to know Guiness vs. FullHouse and the board
+	 *       revision on this machine. You have been warned.
+	 */
+
+	/* First the basic invariants across all GIO64 implementations. */
+	tmp = SGIMC_GIOPAR_HPC64;	/* All 1st HPC's interface at 64bits */
+	tmp |= SGIMC_GIOPAR_ONEBUS;	/* Only one physical GIO bus exists */
+
+	if (ip22_is_fullhouse()) {
+		/* Fullhouse specific settings. */
+		if (SGIOC_SYSID_BOARDREV(sgioc->sysid) < 2) {
+			tmp |= SGIMC_GIOPAR_HPC264;	/* 2nd HPC at 64bits */
+			tmp |= SGIMC_GIOPAR_PLINEEXP0;	/* exp0 pipelines */
+			tmp |= SGIMC_GIOPAR_MASTEREXP1;	/* exp1 masters */
+			tmp |= SGIMC_GIOPAR_RTIMEEXP0;	/* exp0 is realtime */
+		} else {
+			tmp |= SGIMC_GIOPAR_HPC264;	/* 2nd HPC 64bits */
+			tmp |= SGIMC_GIOPAR_PLINEEXP0;	/* exp[01] pipelined */
+			tmp |= SGIMC_GIOPAR_PLINEEXP1;
+			tmp |= SGIMC_GIOPAR_MASTEREISA;	/* EISA masters */
+			tmp |= SGIMC_GIOPAR_GFX64;	/* GFX at 64 bits */
+		}
+	} else {
+		/* Guiness specific settings. */
+		tmp |= SGIMC_GIOPAR_EISA64;	/* MC talks to EISA at 64bits */
+		tmp |= SGIMC_GIOPAR_MASTEREISA;	/* EISA bus can act as master */
+	}
+	sgimc->giopar = tmp;	/* poof */
+
+	probe_memory();
+}
+
+void __init prom_meminit(void) {}
+unsigned long __init prom_free_prom_memory(void)
+{
+	return 0;
+}
diff --git a/arch/mips/sgi-ip22/ip22-nvram.c b/arch/mips/sgi-ip22/ip22-nvram.c
new file mode 100644
index 0000000..de43e86
--- /dev/null
+++ b/arch/mips/sgi-ip22/ip22-nvram.c
@@ -0,0 +1,119 @@
+/*
+ * ip22-nvram.c: NVRAM and serial EEPROM handling.
+ *
+ * Copyright (C) 2003 Ladislav Michl (ladis@linux-mips.org)
+ */
+#include <linux/module.h>
+
+#include <asm/sgi/hpc3.h>
+#include <asm/sgi/ip22.h>
+
+/* Control opcode for serial eeprom  */
+#define EEPROM_READ	0xc000	/* serial memory read */
+#define EEPROM_WEN	0x9800	/* write enable before prog modes */
+#define EEPROM_WRITE	0xa000	/* serial memory write */
+#define EEPROM_WRALL	0x8800	/* write all registers */
+#define EEPROM_WDS	0x8000	/* disable all programming */
+#define	EEPROM_PRREAD	0xc000	/* read protect register */
+#define	EEPROM_PREN	0x9800	/* enable protect register mode */
+#define	EEPROM_PRCLEAR	0xffff	/* clear protect register */
+#define	EEPROM_PRWRITE	0xa000	/* write protect register */
+#define	EEPROM_PRDS	0x8000	/* disable protect register, forever */
+
+#define EEPROM_EPROT	0x01	/* Protect register enable */
+#define EEPROM_CSEL	0x02	/* Chip select */
+#define EEPROM_ECLK	0x04	/* EEPROM clock */
+#define EEPROM_DATO	0x08	/* Data out */
+#define EEPROM_DATI	0x10	/* Data in */
+
+/* We need to use these functions early... */
+#define delay()	({						\
+	int x;							\
+	for (x=0; x<100000; x++) __asm__ __volatile__(""); })
+
+#define eeprom_cs_on(ptr) ({	\
+	*ptr &= ~EEPROM_DATO;	\
+	*ptr &= ~EEPROM_ECLK;	\
+	*ptr &= ~EEPROM_EPROT;	\
+	delay();		\
+	*ptr |= EEPROM_CSEL;	\
+	*ptr |= EEPROM_ECLK; })
+
+		
+#define eeprom_cs_off(ptr) ({	\
+	*ptr &= ~EEPROM_ECLK;	\
+	*ptr &= ~EEPROM_CSEL;	\
+	*ptr |= EEPROM_EPROT;	\
+	*ptr |= EEPROM_ECLK; })
+
+#define	BITS_IN_COMMAND	11
+/*
+ * clock in the nvram command and the register number. For the
+ * national semiconductor nv ram chip the op code is 3 bits and
+ * the address is 6/8 bits. 
+ */
+static inline void eeprom_cmd(volatile unsigned int *ctrl, unsigned cmd,
+			      unsigned reg)
+{
+	unsigned short ser_cmd;
+	int i;
+
+	ser_cmd = cmd | (reg << (16 - BITS_IN_COMMAND));
+	for (i = 0; i < BITS_IN_COMMAND; i++) {
+		if (ser_cmd & (1<<15))	/* if high order bit set */
+			*ctrl |= EEPROM_DATO;
+		else
+			*ctrl &= ~EEPROM_DATO;
+		*ctrl &= ~EEPROM_ECLK;
+		*ctrl |= EEPROM_ECLK;
+		ser_cmd <<= 1;
+	}
+	*ctrl &= ~EEPROM_DATO;	/* see data sheet timing diagram */
+}
+
+unsigned short ip22_eeprom_read(volatile unsigned int *ctrl, int reg)
+{
+	unsigned short res = 0;
+	int i;
+
+	*ctrl &= ~EEPROM_EPROT;
+	eeprom_cs_on(ctrl);
+	eeprom_cmd(ctrl, EEPROM_READ, reg);
+
+	/* clock the data ouf of serial mem */
+	for (i = 0; i < 16; i++) {
+		*ctrl &= ~EEPROM_ECLK;
+		delay();
+		*ctrl |= EEPROM_ECLK;
+		delay();
+		res <<= 1;
+		if (*ctrl & EEPROM_DATI)
+			res |= 1;
+	}
+		
+	eeprom_cs_off(ctrl);
+
+	return res;
+}
+
+EXPORT_SYMBOL(ip22_eeprom_read);
+
+/*
+ * Read specified register from main NVRAM
+ */
+unsigned short ip22_nvram_read(int reg)
+{
+	if (ip22_is_fullhouse())
+		/* IP22 (Indigo2 aka FullHouse) stores env variables into
+		 * 93CS56 Microwire Bus EEPROM 2048 Bit (128x16) */
+		return ip22_eeprom_read(&hpc3c0->eeprom, reg);
+	else {
+		unsigned short tmp;
+		/* IP24 (Indy aka Guiness) uses DS1386 8K version */
+		reg <<= 1;
+		tmp = hpc3c0->bbram[reg++] & 0xff;
+		return (tmp << 8) | (hpc3c0->bbram[reg] & 0xff);
+	}		
+}
+
+EXPORT_SYMBOL(ip22_nvram_read);
diff --git a/arch/mips/sgi-ip22/ip22-reset.c b/arch/mips/sgi-ip22/ip22-reset.c
new file mode 100644
index 0000000..ed5c60a
--- /dev/null
+++ b/arch/mips/sgi-ip22/ip22-reset.c
@@ -0,0 +1,247 @@
+/*
+ * 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) 1997, 1998, 2001, 2003 by Ralf Baechle
+ */
+#include <linux/init.h>
+#include <linux/ds1286.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/notifier.h>
+#include <linux/timer.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/reboot.h>
+#include <asm/sgialib.h>
+#include <asm/sgi/ioc.h>
+#include <asm/sgi/hpc3.h>
+#include <asm/sgi/mc.h>
+#include <asm/sgi/ip22.h>
+
+/*
+ * Just powerdown if init hasn't done after POWERDOWN_TIMEOUT seconds.
+ * I'm not sure if this feature is a good idea, for now it's here just to
+ * make the power button make behave just like under IRIX.
+ */
+#define POWERDOWN_TIMEOUT	120
+
+/*
+ * Blink frequency during reboot grace period and when paniced.
+ */
+#define POWERDOWN_FREQ		(HZ / 4)
+#define PANIC_FREQ		(HZ / 8)
+
+static struct timer_list power_timer, blink_timer, debounce_timer, volume_timer;
+
+#define MACHINE_PANICED		1
+#define MACHINE_SHUTTING_DOWN	2
+static int machine_state = 0;
+
+static void sgi_machine_restart(char *command) __attribute__((noreturn));
+static void sgi_machine_halt(void) __attribute__((noreturn));
+static void sgi_machine_power_off(void) __attribute__((noreturn));
+
+static void sgi_machine_restart(char *command)
+{
+	if (machine_state & MACHINE_SHUTTING_DOWN)
+		sgi_machine_power_off();
+	sgimc->cpuctrl0 |= SGIMC_CCTRL0_SYSINIT;
+	while (1);
+}
+
+static void sgi_machine_halt(void)
+{
+	if (machine_state & MACHINE_SHUTTING_DOWN)
+		sgi_machine_power_off();
+	ArcEnterInteractiveMode();
+}
+
+static void sgi_machine_power_off(void)
+{
+	unsigned int tmp;
+
+	local_irq_disable();
+
+	/* Disable watchdog */
+	tmp = hpc3c0->rtcregs[RTC_CMD] & 0xff;
+	hpc3c0->rtcregs[RTC_CMD] = tmp | RTC_WAM;
+	hpc3c0->rtcregs[RTC_WSEC] = 0;
+	hpc3c0->rtcregs[RTC_WHSEC] = 0;
+
+	while (1) {
+		sgioc->panel = ~SGIOC_PANEL_POWERON;
+		/* Good bye cruel world ...  */
+
+		/* If we're still running, we probably got sent an alarm
+		   interrupt.  Read the flag to clear it.  */
+		tmp = hpc3c0->rtcregs[RTC_HOURS_ALARM];
+	}
+}
+
+static void power_timeout(unsigned long data)
+{
+	sgi_machine_power_off();
+}
+
+static void blink_timeout(unsigned long data)
+{
+	/* XXX fix this for fullhouse  */
+	sgi_ioc_reset ^= (SGIOC_RESET_LC0OFF|SGIOC_RESET_LC1OFF);
+	sgioc->reset = sgi_ioc_reset;
+
+	mod_timer(&blink_timer, jiffies+data);
+}
+
+static void debounce(unsigned long data)
+{
+	del_timer(&debounce_timer);
+	if (sgint->istat1 & SGINT_ISTAT1_PWR) {
+		/* Interrupt still being sent. */
+		debounce_timer.expires = jiffies + 5; /* 0.05s  */
+		add_timer(&debounce_timer);
+
+		sgioc->panel = SGIOC_PANEL_POWERON | SGIOC_PANEL_POWERINTR |
+			       SGIOC_PANEL_VOLDNINTR | SGIOC_PANEL_VOLDNHOLD |
+			       SGIOC_PANEL_VOLUPINTR | SGIOC_PANEL_VOLUPHOLD;
+
+		return;
+	}
+
+	if (machine_state & MACHINE_PANICED)
+		sgimc->cpuctrl0 |= SGIMC_CCTRL0_SYSINIT;
+
+	enable_irq(SGI_PANEL_IRQ);
+}
+
+static inline void power_button(void)
+{
+	if (machine_state & MACHINE_PANICED)
+		return;
+
+	if ((machine_state & MACHINE_SHUTTING_DOWN) || kill_proc(1,SIGINT,1)) {
+		/* No init process or button pressed twice.  */
+		sgi_machine_power_off();
+	}
+
+	machine_state |= MACHINE_SHUTTING_DOWN;
+	blink_timer.data = POWERDOWN_FREQ;
+	blink_timeout(POWERDOWN_FREQ);
+
+	init_timer(&power_timer);
+	power_timer.function = power_timeout;
+	power_timer.expires = jiffies + POWERDOWN_TIMEOUT * HZ;
+	add_timer(&power_timer);
+}
+
+void (*indy_volume_button)(int) = NULL;
+
+EXPORT_SYMBOL(indy_volume_button);
+
+static inline void volume_up_button(unsigned long data)
+{
+	del_timer(&volume_timer);
+
+	if (indy_volume_button)
+		indy_volume_button(1);
+
+	if (sgint->istat1 & SGINT_ISTAT1_PWR) {
+		volume_timer.expires = jiffies + 1;
+		add_timer(&volume_timer);
+	}
+}
+
+static inline void volume_down_button(unsigned long data)
+{
+	del_timer(&volume_timer);
+
+	if (indy_volume_button)
+		indy_volume_button(-1);
+
+	if (sgint->istat1 & SGINT_ISTAT1_PWR) {
+		volume_timer.expires = jiffies + 1;
+		add_timer(&volume_timer);
+	}
+}
+
+static irqreturn_t panel_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned int buttons;
+
+	buttons = sgioc->panel;
+	sgioc->panel = SGIOC_PANEL_POWERON | SGIOC_PANEL_POWERINTR;
+
+	if (sgint->istat1 & SGINT_ISTAT1_PWR) {
+		/* Wait until interrupt goes away */
+		disable_irq(SGI_PANEL_IRQ);
+		init_timer(&debounce_timer);
+		debounce_timer.function = debounce;
+		debounce_timer.expires = jiffies + 5;
+		add_timer(&debounce_timer);
+	}
+
+	/* Power button was pressed 
+	 * ioc.ps page 22: "The Panel Register is called Power Control by Full
+	 * House. Only lowest 2 bits are used. Guiness uses upper four bits
+	 * for volume control". This is not true, all bits are pulled high
+	 * on fullhouse */
+	if (ip22_is_fullhouse() || !(buttons & SGIOC_PANEL_POWERINTR)) {
+		power_button();
+		return IRQ_HANDLED;
+	}
+	/* TODO: mute/unmute */
+	/* Volume up button was pressed */
+	if (!(buttons & SGIOC_PANEL_VOLUPINTR)) {
+		init_timer(&volume_timer);
+		volume_timer.function = volume_up_button;
+		volume_timer.expires = jiffies + 1;
+		add_timer(&volume_timer);
+	}
+	/* Volume down button was pressed */
+	if (!(buttons & SGIOC_PANEL_VOLDNINTR)) {
+		init_timer(&volume_timer);
+		volume_timer.function = volume_down_button;
+		volume_timer.expires = jiffies + 1;
+		add_timer(&volume_timer);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int panic_event(struct notifier_block *this, unsigned long event,
+                      void *ptr)
+{
+	if (machine_state & MACHINE_PANICED)
+		return NOTIFY_DONE;
+	machine_state |= MACHINE_PANICED;
+
+	blink_timer.data = PANIC_FREQ;
+	blink_timeout(PANIC_FREQ);
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block panic_block = {
+	.notifier_call	= panic_event,
+};
+
+static int __init reboot_setup(void)
+{
+	_machine_restart = sgi_machine_restart;
+	_machine_halt = sgi_machine_halt;
+	_machine_power_off = sgi_machine_power_off;
+
+	request_irq(SGI_PANEL_IRQ, panel_int, 0, "Front Panel", NULL);
+	init_timer(&blink_timer);
+	blink_timer.function = blink_timeout;
+	notifier_chain_register(&panic_notifier_list, &panic_block);
+
+	return 0;
+}
+
+subsys_initcall(reboot_setup);
diff --git a/arch/mips/sgi-ip22/ip22-setup.c b/arch/mips/sgi-ip22/ip22-setup.c
new file mode 100644
index 0000000..0e96a5d
--- /dev/null
+++ b/arch/mips/sgi-ip22/ip22-setup.c
@@ -0,0 +1,144 @@
+/*
+ * ip22-setup.c: SGI specific setup, including init of the feature struct.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org)
+ */
+#include <linux/config.h>
+#include <linux/ds1286.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/kdev_t.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/console.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+
+#include <asm/addrspace.h>
+#include <asm/bcache.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/reboot.h>
+#include <asm/time.h>
+#include <asm/gdb-stub.h>
+#include <asm/io.h>
+#include <asm/traps.h>
+#include <asm/sgialib.h>
+#include <asm/sgi/mc.h>
+#include <asm/sgi/hpc3.h>
+#include <asm/sgi/ip22.h>
+
+unsigned long sgi_gfxaddr;
+
+/*
+ * Stop-A is originally a Sun thing that isn't standard on IP22 so to avoid
+ * accidents it's disabled by default on IP22.
+ *
+ * FIXME: provide a mechanism to change the value of stop_a_enabled.
+ */
+int stop_a_enabled;
+
+void ip22_do_break(void)
+{
+	if (!stop_a_enabled)
+		return;
+
+	printk("\n");
+	ArcEnterInteractiveMode();
+}
+
+EXPORT_SYMBOL(ip22_do_break);
+
+extern void ip22_be_init(void) __init;
+extern void ip22_time_init(void) __init;
+
+static int __init ip22_setup(void)
+{
+	char *ctype;
+
+	board_be_init = ip22_be_init;
+	ip22_time_init();
+
+	/* Init the INDY HPC I/O controller.  Need to call this before
+	 * fucking with the memory controller because it needs to know the
+	 * boardID and whether this is a Guiness or a FullHouse machine.
+	 */
+	sgihpc_init();
+
+	/* Init INDY memory controller. */
+	sgimc_init();
+
+#ifdef CONFIG_BOARD_SCACHE
+	/* Now enable boardcaches, if any. */
+	indy_sc_init();
+#endif
+
+	/* Set EISA IO port base for Indigo2
+	 * ioremap cannot fail */
+	set_io_port_base((unsigned long)ioremap(0x00080000,
+						0x1fffffff - 0x00080000));
+	/* ARCS console environment variable is set to "g?" for
+	 * graphics console, it is set to "d" for the first serial
+	 * line and "d2" for the second serial line.
+	 */
+	ctype = ArcGetEnvironmentVariable("console");
+	if (ctype && *ctype == 'd') {
+		static char options[8];
+		char *baud = ArcGetEnvironmentVariable("dbaud");
+		if (baud)
+			strcpy(options, baud);
+		add_preferred_console("ttyS", *(ctype + 1) == '2' ? 1 : 0,
+				      baud ? options : NULL);
+	} else if (!ctype || *ctype != 'g') {
+		/* Use ARC if we don't want serial ('d') or Newport ('g'). */
+		prom_flags |= PROM_FLAG_USE_AS_CONSOLE;
+		add_preferred_console("arc", 0, NULL);
+	}
+
+#ifdef CONFIG_KGDB
+	{
+	char *kgdb_ttyd = prom_getcmdline();
+
+	if ((kgdb_ttyd = strstr(kgdb_ttyd, "kgdb=ttyd")) != NULL) {
+		int line;
+		kgdb_ttyd += strlen("kgdb=ttyd");
+		if (*kgdb_ttyd != '1' && *kgdb_ttyd != '2')
+			printk(KERN_INFO "KGDB: Uknown serial line /dev/ttyd%c"
+			       ", falling back to /dev/ttyd1\n", *kgdb_ttyd);
+		line = *kgdb_ttyd == '2' ? 0 : 1;
+		printk(KERN_INFO "KGDB: Using serial line /dev/ttyd%d for "
+		       "session\n", line ? 1 : 2);
+		rs_kgdb_hook(line);
+
+		printk(KERN_INFO "KGDB: Using serial line /dev/ttyd%d for "
+		       "session, please connect your debugger\n", line ? 1:2);
+
+		kgdb_enabled = 1;
+		/* Breakpoints and stuff are in sgi_irq_setup() */
+	}
+	}
+#endif
+
+#if defined(CONFIG_VT) && defined(CONFIG_SGI_NEWPORT_CONSOLE)
+	{
+		ULONG *gfxinfo;
+		ULONG * (*__vec)(void) = (void *) (long)
+			*((_PULONG *)(long)((PROMBLOCK)->pvector + 0x20));
+
+		gfxinfo = __vec();
+		sgi_gfxaddr = ((gfxinfo[1] >= 0xa0000000
+			       && gfxinfo[1] <= 0xc0000000)
+			       ? gfxinfo[1] - 0xa0000000 : 0);
+
+		/* newport addresses? */
+		if (sgi_gfxaddr == 0x1f0f0000 || sgi_gfxaddr == 0x1f4f0000) {
+			conswitchp = &newport_con;
+		}
+	}
+#endif
+
+	return 0;
+}
+
+early_initcall(ip22_setup);
diff --git a/arch/mips/sgi-ip22/ip22-time.c b/arch/mips/sgi-ip22/ip22-time.c
new file mode 100644
index 0000000..173f768
--- /dev/null
+++ b/arch/mips/sgi-ip22/ip22-time.c
@@ -0,0 +1,214 @@
+/*
+ * 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.
+ *
+ * Time operations for IP22 machines. Original code may come from
+ * Ralf Baechle or David S. Miller (sorry guys, i'm really not sure)
+ *
+ * Copyright (C) 2001 by Ladislav Michl
+ * Copyright (C) 2003 Ralf Baechle (ralf@linux-mips.org)
+ */
+#include <linux/bcd.h>
+#include <linux/ds1286.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/time.h>
+
+#include <asm/cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/time.h>
+#include <asm/sgialib.h>
+#include <asm/sgi/ioc.h>
+#include <asm/sgi/hpc3.h>
+#include <asm/sgi/ip22.h>
+
+/*
+ * note that mktime uses month from 1 to 12 while to_tm
+ * uses 0 to 11.
+ */
+static unsigned long indy_rtc_get_time(void)
+{
+	unsigned int yrs, mon, day, hrs, min, sec;
+	unsigned int save_control;
+
+	save_control = hpc3c0->rtcregs[RTC_CMD] & 0xff;
+	hpc3c0->rtcregs[RTC_CMD] = save_control | RTC_TE;
+
+	sec = BCD2BIN(hpc3c0->rtcregs[RTC_SECONDS] & 0xff);
+	min = BCD2BIN(hpc3c0->rtcregs[RTC_MINUTES] & 0xff);
+	hrs = BCD2BIN(hpc3c0->rtcregs[RTC_HOURS] & 0x3f);
+	day = BCD2BIN(hpc3c0->rtcregs[RTC_DATE] & 0xff);
+	mon = BCD2BIN(hpc3c0->rtcregs[RTC_MONTH] & 0x1f);
+	yrs = BCD2BIN(hpc3c0->rtcregs[RTC_YEAR] & 0xff);
+
+	hpc3c0->rtcregs[RTC_CMD] = save_control;
+
+	if (yrs < 45)
+		yrs += 30;
+	if ((yrs += 40) < 70)
+		yrs += 100;
+
+	return mktime(yrs + 1900, mon, day, hrs, min, sec);
+}
+
+static int indy_rtc_set_time(unsigned long tim)
+{
+	struct rtc_time tm;
+	unsigned int save_control;
+
+	to_tm(tim, &tm);
+
+	tm.tm_mon += 1;		/* tm_mon starts at zero */
+	tm.tm_year -= 1940;
+	if (tm.tm_year >= 100)
+		tm.tm_year -= 100;
+
+	save_control = hpc3c0->rtcregs[RTC_CMD] & 0xff;
+	hpc3c0->rtcregs[RTC_CMD] = save_control | RTC_TE;
+
+	hpc3c0->rtcregs[RTC_YEAR] = BIN2BCD(tm.tm_sec);
+	hpc3c0->rtcregs[RTC_MONTH] = BIN2BCD(tm.tm_mon);
+	hpc3c0->rtcregs[RTC_DATE] = BIN2BCD(tm.tm_mday);
+	hpc3c0->rtcregs[RTC_HOURS] = BIN2BCD(tm.tm_hour);
+	hpc3c0->rtcregs[RTC_MINUTES] = BIN2BCD(tm.tm_min);
+	hpc3c0->rtcregs[RTC_SECONDS] = BIN2BCD(tm.tm_sec);
+	hpc3c0->rtcregs[RTC_HUNDREDTH_SECOND] = 0;
+
+	hpc3c0->rtcregs[RTC_CMD] = save_control;
+
+	return 0;
+}
+
+static unsigned long dosample(void)
+{
+	u32 ct0, ct1;
+	volatile u8 msb, lsb;
+
+	/* Start the counter. */
+	sgint->tcword = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL |
+			 SGINT_TCWORD_MRGEN);
+	sgint->tcnt2 = SGINT_TCSAMP_COUNTER & 0xff;
+	sgint->tcnt2 = SGINT_TCSAMP_COUNTER >> 8;
+
+	/* Get initial counter invariant */
+	ct0 = read_c0_count();
+
+	/* Latch and spin until top byte of counter2 is zero */
+	do {
+		sgint->tcword = SGINT_TCWORD_CNT2 | SGINT_TCWORD_CLAT;
+		lsb = sgint->tcnt2;
+		msb = sgint->tcnt2;
+		ct1 = read_c0_count();
+	} while (msb);
+
+	/* Stop the counter. */
+	sgint->tcword = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL |
+			 SGINT_TCWORD_MSWST);
+	/*
+	 * Return the difference, this is how far the r4k counter increments
+	 * for every 1/HZ seconds. We round off the nearest 1 MHz of master
+	 * clock (= 1000000 / HZ / 2).
+	 */
+	/*return (ct1 - ct0 + (500000/HZ/2)) / (500000/HZ) * (500000/HZ);*/
+	return (ct1 - ct0) / (500000/HZ) * (500000/HZ);
+}
+
+/*
+ * Here we need to calibrate the cycle counter to at least be close.
+ */
+static __init void indy_time_init(void)
+{
+	unsigned long r4k_ticks[3];
+	unsigned long r4k_tick;
+
+	/* 
+	 * Figure out the r4k offset, the algorithm is very simple and works in
+	 * _all_ cases as long as the 8254 counter register itself works ok (as
+	 * an interrupt driving timer it does not because of bug, this is why
+	 * we are using the onchip r4k counter/compare register to serve this
+	 * purpose, but for r4k_offset calculation it will work ok for us).
+	 * There are other very complicated ways of performing this calculation
+	 * but this one works just fine so I am not going to futz around. ;-)
+	 */
+	printk(KERN_INFO "Calibrating system timer... ");
+	dosample();	/* Prime cache. */
+	dosample();	/* Prime cache. */
+	/* Zero is NOT an option. */
+	do {
+		r4k_ticks[0] = dosample();
+	} while (!r4k_ticks[0]);
+	do {
+		r4k_ticks[1] = dosample();
+	} while (!r4k_ticks[1]);
+
+	if (r4k_ticks[0] != r4k_ticks[1]) {
+		printk("warning: timer counts differ, retrying... ");
+		r4k_ticks[2] = dosample();
+		if (r4k_ticks[2] == r4k_ticks[0]
+		    || r4k_ticks[2] == r4k_ticks[1])
+			r4k_tick = r4k_ticks[2];
+		else {
+			printk("disagreement, using average... ");
+			r4k_tick = (r4k_ticks[0] + r4k_ticks[1]
+				   + r4k_ticks[2]) / 3;
+		}
+	} else
+		r4k_tick = r4k_ticks[0];
+
+	printk("%d [%d.%04d MHz CPU]\n", (int) r4k_tick,
+		(int) (r4k_tick / (500000 / HZ)),
+		(int) (r4k_tick % (500000 / HZ)));
+
+	mips_hpt_frequency = r4k_tick * HZ;
+}
+
+/* Generic SGI handler for (spurious) 8254 interrupts */
+void indy_8254timer_irq(struct pt_regs *regs)
+{
+	int irq = SGI_8254_0_IRQ;
+	ULONG cnt;
+	char c;
+
+	irq_enter();
+	kstat_this_cpu.irqs[irq]++;
+	printk(KERN_ALERT "Oops, got 8254 interrupt.\n");
+	ArcRead(0, &c, 1, &cnt);
+	ArcEnterInteractiveMode();
+	irq_exit();
+}
+
+void indy_r4k_timer_interrupt(struct pt_regs *regs)
+{
+	int irq = SGI_TIMER_IRQ;
+
+	irq_enter();
+	kstat_this_cpu.irqs[irq]++;
+	timer_interrupt(irq, NULL, regs);
+	irq_exit();
+}
+
+extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
+
+static void indy_timer_setup(struct irqaction *irq)
+{
+	/* over-write the handler, we use our own way */
+	irq->handler = no_action;
+
+	/* setup irqaction */
+	setup_irq(SGI_TIMER_IRQ, irq);
+}
+
+void __init ip22_time_init(void)
+{
+	/* setup hookup functions */
+	rtc_get_time = indy_rtc_get_time;
+	rtc_set_time = indy_rtc_set_time;
+
+	board_time_init = indy_time_init;
+	board_timer_setup = indy_timer_setup;
+}
diff --git a/arch/mips/sgi-ip27/Makefile b/arch/mips/sgi-ip27/Makefile
new file mode 100644
index 0000000..4ba3407
--- /dev/null
+++ b/arch/mips/sgi-ip27/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for the IP27 specific kernel interface routines under Linux.
+#
+
+obj-y	:= ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o ip27-irq-glue.o \
+	   ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-reset.o \
+	   ip27-timer.o ip27-hubio.o ip27-xtalk.o
+
+obj-$(CONFIG_KGDB)	+= ip27-dbgio.o
+obj-$(CONFIG_SMP)	+= ip27-smp.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/sgi-ip27/TODO b/arch/mips/sgi-ip27/TODO
new file mode 100644
index 0000000..3210613
--- /dev/null
+++ b/arch/mips/sgi-ip27/TODO
@@ -0,0 +1,23 @@
+1. Need to figure out why PCI writes to the IOC3 hang, and if it is okay
+not to write to the IOC3 ever.
+2. Need to figure out RRB allocation in bridge_startup().
+3. Need to figure out why address swaizzling is needed in inw/outw for
+Qlogic scsi controllers.
+4. Need to integrate ip27-klconfig.c:find_lboard and
+ip27-init.c:find_lbaord_real. DONE
+5. Is it okay to set calias space on all nodes as 0, instead of 8k as
+in irix?
+6. Investigate why things do not work without the setup_test() call
+being invoked on all nodes in ip27-memory.c.
+7. Too many CLIs in the locore handlers :
+For the low level handlers set up by set_except_vector(),
+__tlb_refill_debug_tramp, __xtlb_refill_debug_tramp and cacheerror,
+investigate whether the code should do CLI, STI or KMODE.
+8. Too many do_page_faults invoked - investigate.
+9. start_thread must turn off UX64 ... and define tlb_refill_debug.
+10. Need a bad pmd table, bad pte table. __bad_pmd_table/__bad_pagetable
+does not agree with pgd_bad/pmd_bad.
+11. All intrs (ip27_do_irq handlers) are targetted at cpu A on the node.
+This might need to change later. Only the timer intr is set up to be
+received on both Cpu A and B. (ip27_do_irq()/bridge_startup())
+13. Cache flushing (specially the SMP version) has to be investigated.
diff --git a/arch/mips/sgi-ip27/ip27-berr.c b/arch/mips/sgi-ip27/ip27-berr.c
new file mode 100644
index 0000000..e1829a5
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-berr.c
@@ -0,0 +1,94 @@
+/*
+ * 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) 1994, 1995, 1996, 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 by Silicon Graphics
+ * Copyright (C) 2002  Maciej W. Rozycki
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/module.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/sn0/hub.h>
+#include <asm/tlbdebug.h>
+#include <asm/traps.h>
+#include <asm/uaccess.h>
+
+extern void dump_tlb_addr(unsigned long addr);
+extern void dump_tlb_all(void);
+
+static void dump_hub_information(unsigned long errst0, unsigned long errst1)
+{
+	static char *err_type[2][8] = {
+		{ NULL, "Uncached Partial Read PRERR", "DERR", "Read Timeout",
+		  NULL, NULL, NULL, NULL },
+		{ "WERR", "Uncached Partial Write", "PWERR", "Write Timeout",
+		  NULL, NULL, NULL, NULL }
+	};
+	int wrb = errst1 & PI_ERR_ST1_WRBRRB_MASK;
+
+	if (!(errst0 & PI_ERR_ST0_VALID_MASK)) {
+		printk("Hub does not contain valid error information\n");
+		return;
+	}
+
+
+	printk("Hub has valid error information:\n");
+	if (errst0 & PI_ERR_ST0_OVERRUN_MASK)
+		printk("Overrun is set.  Error stack may contain additional "
+		       "information.\n");
+	printk("Hub error address is %08lx\n",
+	       (errst0 & PI_ERR_ST0_ADDR_MASK) >> (PI_ERR_ST0_ADDR_SHFT - 3));
+	printk("Incoming message command 0x%lx\n",
+	       (errst0 & PI_ERR_ST0_CMD_MASK) >> PI_ERR_ST0_CMD_SHFT);
+	printk("Supplemental field of incoming message is 0x%lx\n",
+	       (errst0 & PI_ERR_ST0_SUPPL_MASK) >> PI_ERR_ST0_SUPPL_SHFT);
+	printk("T5 Rn (for RRB only) is 0x%lx\n",
+	       (errst0 & PI_ERR_ST0_REQNUM_MASK) >> PI_ERR_ST0_REQNUM_SHFT);
+	printk("Error type is %s\n", err_type[wrb]
+	       [(errst0 & PI_ERR_ST0_TYPE_MASK) >> PI_ERR_ST0_TYPE_SHFT]
+		? : "invalid");
+}
+
+int ip27_be_handler(struct pt_regs *regs, int is_fixup)
+{
+	unsigned long errst0, errst1;
+	int data = regs->cp0_cause & 4;
+	int cpu = LOCAL_HUB_L(PI_CPU_NUM);
+
+	if (is_fixup)
+		return MIPS_BE_FIXUP;
+
+	printk("Slice %c got %cbe at 0x%lx\n", 'A' + cpu, data ? 'd' : 'i',
+	       regs->cp0_epc);
+	printk("Hub information:\n");
+	printk("ERR_INT_PEND = 0x%06lx\n", LOCAL_HUB_L(PI_ERR_INT_PEND));
+	errst0 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS0_B : PI_ERR_STATUS0_A);
+	errst1 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS1_B : PI_ERR_STATUS1_A);
+	dump_hub_information(errst0, errst1);
+	show_regs(regs);
+	dump_tlb_all();
+	while(1);
+	force_sig(SIGBUS, current);
+}
+
+void __init ip27_be_init(void)
+{
+	/* XXX Initialize all the Hub & Bridge error handling here.  */
+	int cpu = LOCAL_HUB_L(PI_CPU_NUM);
+	int cpuoff = cpu << 8;
+
+	board_be_handler = ip27_be_handler;
+
+	LOCAL_HUB_S(PI_ERR_INT_PEND,
+	            cpu ? PI_ERR_CLEAR_ALL_B : PI_ERR_CLEAR_ALL_A);
+	LOCAL_HUB_S(PI_ERR_INT_MASK_A + cpuoff, 0);
+	LOCAL_HUB_S(PI_ERR_STACK_ADDR_A + cpuoff, 0);
+	LOCAL_HUB_S(PI_ERR_STACK_SIZE, 0);	/* Disable error stack */
+	LOCAL_HUB_S(PI_SYSAD_ERRCHK_EN, PI_SYSAD_CHECK_ALL);
+}
diff --git a/arch/mips/sgi-ip27/ip27-console.c b/arch/mips/sgi-ip27/ip27-console.c
new file mode 100644
index 0000000..d97f5b5
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-console.c
@@ -0,0 +1,76 @@
+/*
+ * 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) 2001, 2002 Ralf Baechle
+ */
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/kdev_t.h>
+#include <linux/major.h>
+#include <linux/termios.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+
+#include <asm/page.h>
+#include <asm/semaphore.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/sn0/hub.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/ioc3.h>
+#include <asm/sn/sn_private.h>
+
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+
+#define IOC3_CLK	(22000000 / 3)
+#define IOC3_FLAGS	(0)
+
+static inline struct ioc3_uartregs *console_uart(void)
+{
+	struct ioc3 *ioc3;
+
+	ioc3 = (struct ioc3 *)KL_CONFIG_CH_CONS_INFO(get_nasid())->memory_base;
+
+	return &ioc3->sregs.uarta;
+}
+
+void prom_putchar(char c)
+{
+	struct ioc3_uartregs *uart = console_uart();
+
+	while ((uart->iu_lsr & 0x20) == 0);
+	uart->iu_thr = c;
+}
+
+char __init prom_getchar(void)
+{
+	return 0;
+}
+
+static void inline ioc3_console_probe(void)
+{
+	struct uart_port up;
+
+	/*
+	 * Register to interrupt zero because we share the interrupt with
+	 * the serial driver which we don't properly support yet.
+	 */
+	memset(&up, 0, sizeof(up));
+	up.membase	= (unsigned char *) console_uart();
+	up.irq		= 0;
+	up.uartclk	= IOC3_CLK;
+	up.regshift	= 0;
+	up.iotype	= UPIO_MEM;
+	up.flags	= IOC3_FLAGS;
+	up.line		= 0;
+
+	if (early_serial_setup(&up))
+		printk(KERN_ERR "Early serial init of port 0 failed\n");
+}
+
+__init void ip27_setup_console(void)
+{
+	ioc3_console_probe();
+}
diff --git a/arch/mips/sgi-ip27/ip27-dbgio.c b/arch/mips/sgi-ip27/ip27-dbgio.c
new file mode 100644
index 0000000..08fd88b
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-dbgio.c
@@ -0,0 +1,60 @@
+/*
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Copyright 2004 Ralf Baechle <ralf@linux-mips.org>
+ */
+#include <asm/sn/addrs.h>
+#include <asm/sn/sn0/hub.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/ioc3.h>
+#include <asm/sn/sn_private.h>
+
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+
+#define IOC3_CLK        (22000000 / 3)
+#define IOC3_FLAGS      (0)
+
+static inline struct ioc3_uartregs *console_uart(void)
+{
+	struct ioc3 *ioc3;
+
+	ioc3 = (struct ioc3 *)KL_CONFIG_CH_CONS_INFO(get_nasid())->memory_base;
+
+	return &ioc3->sregs.uarta;
+}
+
+unsigned char getDebugChar(void)
+{
+	struct ioc3_uartregs *uart = console_uart();
+
+	while ((uart->iu_lsr & UART_LSR_DR) == 0);
+	return uart->iu_rbr;
+}
+
+void putDebugChar(unsigned char c)
+{
+	struct ioc3_uartregs *uart = console_uart();
+
+	while ((uart->iu_lsr & UART_LSR_THRE) == 0);
+	uart->iu_thr = c;
+}
diff --git a/arch/mips/sgi-ip27/ip27-hubio.c b/arch/mips/sgi-ip27/ip27-hubio.c
new file mode 100644
index 0000000..524b371
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-hubio.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.
+ * Copyright (C) 2004 Christoph Hellwig.
+ *	Released under GPL v2.
+ *
+ * Support functions for the HUB ASIC - mostly PIO mapping related.
+ */
+
+#include <linux/bitops.h>
+#include <linux/string.h>
+#include <linux/mmzone.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/hub.h>
+
+
+static int force_fire_and_forget = 1;
+
+/**
+ * hub_pio_map  -  establish a HUB PIO mapping
+ *
+ * @hub:	hub to perform PIO mapping on
+ * @widget:	widget ID to perform PIO mapping for
+ * @xtalk_addr:	xtalk_address that needs to be mapped
+ * @size:	size of the PIO mapping
+ *
+ **/
+unsigned long hub_pio_map(cnodeid_t cnode, xwidgetnum_t widget,
+			  unsigned long xtalk_addr, size_t size)
+{
+	nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
+	volatile hubreg_t junk;
+	unsigned i;
+
+	/* use small-window mapping if possible */
+	if ((xtalk_addr % SWIN_SIZE) + size <= SWIN_SIZE)
+		return NODE_SWIN_BASE(nasid, widget) + (xtalk_addr % SWIN_SIZE);
+
+	if ((xtalk_addr % BWIN_SIZE) + size > BWIN_SIZE) {
+		printk(KERN_WARNING "PIO mapping at hub %d widget %d addr 0x%lx"
+				" too big (%ld)\n",
+				nasid, widget, xtalk_addr, size);
+		return 0;
+	}
+
+	xtalk_addr &= ~(BWIN_SIZE-1);
+	for (i = 0; i < HUB_NUM_BIG_WINDOW; i++) {
+		if (test_and_set_bit(i, hub_data(cnode)->h_bigwin_used))
+			continue;
+
+		/*
+		 * The code below does a PIO write to setup an ITTE entry.
+		 *
+		 * We need to prevent other CPUs from seeing our updated
+		 * memory shadow of the ITTE (in the piomap) until the ITTE
+		 * entry is actually set up; otherwise, another CPU might
+		 * attempt a PIO prematurely.
+		 *
+		 * Also, the only way we can know that an entry has been
+		 * received  by the hub and can be used by future PIO reads/
+		 * writes is by reading back the ITTE entry after writing it.
+		 *
+		 * For these two reasons, we PIO read back the ITTE entry
+		 * after we write it.
+		 */
+		IIO_ITTE_PUT(nasid, i, HUB_PIO_MAP_TO_MEM, widget, xtalk_addr);
+		junk = HUB_L(IIO_ITTE_GET(nasid, i));
+
+		return NODE_BWIN_BASE(nasid, widget) + (xtalk_addr % BWIN_SIZE);
+	}
+
+	printk(KERN_WARNING "unable to establish PIO mapping for at"
+			" hub %d widget %d addr 0x%lx\n",
+			nasid, widget, xtalk_addr);
+	return 0;
+}
+
+
+/*
+ * hub_setup_prb(nasid, prbnum, credits, conveyor)
+ *
+ * 	Put a PRB into fire-and-forget mode if conveyor isn't set.  Otherwise,
+ * 	put it into conveyor belt mode with the specified number of credits.
+ */
+static void hub_setup_prb(nasid_t nasid, int prbnum, int credits)
+{
+	iprb_t prb;
+	int prb_offset;
+
+	/*
+	 * Get the current register value.
+	 */
+	prb_offset = IIO_IOPRB(prbnum);
+	prb.iprb_regval = REMOTE_HUB_L(nasid, prb_offset);
+
+	/*
+	 * Clear out some fields.
+	 */
+	prb.iprb_ovflow = 1;
+	prb.iprb_bnakctr = 0;
+	prb.iprb_anakctr = 0;
+
+	/*
+	 * Enable or disable fire-and-forget mode.
+	 */
+	prb.iprb_ff = force_fire_and_forget ? 1 : 0;
+
+	/*
+	 * Set the appropriate number of PIO cresits for the widget.
+	 */
+	prb.iprb_xtalkctr = credits;
+
+	/*
+	 * Store the new value to the register.
+	 */
+	REMOTE_HUB_S(nasid, prb_offset, prb.iprb_regval);
+}
+
+/**
+ * hub_set_piomode  -  set pio mode for a given hub
+ *
+ * @nasid:	physical node ID for the hub in question
+ *
+ * Put the hub into either "PIO conveyor belt" mode or "fire-and-forget" mode.
+ * To do this, we have to make absolutely sure that no PIOs are in progress
+ * so we turn off access to all widgets for the duration of the function.
+ *
+ * XXX - This code should really check what kind of widget we're talking
+ * to.  Bridges can only handle three requests, but XG will do more.
+ * How many can crossbow handle to widget 0?  We're assuming 1.
+ *
+ * XXX - There is a bug in the crossbow that link reset PIOs do not
+ * return write responses.  The easiest solution to this problem is to
+ * leave widget 0 (xbow) in fire-and-forget mode at all times.  This
+ * only affects pio's to xbow registers, which should be rare.
+ **/
+static void hub_set_piomode(nasid_t nasid)
+{
+	hubreg_t ii_iowa;
+	hubii_wcr_t ii_wcr;
+	unsigned i;
+
+	ii_iowa = REMOTE_HUB_L(nasid, IIO_OUTWIDGET_ACCESS);
+	REMOTE_HUB_S(nasid, IIO_OUTWIDGET_ACCESS, 0);
+
+	ii_wcr.wcr_reg_value = REMOTE_HUB_L(nasid, IIO_WCR);
+
+	if (ii_wcr.iwcr_dir_con) {
+		/*
+		 * Assume a bridge here.
+		 */
+		hub_setup_prb(nasid, 0, 3);
+	} else {
+		/*
+		 * Assume a crossbow here.
+		 */
+		hub_setup_prb(nasid, 0, 1);
+	}
+
+	/*
+	 * XXX - Here's where we should take the widget type into
+	 * when account assigning credits.
+	 */
+	for (i = HUB_WIDGET_ID_MIN; i <= HUB_WIDGET_ID_MAX; i++)
+		hub_setup_prb(nasid, i, 3);
+
+	REMOTE_HUB_S(nasid, IIO_OUTWIDGET_ACCESS, ii_iowa);
+}
+
+/*
+ * hub_pio_init  -  PIO-related hub initalization
+ *
+ * @hub:	hubinfo structure for our hub
+ */
+void hub_pio_init(cnodeid_t cnode)
+{
+	nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
+	unsigned i;
+
+	/* initialize big window piomaps for this hub */
+	bitmap_zero(hub_data(cnode)->h_bigwin_used, HUB_NUM_BIG_WINDOW);
+	for (i = 0; i < HUB_NUM_BIG_WINDOW; i++)
+		IIO_ITTE_DISABLE(nasid, i);
+
+	hub_set_piomode(nasid);
+}
diff --git a/arch/mips/sgi-ip27/ip27-init.c b/arch/mips/sgi-ip27/ip27-init.c
new file mode 100644
index 0000000..6dcee5c
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-init.c
@@ -0,0 +1,252 @@
+/*
+ * 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) 2000 - 2001 by Kanoj Sarcar (kanoj@sgi.com)
+ * Copyright (C) 2000 - 2001 by Silicon Graphics, Inc.
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/cpumask.h>
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/time.h>
+#include <asm/sn/types.h>
+#include <asm/sn/sn0/addrs.h>
+#include <asm/sn/sn0/hubni.h>
+#include <asm/sn/sn0/hubio.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/ioc3.h>
+#include <asm/mipsregs.h>
+#include <asm/sn/gda.h>
+#include <asm/sn/hub.h>
+#include <asm/sn/intr.h>
+#include <asm/current.h>
+#include <asm/smp.h>
+#include <asm/processor.h>
+#include <asm/mmu_context.h>
+#include <asm/thread_info.h>
+#include <asm/sn/launch.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/sn0/ip27.h>
+#include <asm/sn/mapped_kernel.h>
+
+#define CPU_NONE		(cpuid_t)-1
+
+static DECLARE_BITMAP(hub_init_mask, MAX_COMPACT_NODES);
+nasid_t master_nasid = INVALID_NASID;
+
+cnodeid_t	nasid_to_compact_node[MAX_NASIDS];
+nasid_t		compact_to_nasid_node[MAX_COMPACT_NODES];
+cnodeid_t	cpuid_to_compact_node[MAXCPUS];
+
+EXPORT_SYMBOL(nasid_to_compact_node);
+
+extern void pcibr_setup(cnodeid_t);
+
+extern void xtalk_probe_node(cnodeid_t nid);
+
+static void __init per_hub_init(cnodeid_t cnode)
+{
+	struct hub_data *hub = hub_data(cnode);
+	nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
+
+	cpu_set(smp_processor_id(), hub->h_cpus);
+
+	if (test_and_set_bit(cnode, hub_init_mask))
+		return;
+
+	/*
+	 * Set CRB timeout at 5ms, (< PI timeout of 10ms)
+	 */
+	REMOTE_HUB_S(nasid, IIO_ICTP, 0x800);
+	REMOTE_HUB_S(nasid, IIO_ICTO, 0xff);
+
+	hub_rtc_init(cnode);
+	xtalk_probe_node(cnode);
+
+#ifdef CONFIG_REPLICATE_EXHANDLERS
+	/*
+	 * If this is not a headless node initialization,
+	 * copy over the caliased exception handlers.
+	 */
+	if (get_compact_nodeid() == cnode) {
+		extern char except_vec2_generic, except_vec3_generic;
+		extern void build_tlb_refill_handler(void);
+
+		memcpy((void *)(CKSEG0 + 0x100), &except_vec2_generic, 0x80);
+		memcpy((void *)(CKSEG0 + 0x180), &except_vec3_generic, 0x80);
+		build_tlb_refill_handler();
+		memcpy((void *)(CKSEG0 + 0x100), (void *) CKSEG0, 0x80);
+		memcpy((void *)(CKSEG0 + 0x180), &except_vec3_generic, 0x100);
+		__flush_cache_all();
+	}
+#endif
+}
+
+void __init per_cpu_init(void)
+{
+	int cpu = smp_processor_id();
+	int slice = LOCAL_HUB_L(PI_CPU_NUM);
+	cnodeid_t cnode = get_compact_nodeid();
+	struct hub_data *hub = hub_data(cnode);
+	struct slice_data *si = hub->slice + slice;
+	int i;
+
+	if (test_and_set_bit(slice, &hub->slice_map))
+		return;
+
+	clear_c0_status(ST0_IM);
+
+	for (i = 0; i < LEVELS_PER_SLICE; i++)
+		si->level_to_irq[i] = -1;
+
+	/*
+	 * Some interrupts are reserved by hardware or by software convention.
+	 * Mark these as reserved right away so they won't be used accidently
+	 * later.
+	 */
+	for (i = 0; i <= BASE_PCI_IRQ; i++) {
+		__set_bit(i, si->irq_alloc_mask);
+		LOCAL_HUB_S(PI_INT_PEND_MOD, i);
+	}
+
+	__set_bit(IP_PEND0_6_63, si->irq_alloc_mask);
+	LOCAL_HUB_S(PI_INT_PEND_MOD, IP_PEND0_6_63);
+
+	for (i = NI_BRDCAST_ERR_A; i <= MSC_PANIC_INTR; i++) {
+		__set_bit(i, si->irq_alloc_mask + 1);
+		LOCAL_HUB_S(PI_INT_PEND_MOD, i);
+	}
+
+	LOCAL_HUB_L(PI_INT_PEND0);
+
+	/*
+	 * We use this so we can find the local hub's data as fast as only
+	 * possible.
+	 */
+	cpu_data[cpu].data = si;
+
+	cpu_time_init();
+	install_ipi();
+
+	/* Install our NMI handler if symmon hasn't installed one. */
+	install_cpu_nmi_handler(cputoslice(cpu));
+
+	set_c0_status(SRB_DEV0 | SRB_DEV1);
+
+	per_hub_init(cnode);
+}
+
+/*
+ * get_nasid() returns the physical node id number of the caller.
+ */
+nasid_t
+get_nasid(void)
+{
+	return (nasid_t)((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_NODEID_MASK)
+	                 >> NSRI_NODEID_SHFT);
+}
+
+/*
+ * Map the physical node id to a virtual node id (virtual node ids are contiguous).
+ */
+cnodeid_t get_compact_nodeid(void)
+{
+	return NASID_TO_COMPACT_NODEID(get_nasid());
+}
+
+/* Extracted from the IOC3 meta driver.  FIXME.  */
+static inline void ioc3_sio_init(void)
+{
+	struct ioc3 *ioc3;
+	nasid_t nid;
+	long loops;
+
+	nid = get_nasid();
+	ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base;
+
+	ioc3->sscr_a = 0;			/* PIO mode for uarta.  */
+	ioc3->sscr_b = 0;			/* PIO mode for uartb.  */
+	ioc3->sio_iec = ~0;
+	ioc3->sio_ies = (SIO_IR_SA_INT | SIO_IR_SB_INT);
+
+	loops=1000000; while(loops--);
+	ioc3->sregs.uarta.iu_fcr = 0;
+	ioc3->sregs.uartb.iu_fcr = 0;
+	loops=1000000; while(loops--);
+}
+
+static inline void ioc3_eth_init(void)
+{
+	struct ioc3 *ioc3;
+	nasid_t nid;
+
+	nid = get_nasid();
+	ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base;
+
+	ioc3->eier = 0;
+}
+
+extern void ip27_setup_console(void);
+extern void ip27_time_init(void);
+extern void ip27_reboot_setup(void);
+
+static int __init ip27_setup(void)
+{
+	hubreg_t p, e, n_mode;
+	nasid_t nid;
+
+	ip27_setup_console();
+	ip27_reboot_setup();
+
+	/*
+	 * hub_rtc init and cpu clock intr enabled for later calibrate_delay.
+	 */
+	nid = get_nasid();
+	printk("IP27: Running on node %d.\n", nid);
+
+	p = LOCAL_HUB_L(PI_CPU_PRESENT_A) & 1;
+	e = LOCAL_HUB_L(PI_CPU_ENABLE_A) & 1;
+	printk("Node %d has %s primary CPU%s.\n", nid,
+	       p ? "a" : "no",
+	       e ? ", CPU is running" : "");
+
+	p = LOCAL_HUB_L(PI_CPU_PRESENT_B) & 1;
+	e = LOCAL_HUB_L(PI_CPU_ENABLE_B) & 1;
+	printk("Node %d has %s secondary CPU%s.\n", nid,
+	       p ? "a" : "no",
+	       e ? ", CPU is running" : "");
+
+	/*
+	 * Try to catch kernel missconfigurations and give user an
+	 * indication what option to select.
+	 */
+	n_mode = LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_MORENODES_MASK;
+	printk("Machine is in %c mode.\n", n_mode ? 'N' : 'M');
+#ifdef CONFIG_SGI_SN0_N_MODE
+	if (!n_mode)
+		panic("Kernel compiled for M mode.");
+#else
+	if (n_mode)
+		panic("Kernel compiled for N mode.");
+#endif
+
+	ioc3_sio_init();
+	ioc3_eth_init();
+	per_cpu_init();
+
+	set_io_port_base(IO_BASE);
+
+	board_time_init = ip27_time_init;
+
+	return 0;
+}
+
+early_initcall(ip27_setup);
diff --git a/arch/mips/sgi-ip27/ip27-irq-glue.S b/arch/mips/sgi-ip27/ip27-irq-glue.S
new file mode 100644
index 0000000..c304df7
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-irq-glue.S
@@ -0,0 +1,45 @@
+/*
+ * 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) 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+	.text
+	.align	5
+NESTED(ip27_irq, PT_SIZE, sp)
+	SAVE_ALL
+	CLI
+
+	mfc0	s0, CP0_CAUSE
+	mfc0	t0, CP0_STATUS
+	and	s0, t0
+	move	a0, sp
+	PTR_LA	ra, ret_from_irq
+
+	/* First check for RT interrupt.  */
+	andi	t0, s0, CAUSEF_IP4
+	bnez	t0, ip4
+	andi	t0, s0, CAUSEF_IP2
+	bnez	t0, ip2
+	andi	t0, s0, CAUSEF_IP3
+	bnez	t0, ip3
+	andi	t0, s0, CAUSEF_IP5
+	bnez	t0, ip5
+	andi	t0, s0, CAUSEF_IP6
+	bnez	t0, ip6
+	j	ra
+
+ip2:	j	ip27_do_irq_mask0	# PI_INT_PEND_0 or CC_PEND_{A|B}
+ip3:	j	ip27_do_irq_mask1	# PI_INT_PEND_1
+ip4:	j	ip27_rt_timer_interrupt
+ip5:	j	ip27_prof_timer
+ip6:	j	ip27_hub_error
+
+	END(ip27_irq)
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c
new file mode 100644
index 0000000..61817a1
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-irq.c
@@ -0,0 +1,457 @@
+/*
+ * ip27-irq.c: Highlevel interrupt handling for IP27 architecture.
+ *
+ * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 1999 - 2001 Kanoj Sarcar
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/smp_lock.h>
+#include <linux/kernel_stat.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+#include <asm/ptrace.h>
+#include <asm/processor.h>
+#include <asm/pci/bridge.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/agent.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/hub.h>
+#include <asm/sn/intr.h>
+
+#undef DEBUG_IRQ
+#ifdef DEBUG_IRQ
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+/*
+ * Linux has a controller-independent x86 interrupt architecture.
+ * every controller has a 'controller-template', that is used
+ * by the main code to do the right thing. Each driver-visible
+ * interrupt source is transparently wired to the apropriate
+ * controller. Thus drivers need not be aware of the
+ * interrupt-controller.
+ *
+ * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC,
+ * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC.
+ * (IO-APICs assumed to be messaging to Pentium local-APICs)
+ *
+ * the code is designed to be easily extended with new/different
+ * interrupt controllers, without having to do assembly magic.
+ */
+
+extern asmlinkage void ip27_irq(void);
+
+extern struct bridge_controller *irq_to_bridge[];
+extern int irq_to_slot[];
+
+/*
+ * use these macros to get the encoded nasid and widget id
+ * from the irq value
+ */
+#define IRQ_TO_BRIDGE(i)		irq_to_bridge[(i)]
+#define	SLOT_FROM_PCI_IRQ(i)		irq_to_slot[i]
+
+static inline int alloc_level(int cpu, int irq)
+{
+	struct slice_data *si = cpu_data[cpu].data;
+	int level;				/* pre-allocated entries */
+
+	level = find_first_zero_bit(si->irq_alloc_mask, LEVELS_PER_SLICE);
+	if (level >= LEVELS_PER_SLICE)
+		panic("Cpu %d flooded with devices\n", cpu);
+
+	__set_bit(level, si->irq_alloc_mask);
+	si->level_to_irq[level] = irq;
+
+	return level;
+}
+
+static inline int find_level(cpuid_t *cpunum, int irq)
+{
+	int cpu, i;
+
+	for (cpu = 0; cpu <= NR_CPUS; cpu++) {
+		struct slice_data *si = cpu_data[cpu].data;
+
+		if (!cpu_online(cpu))
+			continue;
+
+		for (i = BASE_PCI_IRQ; i < LEVELS_PER_SLICE; i++)
+			if (si->level_to_irq[i] == irq) {
+				*cpunum = cpu;
+
+				return i;
+			}
+	}
+
+	panic("Could not identify cpu/level for irq %d\n", irq);
+}
+
+/*
+ * Find first bit set
+ */
+static int ms1bit(unsigned long x)
+{
+	int b = 0, s;
+
+	s = 16; if (x >> 16 == 0) s = 0; b += s; x >>= s;
+	s =  8; if (x >>  8 == 0) s = 0; b += s; x >>= s;
+	s =  4; if (x >>  4 == 0) s = 0; b += s; x >>= s;
+	s =  2; if (x >>  2 == 0) s = 0; b += s; x >>= s;
+	s =  1; if (x >>  1 == 0) s = 0; b += s;
+
+	return b;
+}
+
+/*
+ * This code is unnecessarily complex, because we do SA_INTERRUPT
+ * intr enabling. Basically, once we grab the set of intrs we need
+ * to service, we must mask _all_ these interrupts; firstly, to make
+ * sure the same intr does not intr again, causing recursion that
+ * can lead to stack overflow. Secondly, we can not just mask the
+ * one intr we are do_IRQing, because the non-masked intrs in the
+ * first set might intr again, causing multiple servicings of the
+ * same intr. This effect is mostly seen for intercpu intrs.
+ * Kanoj 05.13.00
+ */
+
+void ip27_do_irq_mask0(struct pt_regs *regs)
+{
+	int irq, swlevel;
+	hubreg_t pend0, mask0;
+	cpuid_t cpu = smp_processor_id();
+	int pi_int_mask0 =
+		(cputoslice(cpu) == 0) ?  PI_INT_MASK0_A : PI_INT_MASK0_B;
+
+	/* copied from Irix intpend0() */
+	pend0 = LOCAL_HUB_L(PI_INT_PEND0);
+	mask0 = LOCAL_HUB_L(pi_int_mask0);
+
+	pend0 &= mask0;		/* Pick intrs we should look at */
+	if (!pend0)
+		return;
+
+	swlevel = ms1bit(pend0);
+#ifdef CONFIG_SMP
+	if (pend0 & (1UL << CPU_RESCHED_A_IRQ)) {
+		LOCAL_HUB_CLR_INTR(CPU_RESCHED_A_IRQ);
+	} else if (pend0 & (1UL << CPU_RESCHED_B_IRQ)) {
+		LOCAL_HUB_CLR_INTR(CPU_RESCHED_B_IRQ);
+	} else if (pend0 & (1UL << CPU_CALL_A_IRQ)) {
+		LOCAL_HUB_CLR_INTR(CPU_CALL_A_IRQ);
+		smp_call_function_interrupt();
+	} else if (pend0 & (1UL << CPU_CALL_B_IRQ)) {
+		LOCAL_HUB_CLR_INTR(CPU_CALL_B_IRQ);
+		smp_call_function_interrupt();
+	} else
+#endif
+	{
+		/* "map" swlevel to irq */
+		struct slice_data *si = cpu_data[cpu].data;
+
+		irq = si->level_to_irq[swlevel];
+		do_IRQ(irq, regs);
+	}
+
+	LOCAL_HUB_L(PI_INT_PEND0);
+}
+
+void ip27_do_irq_mask1(struct pt_regs *regs)
+{
+	int irq, swlevel;
+	hubreg_t pend1, mask1;
+	cpuid_t cpu = smp_processor_id();
+	int pi_int_mask1 = (cputoslice(cpu) == 0) ?  PI_INT_MASK1_A : PI_INT_MASK1_B;
+	struct slice_data *si = cpu_data[cpu].data;
+
+	/* copied from Irix intpend0() */
+	pend1 = LOCAL_HUB_L(PI_INT_PEND1);
+	mask1 = LOCAL_HUB_L(pi_int_mask1);
+
+	pend1 &= mask1;		/* Pick intrs we should look at */
+	if (!pend1)
+		return;
+
+	swlevel = ms1bit(pend1);
+	/* "map" swlevel to irq */
+	irq = si->level_to_irq[swlevel];
+	LOCAL_HUB_CLR_INTR(swlevel);
+	do_IRQ(irq, regs);
+
+	LOCAL_HUB_L(PI_INT_PEND1);
+}
+
+void ip27_prof_timer(struct pt_regs *regs)
+{
+	panic("CPU %d got a profiling interrupt", smp_processor_id());
+}
+
+void ip27_hub_error(struct pt_regs *regs)
+{
+	panic("CPU %d got a hub error interrupt", smp_processor_id());
+}
+
+static int intr_connect_level(int cpu, int bit)
+{
+	nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
+	struct slice_data *si = cpu_data[cpu].data;
+
+	__set_bit(bit, si->irq_enable_mask);
+
+	if (!cputoslice(cpu)) {
+		REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]);
+		REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]);
+	} else {
+		REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]);
+		REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]);
+	}
+
+	return 0;
+}
+
+static int intr_disconnect_level(int cpu, int bit)
+{
+	nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
+	struct slice_data *si = cpu_data[cpu].data;
+
+	__clear_bit(bit, si->irq_enable_mask);
+
+	if (!cputoslice(cpu)) {
+		REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]);
+		REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]);
+	} else {
+		REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]);
+		REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]);
+	}
+
+	return 0;
+}
+
+/* Startup one of the (PCI ...) IRQs routes over a bridge.  */
+static unsigned int startup_bridge_irq(unsigned int irq)
+{
+	struct bridge_controller *bc;
+	bridgereg_t device;
+	bridge_t *bridge;
+	int pin, swlevel;
+	cpuid_t cpu;
+
+	pin = SLOT_FROM_PCI_IRQ(irq);
+	bc = IRQ_TO_BRIDGE(irq);
+	bridge = bc->base;
+
+	DBG("bridge_startup(): irq= 0x%x  pin=%d\n", irq, pin);
+	/*
+	 * "map" irq to a swlevel greater than 6 since the first 6 bits
+	 * of INT_PEND0 are taken
+	 */
+	swlevel = find_level(&cpu, irq);
+	bridge->b_int_addr[pin].addr = (0x20000 | swlevel | (bc->nasid << 8));
+	bridge->b_int_enable |= (1 << pin);
+	bridge->b_int_enable |= 0x7ffffe00;	/* more stuff in int_enable */
+
+	/*
+	 * Enable sending of an interrupt clear packt to the hub on a high to
+	 * low transition of the interrupt pin.
+	 *
+	 * IRIX sets additional bits in the address which are documented as
+	 * reserved in the bridge docs.
+	 */
+	bridge->b_int_mode |= (1UL << pin);
+
+	/*
+	 * We assume the bridge to have a 1:1 mapping between devices
+	 * (slots) and intr pins.
+	 */
+	device = bridge->b_int_device;
+	device &= ~(7 << (pin*3));
+	device |= (pin << (pin*3));
+	bridge->b_int_device = device;
+
+        bridge->b_wid_tflush;
+
+        return 0;       /* Never anything pending.  */
+}
+
+/* Shutdown one of the (PCI ...) IRQs routes over a bridge.  */
+static void shutdown_bridge_irq(unsigned int irq)
+{
+	struct bridge_controller *bc = IRQ_TO_BRIDGE(irq);
+	bridge_t *bridge = bc->base;
+	struct slice_data *si = cpu_data[bc->irq_cpu].data;
+	int pin, swlevel;
+	cpuid_t cpu;
+
+	DBG("bridge_shutdown: irq 0x%x\n", irq);
+	pin = SLOT_FROM_PCI_IRQ(irq);
+
+	/*
+	 * map irq to a swlevel greater than 6 since the first 6 bits
+	 * of INT_PEND0 are taken
+	 */
+	swlevel = find_level(&cpu, irq);
+	intr_disconnect_level(cpu, swlevel);
+
+	__clear_bit(swlevel, si->irq_alloc_mask);
+	si->level_to_irq[swlevel] = -1;
+
+	bridge->b_int_enable &= ~(1 << pin);
+	bridge->b_wid_tflush;
+}
+
+static inline void enable_bridge_irq(unsigned int irq)
+{
+	cpuid_t cpu;
+	int swlevel;
+
+	swlevel = find_level(&cpu, irq);	/* Criminal offence */
+	intr_connect_level(cpu, swlevel);
+}
+
+static inline void disable_bridge_irq(unsigned int irq)
+{
+	cpuid_t cpu;
+	int swlevel;
+
+	swlevel = find_level(&cpu, irq);	/* Criminal offence */
+	intr_disconnect_level(cpu, swlevel);
+}
+
+static void mask_and_ack_bridge_irq(unsigned int irq)
+{
+	disable_bridge_irq(irq);
+}
+
+static void end_bridge_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)) &&
+	    irq_desc[irq].action)
+		enable_bridge_irq(irq);
+}
+
+static struct hw_interrupt_type bridge_irq_type = {
+	.typename	= "bridge",
+	.startup	= startup_bridge_irq,
+	.shutdown	= shutdown_bridge_irq,
+	.enable		= enable_bridge_irq,
+	.disable	= disable_bridge_irq,
+	.ack		= mask_and_ack_bridge_irq,
+	.end		= end_bridge_irq,
+};
+
+static unsigned long irq_map[NR_IRQS / BITS_PER_LONG];
+
+static int allocate_irqno(void)
+{
+	int irq;
+
+again:
+	irq = find_first_zero_bit(irq_map, NR_IRQS);
+
+	if (irq >= NR_IRQS)
+		return -ENOSPC;
+
+	if (test_and_set_bit(irq, irq_map))
+		goto again;
+
+	return irq;
+}
+
+void free_irqno(unsigned int irq)
+{
+	clear_bit(irq, irq_map);
+}
+
+void __devinit register_bridge_irq(unsigned int irq)
+{
+	irq_desc[irq].status	= IRQ_DISABLED;
+	irq_desc[irq].action	= 0;
+	irq_desc[irq].depth	= 1;
+	irq_desc[irq].handler	= &bridge_irq_type;
+}
+
+int __devinit request_bridge_irq(struct bridge_controller *bc)
+{
+	int irq = allocate_irqno();
+	int swlevel, cpu;
+	nasid_t nasid;
+
+	if (irq < 0)
+		return irq;
+
+	/*
+	 * "map" irq to a swlevel greater than 6 since the first 6 bits
+	 * of INT_PEND0 are taken
+	 */
+	cpu = bc->irq_cpu;
+	swlevel = alloc_level(cpu, irq);
+	if (unlikely(swlevel < 0)) {
+		free_irqno(irq);
+
+		return -EAGAIN;
+	}
+
+	/* Make sure it's not already pending when we connect it. */
+	nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
+	REMOTE_HUB_CLR_INTR(nasid, swlevel);
+
+	intr_connect_level(cpu, swlevel);
+
+	register_bridge_irq(irq);
+
+	return irq;
+}
+
+void __init arch_init_irq(void)
+{
+	set_except_vector(0, ip27_irq);
+}
+
+void install_ipi(void)
+{
+	int slice = LOCAL_HUB_L(PI_CPU_NUM);
+	int cpu = smp_processor_id();
+	struct slice_data *si = cpu_data[cpu].data;
+	hubreg_t mask, set;
+
+	if (slice == 0) {
+		LOCAL_HUB_CLR_INTR(CPU_RESCHED_A_IRQ);
+		LOCAL_HUB_CLR_INTR(CPU_CALL_A_IRQ);
+		mask = LOCAL_HUB_L(PI_INT_MASK0_A);	/* Slice A */
+		set = (1UL << CPU_RESCHED_A_IRQ) | (1UL << CPU_CALL_A_IRQ);
+		mask |= set;
+		si->irq_enable_mask[0] |= set;
+		si->irq_alloc_mask[0] |= set;
+		LOCAL_HUB_S(PI_INT_MASK0_A, mask);
+	} else {
+		LOCAL_HUB_CLR_INTR(CPU_RESCHED_B_IRQ);
+		LOCAL_HUB_CLR_INTR(CPU_CALL_B_IRQ);
+		mask = LOCAL_HUB_L(PI_INT_MASK0_B);	/* Slice B */
+		set = (1UL << CPU_RESCHED_B_IRQ) | (1UL << CPU_CALL_B_IRQ);
+		mask |= set;
+		si->irq_enable_mask[1] |= set;
+		si->irq_alloc_mask[1] |= set;
+		LOCAL_HUB_S(PI_INT_MASK0_B, mask);
+	}
+}
diff --git a/arch/mips/sgi-ip27/ip27-klconfig.c b/arch/mips/sgi-ip27/ip27-klconfig.c
new file mode 100644
index 0000000..dd830b3
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-klconfig.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/param.h>
+#include <linux/timex.h>
+#include <linux/mm.h>
+
+#include <asm/sn/klconfig.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/gda.h>
+
+klinfo_t *find_component(lboard_t *brd, klinfo_t *kli, unsigned char struct_type)
+{
+	int index, j;
+
+	if (kli == (klinfo_t *)NULL) {
+		index = 0;
+	} else {
+		for (j = 0; j < KLCF_NUM_COMPS(brd); j++)
+			if (kli == KLCF_COMP(brd, j))
+				break;
+		index = j;
+		if (index == KLCF_NUM_COMPS(brd)) {
+			printk("find_component: Bad pointer: 0x%p\n", kli);
+			return (klinfo_t *)NULL;
+		}
+		index++;		/* next component */
+	}
+
+	for (; index < KLCF_NUM_COMPS(brd); index++) {
+		kli = KLCF_COMP(brd, index);
+		if (KLCF_COMP_TYPE(kli) == struct_type)
+			return kli;
+	}
+
+	/* Didn't find it. */
+	return (klinfo_t *)NULL;
+}
+
+klinfo_t *find_first_component(lboard_t *brd, unsigned char struct_type)
+{
+	return find_component(brd, (klinfo_t *)NULL, struct_type);
+}
+
+lboard_t * find_lboard(lboard_t *start, unsigned char brd_type)
+{
+	/* Search all boards stored on this node. */
+	while (start) {
+		if (start->brd_type == brd_type)
+			return start;
+		start = KLCF_NEXT(start);
+	}
+	/* Didn't find it. */
+	return (lboard_t *)NULL;
+}
+
+lboard_t * find_lboard_class(lboard_t *start, unsigned char brd_type)
+{
+	/* Search all boards stored on this node. */
+	while (start) {
+		if (KLCLASS(start->brd_type) == KLCLASS(brd_type))
+			return start;
+		start = KLCF_NEXT(start);
+	}
+
+	/* Didn't find it. */
+	return (lboard_t *)NULL;
+}
+
+cnodeid_t get_cpu_cnode(cpuid_t cpu)
+{
+	return CPUID_TO_COMPACT_NODEID(cpu);
+}
+
+klcpu_t * nasid_slice_to_cpuinfo(nasid_t nasid, int slice)
+{
+	lboard_t *brd;
+	klcpu_t *acpu;
+
+	if (!(brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27)))
+		return (klcpu_t *)NULL;
+
+	if (!(acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU)))
+		return (klcpu_t *)NULL;
+
+	do {
+		if ((acpu->cpu_info.physid) == slice)
+			return acpu;
+	} while ((acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu,
+								KLSTRUCT_CPU)));
+	return (klcpu_t *)NULL;
+}
+
+klcpu_t * sn_get_cpuinfo(cpuid_t cpu)
+{
+	nasid_t nasid;
+	int slice;
+	klcpu_t *acpu;
+	gda_t *gdap = GDA;
+	cnodeid_t cnode;
+
+	if (!(cpu < MAXCPUS)) {
+		printk("sn_get_cpuinfo: illegal cpuid 0x%lx\n", cpu);
+		return NULL;
+	}
+
+	cnode = get_cpu_cnode(cpu);
+	if (cnode == INVALID_CNODEID)
+		return NULL;
+
+	if ((nasid = gdap->g_nasidtable[cnode]) == INVALID_NASID)
+		return NULL;
+
+	for (slice = 0; slice < CPUS_PER_NODE; slice++) {
+		acpu = nasid_slice_to_cpuinfo(nasid, slice);
+		if (acpu && acpu->cpu_info.virtid == cpu)
+			return acpu;
+	}
+	return NULL;
+}
+
+int get_cpu_slice(cpuid_t cpu)
+{
+	klcpu_t *acpu;
+
+	if ((acpu = sn_get_cpuinfo(cpu)) == NULL)
+		return -1;
+	return acpu->cpu_info.physid;
+}
diff --git a/arch/mips/sgi-ip27/ip27-klnuma.c b/arch/mips/sgi-ip27/ip27-klnuma.c
new file mode 100644
index 0000000..41c3f40
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-klnuma.c
@@ -0,0 +1,135 @@
+/*
+ * Ported from IRIX to Linux by Kanoj Sarcar, 06/08/00.
+ * Copyright 2000 - 2001 Silicon Graphics, Inc.
+ * Copyright 2000 - 2001 Kanoj Sarcar (kanoj@sgi.com)
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/mmzone.h>
+#include <linux/kernel.h>
+#include <linux/nodemask.h>
+#include <linux/string.h>
+
+#include <asm/page.h>
+#include <asm/sections.h>
+#include <asm/smp.h>
+#include <asm/sn/types.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/gda.h>
+#include <asm/sn/hub.h>
+#include <asm/sn/mapped_kernel.h>
+#include <asm/sn/sn_private.h>
+
+static cpumask_t ktext_repmask;
+
+/*
+ * XXX - This needs to be much smarter about where it puts copies of the
+ * kernel.  For example, we should never put a copy on a headless node,
+ * and we should respect the topology of the machine.
+ */
+void __init setup_replication_mask()
+{
+	cnodeid_t	cnode;
+
+	/* Set only the master cnode's bit.  The master cnode is always 0. */
+	cpus_clear(ktext_repmask);
+	cpu_set(0, ktext_repmask);
+
+#ifdef CONFIG_REPLICATE_KTEXT
+#ifndef CONFIG_MAPPED_KERNEL
+#error Kernel replication works with mapped kernel support. No calias support.
+#endif
+	for_each_online_node(cnode) {
+		if (cnode == 0)
+			continue;
+		/* Advertise that we have a copy of the kernel */
+		cpu_set(cnode, ktext_repmask);
+	}
+#endif
+	/* Set up a GDA pointer to the replication mask. */
+	GDA->g_ktext_repmask = &ktext_repmask;
+}
+
+
+static __init void set_ktext_source(nasid_t client_nasid, nasid_t server_nasid)
+{
+	cnodeid_t client_cnode;
+	kern_vars_t *kvp;
+
+	client_cnode = NASID_TO_COMPACT_NODEID(client_nasid);
+
+	kvp = &hub_data(client_nasid)->kern_vars;
+
+	KERN_VARS_ADDR(client_nasid) = (unsigned long)kvp;
+
+	kvp->kv_magic = KV_MAGIC;
+	kvp->kv_ro_nasid = server_nasid;
+	kvp->kv_rw_nasid = master_nasid;
+	kvp->kv_ro_baseaddr = NODE_CAC_BASE(server_nasid);
+	kvp->kv_rw_baseaddr = NODE_CAC_BASE(master_nasid);
+	printk("REPLICATION: ON nasid %d, ktext from nasid %d, kdata from nasid %d\n", client_nasid, server_nasid, master_nasid);
+}
+
+/* XXX - When the BTE works, we should use it instead of this. */
+static __init void copy_kernel(nasid_t dest_nasid)
+{
+	unsigned long dest_kern_start, source_start, source_end, kern_size;
+
+	source_start = (unsigned long) _stext;
+	source_end = (unsigned long) _etext;
+	kern_size = source_end - source_start;
+
+	dest_kern_start = CHANGE_ADDR_NASID(MAPPED_KERN_RO_TO_K0(source_start),
+					    dest_nasid);
+	memcpy((void *)dest_kern_start, (void *)source_start, kern_size);
+}
+
+void __init replicate_kernel_text()
+{
+	cnodeid_t cnode;
+	nasid_t client_nasid;
+	nasid_t server_nasid;
+
+	server_nasid = master_nasid;
+
+	/* Record where the master node should get its kernel text */
+	set_ktext_source(master_nasid, master_nasid);
+
+	for_each_online_node(cnode) {
+		if (cnode == 0)
+			continue;
+		client_nasid = COMPACT_TO_NASID_NODEID(cnode);
+
+		/* Check if this node should get a copy of the kernel */
+		if (cpu_isset(cnode, ktext_repmask)) {
+			server_nasid = client_nasid;
+			copy_kernel(server_nasid);
+		}
+
+		/* Record where this node should get its kernel text */
+		set_ktext_source(client_nasid, server_nasid);
+	}
+}
+
+/*
+ * Return pfn of first free page of memory on a node. PROM may allocate
+ * data structures on the first couple of pages of the first slot of each
+ * node. If this is the case, getfirstfree(node) > getslotstart(node, 0).
+ */
+pfn_t node_getfirstfree(cnodeid_t cnode)
+{
+	unsigned long loadbase = REP_BASE;
+	nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
+	unsigned long offset;
+
+#ifdef CONFIG_MAPPED_KERNEL
+	loadbase += 16777216;
+#endif
+	offset = PAGE_ALIGN((unsigned long)(&_end)) - loadbase;
+	if ((cnode == 0) || (cpu_isset(cnode, ktext_repmask)))
+		return (TO_NODE(nasid, offset) >> PAGE_SHIFT);
+	else
+		return (KDM_TO_PHYS(PAGE_ALIGN(SYMMON_STK_ADDR(nasid, 0))) >>
+								PAGE_SHIFT);
+}
+
diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c
new file mode 100644
index 0000000..0a44a98
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-memory.c
@@ -0,0 +1,586 @@
+/*
+ * 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) 2000, 05 by Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2000 by Silicon Graphics, Inc.
+ * Copyright (C) 2004 by Christoph Hellwig
+ *
+ * On SGI IP27 the ARC memory configuration data is completly bogus but
+ * alternate easier to use mechanisms are available.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/mmzone.h>
+#include <linux/module.h>
+#include <linux/nodemask.h>
+#include <linux/swap.h>
+#include <linux/bootmem.h>
+#include <asm/page.h>
+#include <asm/sections.h>
+
+#include <asm/sn/arch.h>
+#include <asm/sn/hub.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/sn_private.h>
+
+
+#define PFN_UP(x)		(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+
+#define SLOT_PFNSHIFT           (SLOT_SHIFT - PAGE_SHIFT)
+#define PFN_NASIDSHFT           (NASID_SHFT - PAGE_SHIFT)
+
+#define SLOT_IGNORED		0xffff
+
+static short __initdata slot_lastfilled_cache[MAX_COMPACT_NODES];
+static unsigned short __initdata slot_psize_cache[MAX_COMPACT_NODES][MAX_MEM_SLOTS];
+static struct bootmem_data __initdata plat_node_bdata[MAX_COMPACT_NODES];
+
+struct node_data *__node_data[MAX_COMPACT_NODES];
+
+EXPORT_SYMBOL(__node_data);
+
+static int fine_mode;
+
+static int is_fine_dirmode(void)
+{
+	return (((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK)
+	        >> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE);
+}
+
+static hubreg_t get_region(cnodeid_t cnode)
+{
+	if (fine_mode)
+		return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_FINEREG_SHFT;
+	else
+		return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_COARSEREG_SHFT;
+}
+
+static hubreg_t region_mask;
+
+static void gen_region_mask(hubreg_t *region_mask)
+{
+	cnodeid_t cnode;
+
+	(*region_mask) = 0;
+	for_each_online_node(cnode) {
+		(*region_mask) |= 1ULL << get_region(cnode);
+	}
+}
+
+#define	rou_rflag	rou_flags
+
+static int router_distance;
+
+static void router_recurse(klrou_t *router_a, klrou_t *router_b, int depth)
+{
+	klrou_t *router;
+	lboard_t *brd;
+	int	port;
+
+	if (router_a->rou_rflag == 1)
+		return;
+
+	if (depth >= router_distance)
+		return;
+
+	router_a->rou_rflag = 1;
+
+	for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
+		if (router_a->rou_port[port].port_nasid == INVALID_NASID)
+			continue;
+
+		brd = (lboard_t *)NODE_OFFSET_TO_K0(
+			router_a->rou_port[port].port_nasid,
+			router_a->rou_port[port].port_offset);
+
+		if (brd->brd_type == KLTYPE_ROUTER) {
+			router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]);
+			if (router == router_b) {
+				if (depth < router_distance)
+					router_distance = depth;
+			}
+			else
+				router_recurse(router, router_b, depth + 1);
+		}
+	}
+
+	router_a->rou_rflag = 0;
+}
+
+unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES];
+
+static int __init compute_node_distance(nasid_t nasid_a, nasid_t nasid_b)
+{
+	klrou_t *router, *router_a = NULL, *router_b = NULL;
+	lboard_t *brd, *dest_brd;
+	cnodeid_t cnode;
+	nasid_t nasid;
+	int port;
+
+	/* Figure out which routers nodes in question are connected to */
+	for_each_online_node(cnode) {
+		nasid = COMPACT_TO_NASID_NODEID(cnode);
+
+		if (nasid == -1) continue;
+
+		brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
+					KLTYPE_ROUTER);
+
+		if (!brd)
+			continue;
+
+		do {
+			if (brd->brd_flags & DUPLICATE_BOARD)
+				continue;
+
+			router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]);
+			router->rou_rflag = 0;
+
+			for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
+				if (router->rou_port[port].port_nasid == INVALID_NASID)
+					continue;
+
+				dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
+					router->rou_port[port].port_nasid,
+					router->rou_port[port].port_offset);
+
+				if (dest_brd->brd_type == KLTYPE_IP27) {
+					if (dest_brd->brd_nasid == nasid_a)
+						router_a = router;
+					if (dest_brd->brd_nasid == nasid_b)
+						router_b = router;
+				}
+			}
+
+		} while ((brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)));
+	}
+
+	if (router_a == NULL) {
+		printk("node_distance: router_a NULL\n");
+		return -1;
+	}
+	if (router_b == NULL) {
+		printk("node_distance: router_b NULL\n");
+		return -1;
+	}
+
+	if (nasid_a == nasid_b)
+		return 0;
+
+	if (router_a == router_b)
+		return 1;
+
+	router_distance = 100;
+	router_recurse(router_a, router_b, 2);
+
+	return router_distance;
+}
+
+static void __init init_topology_matrix(void)
+{
+	nasid_t nasid, nasid2;
+	cnodeid_t row, col;
+
+	for (row = 0; row < MAX_COMPACT_NODES; row++)
+		for (col = 0; col < MAX_COMPACT_NODES; col++)
+			__node_distances[row][col] = -1;
+
+	for_each_online_node(row) {
+		nasid = COMPACT_TO_NASID_NODEID(row);
+		for_each_online_node(col) {
+			nasid2 = COMPACT_TO_NASID_NODEID(col);
+			__node_distances[row][col] =
+				compute_node_distance(nasid, nasid2);
+		}
+	}
+}
+
+static void __init dump_topology(void)
+{
+	nasid_t nasid;
+	cnodeid_t cnode;
+	lboard_t *brd, *dest_brd;
+	int port;
+	int router_num = 0;
+	klrou_t *router;
+	cnodeid_t row, col;
+
+	printk("************** Topology ********************\n");
+
+	printk("    ");
+	for_each_online_node(col)
+		printk("%02d ", col);
+	printk("\n");
+	for_each_online_node(row) {
+		printk("%02d  ", row);
+		for_each_online_node(col)
+			printk("%2d ", node_distance(row, col));
+		printk("\n");
+	}
+
+	for_each_online_node(cnode) {
+		nasid = COMPACT_TO_NASID_NODEID(cnode);
+
+		if (nasid == -1) continue;
+
+		brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
+					KLTYPE_ROUTER);
+
+		if (!brd)
+			continue;
+
+		do {
+			if (brd->brd_flags & DUPLICATE_BOARD)
+				continue;
+			printk("Router %d:", router_num);
+			router_num++;
+
+			router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]);
+
+			for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
+				if (router->rou_port[port].port_nasid == INVALID_NASID)
+					continue;
+
+				dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
+					router->rou_port[port].port_nasid,
+					router->rou_port[port].port_offset);
+
+				if (dest_brd->brd_type == KLTYPE_IP27)
+					printk(" %d", dest_brd->brd_nasid);
+				if (dest_brd->brd_type == KLTYPE_ROUTER)
+					printk(" r");
+			}
+			printk("\n");
+
+		} while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) );
+	}
+}
+
+static pfn_t __init slot_getbasepfn(cnodeid_t cnode, int slot)
+{
+	nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
+
+	return ((pfn_t)nasid << PFN_NASIDSHFT) | (slot << SLOT_PFNSHIFT);
+}
+
+/*
+ * Return the number of pages of memory provided by the given slot
+ * on the specified node.
+ */
+static pfn_t __init slot_getsize(cnodeid_t node, int slot)
+{
+	return (pfn_t) slot_psize_cache[node][slot];
+}
+
+/*
+ * Return highest slot filled
+ */
+static int __init node_getlastslot(cnodeid_t node)
+{
+	return (int) slot_lastfilled_cache[node];
+}
+
+/*
+ * Return the pfn of the last free page of memory on a node.
+ */
+static pfn_t __init node_getmaxclick(cnodeid_t node)
+{
+	pfn_t	slot_psize;
+	int	slot;
+
+	/*
+	 * Start at the top slot. When we find a slot with memory in it,
+	 * that's the winner.
+	 */
+	for (slot = (MAX_MEM_SLOTS - 1); slot >= 0; slot--) {
+		if ((slot_psize = slot_getsize(node, slot))) {
+			if (slot_psize == SLOT_IGNORED)
+				continue;
+			/* Return the basepfn + the slot size, minus 1. */
+			return slot_getbasepfn(node, slot) + slot_psize - 1;
+		}
+	}
+
+	/*
+	 * If there's no memory on the node, return 0. This is likely
+	 * to cause problems.
+	 */
+	return 0;
+}
+
+static pfn_t __init slot_psize_compute(cnodeid_t node, int slot)
+{
+	nasid_t nasid;
+	lboard_t *brd;
+	klmembnk_t *banks;
+	unsigned long size;
+
+	nasid = COMPACT_TO_NASID_NODEID(node);
+	/* Find the node board */
+	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27);
+	if (!brd)
+		return 0;
+
+	/* Get the memory bank structure */
+	banks = (klmembnk_t *) find_first_component(brd, KLSTRUCT_MEMBNK);
+	if (!banks)
+		return 0;
+
+	/* Size in _Megabytes_ */
+	size = (unsigned long)banks->membnk_bnksz[slot/4];
+
+	/* hack for 128 dimm banks */
+	if (size <= 128) {
+		if (slot % 4 == 0) {
+			size <<= 20;		/* size in bytes */
+			return(size >> PAGE_SHIFT);
+		} else
+			return 0;
+	} else {
+		size /= 4;
+		size <<= 20;
+		return size >> PAGE_SHIFT;
+	}
+}
+
+static void __init mlreset(void)
+{
+	int i;
+
+	master_nasid = get_nasid();
+	fine_mode = is_fine_dirmode();
+
+	/*
+	 * Probe for all CPUs - this creates the cpumask and sets up the
+	 * mapping tables.  We need to do this as early as possible.
+	 */
+#ifdef CONFIG_SMP
+	cpu_node_probe();
+#endif
+
+	init_topology_matrix();
+	dump_topology();
+
+	gen_region_mask(&region_mask);
+
+	setup_replication_mask();
+
+	/*
+	 * Set all nodes' calias sizes to 8k
+	 */
+	for_each_online_node(i) {
+		nasid_t nasid;
+
+		nasid = COMPACT_TO_NASID_NODEID(i);
+
+		/*
+		 * Always have node 0 in the region mask, otherwise
+		 * CALIAS accesses get exceptions since the hub
+		 * thinks it is a node 0 address.
+		 */
+		REMOTE_HUB_S(nasid, PI_REGION_PRESENT, (region_mask | 1));
+#ifdef CONFIG_REPLICATE_EXHANDLERS
+		REMOTE_HUB_S(nasid, PI_CALIAS_SIZE, PI_CALIAS_SIZE_8K);
+#else
+		REMOTE_HUB_S(nasid, PI_CALIAS_SIZE, PI_CALIAS_SIZE_0);
+#endif
+
+#ifdef LATER
+		/*
+		 * Set up all hubs to have a big window pointing at
+		 * widget 0. Memory mode, widget 0, offset 0
+		 */
+		REMOTE_HUB_S(nasid, IIO_ITTE(SWIN0_BIGWIN),
+			((HUB_PIO_MAP_TO_MEM << IIO_ITTE_IOSP_SHIFT) |
+			(0 << IIO_ITTE_WIDGET_SHIFT)));
+#endif
+	}
+}
+
+static void __init szmem(void)
+{
+	pfn_t slot_psize, slot0sz = 0, nodebytes;	/* Hack to detect problem configs */
+	int slot, ignore;
+	cnodeid_t node;
+
+	num_physpages = 0;
+
+	for_each_online_node(node) {
+		ignore = nodebytes = 0;
+		for (slot = 0; slot < MAX_MEM_SLOTS; slot++) {
+			slot_psize = slot_psize_compute(node, slot);
+			if (slot == 0)
+				slot0sz = slot_psize;
+			/*
+			 * We need to refine the hack when we have replicated
+			 * kernel text.
+			 */
+			nodebytes += (1LL << SLOT_SHIFT);
+			if ((nodebytes >> PAGE_SHIFT) * (sizeof(struct page)) >
+						(slot0sz << PAGE_SHIFT))
+				ignore = 1;
+			if (ignore && slot_psize) {
+				printk("Ignoring slot %d onwards on node %d\n",
+								slot, node);
+				slot_psize_cache[node][slot] = SLOT_IGNORED;
+				slot = MAX_MEM_SLOTS;
+				continue;
+			}
+			num_physpages += slot_psize;
+			slot_psize_cache[node][slot] =
+					(unsigned short) slot_psize;
+			if (slot_psize)
+				slot_lastfilled_cache[node] = slot;
+		}
+	}
+}
+
+static void __init node_mem_init(cnodeid_t node)
+{
+	pfn_t slot_firstpfn = slot_getbasepfn(node, 0);
+	pfn_t slot_lastpfn = slot_firstpfn + slot_getsize(node, 0);
+	pfn_t slot_freepfn = node_getfirstfree(node);
+	struct pglist_data *pd;
+	unsigned long bootmap_size;
+
+	/*
+	 * Allocate the node data structures on the node first.
+	 */
+	__node_data[node] = __va(slot_freepfn << PAGE_SHIFT);
+
+	pd = NODE_DATA(node);
+	pd->bdata = &plat_node_bdata[node];
+
+	cpus_clear(hub_data(node)->h_cpus);
+
+	slot_freepfn += PFN_UP(sizeof(struct pglist_data) +
+			       sizeof(struct hub_data));
+
+  	bootmap_size = init_bootmem_node(NODE_DATA(node), slot_freepfn,
+					slot_firstpfn, slot_lastpfn);
+	free_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT,
+			(slot_lastpfn - slot_firstpfn) << PAGE_SHIFT);
+	reserve_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT,
+		((slot_freepfn - slot_firstpfn) << PAGE_SHIFT) + bootmap_size);
+}
+
+/*
+ * A node with nothing.  We use it to avoid any special casing in
+ * node_to_cpumask
+ */
+static struct node_data null_node = {
+	.hub = {
+		.h_cpus = CPU_MASK_NONE
+	}
+};
+
+/*
+ * Currently, the intranode memory hole support assumes that each slot
+ * contains at least 32 MBytes of memory. We assume all bootmem data
+ * fits on the first slot.
+ */
+void __init prom_meminit(void)
+{
+	cnodeid_t node;
+
+	mlreset();
+	szmem();
+
+	for (node = 0; node < MAX_COMPACT_NODES; node++) {
+		if (node_online(node)) {
+			node_mem_init(node);
+			continue;
+		}
+		__node_data[node] = &null_node;
+	}
+}
+
+unsigned long __init prom_free_prom_memory(void)
+{
+	/* We got nothing to free here ...  */
+	return 0;
+}
+
+extern void pagetable_init(void);
+extern unsigned long setup_zero_pages(void);
+
+void __init paging_init(void)
+{
+	unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+	unsigned node;
+
+	pagetable_init();
+
+	for_each_online_node(node) {
+		pfn_t start_pfn = slot_getbasepfn(node, 0);
+		pfn_t end_pfn = node_getmaxclick(node) + 1;
+
+		zones_size[ZONE_DMA] = end_pfn - start_pfn;
+		free_area_init_node(node, NODE_DATA(node),
+				zones_size, start_pfn, NULL);
+
+		if (end_pfn > max_low_pfn)
+			max_low_pfn = end_pfn;
+	}
+}
+
+void __init mem_init(void)
+{
+	unsigned long codesize, datasize, initsize, tmp;
+	unsigned node;
+
+	high_memory = (void *) __va(num_physpages << PAGE_SHIFT);
+
+	for_each_online_node(node) {
+		unsigned slot, numslots;
+		struct page *end, *p;
+	
+		/*
+	 	 * This will free up the bootmem, ie, slot 0 memory.
+	 	 */
+		totalram_pages += free_all_bootmem_node(NODE_DATA(node));
+
+		/*
+		 * We need to manually do the other slots.
+		 */
+		numslots = node_getlastslot(node);
+		for (slot = 1; slot <= numslots; slot++) {
+			p = NODE_DATA(node)->node_mem_map +
+				(slot_getbasepfn(node, slot) -
+				 slot_getbasepfn(node, 0));
+
+			/*
+			 * Free valid memory in current slot.
+			 */
+			for (end = p + slot_getsize(node, slot); p < end; p++) {
+				/* if (!page_is_ram(pgnr)) continue; */
+				/* commented out until page_is_ram works */
+				ClearPageReserved(p);
+				set_page_count(p, 1);
+				__free_page(p);
+				totalram_pages++;
+			}
+		}
+	}
+
+	totalram_pages -= setup_zero_pages();	/* This comes from node 0 */
+
+	codesize =  (unsigned long) &_etext - (unsigned long) &_text;
+	datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
+	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
+
+	tmp = nr_free_pages();
+	printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, "
+	       "%ldk reserved, %ldk data, %ldk init, %ldk highmem)\n",
+	       tmp << (PAGE_SHIFT-10),
+	       num_physpages << (PAGE_SHIFT-10),
+	       codesize >> 10,
+	       (num_physpages - tmp) << (PAGE_SHIFT-10),
+	       datasize >> 10,
+	       initsize >> 10,
+	       (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)));
+}
diff --git a/arch/mips/sgi-ip27/ip27-nmi.c b/arch/mips/sgi-ip27/ip27-nmi.c
new file mode 100644
index 0000000..b0a25e1
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-nmi.c
@@ -0,0 +1,249 @@
+#include <linux/kallsyms.h>
+#include <linux/kernel.h>
+#include <linux/mmzone.h>
+#include <linux/nodemask.h>
+#include <linux/spinlock.h>
+#include <linux/smp.h>
+#include <asm/atomic.h>
+#include <asm/sn/types.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/nmi.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/sn0/hub.h>
+
+#if 0
+#define NODE_NUM_CPUS(n)	CNODE_NUM_CPUS(n)
+#else
+#define NODE_NUM_CPUS(n)	CPUS_PER_NODE
+#endif
+
+#define CNODEID_NONE (cnodeid_t)-1
+#define enter_panic_mode()	spin_lock(&nmi_lock)
+
+typedef unsigned long machreg_t;
+
+DEFINE_SPINLOCK(nmi_lock);
+
+/*
+ * Lets see what else we need to do here. Set up sp, gp?
+ */
+void nmi_dump(void)
+{
+	void cont_nmi_dump(void);
+
+	cont_nmi_dump();
+}
+
+void install_cpu_nmi_handler(int slice)
+{
+	nmi_t *nmi_addr;
+
+	nmi_addr = (nmi_t *)NMI_ADDR(get_nasid(), slice);
+	if (nmi_addr->call_addr)
+		return;
+	nmi_addr->magic = NMI_MAGIC;
+	nmi_addr->call_addr = (void *)nmi_dump;
+	nmi_addr->call_addr_c =
+		(void *)(~((unsigned long)(nmi_addr->call_addr)));
+	nmi_addr->call_parm = 0;
+}
+
+/*
+ * Copy the cpu registers which have been saved in the IP27prom format
+ * into the eframe format for the node under consideration.
+ */
+
+void nmi_cpu_eframe_save(nasid_t nasid, int slice)
+{
+	struct reg_struct *nr;
+	int 		i;
+
+	/* Get the pointer to the current cpu's register set. */
+	nr = (struct reg_struct *)
+		(TO_UNCAC(TO_NODE(nasid, IP27_NMI_KREGS_OFFSET)) +
+		slice * IP27_NMI_KREGS_CPU_SIZE);
+
+	printk("NMI nasid %d: slice %d\n", nasid, slice);
+
+	/*
+	 * Saved main processor registers
+	 */
+	for (i = 0; i < 32; ) {
+		if ((i % 4) == 0)
+			printk("$%2d   :", i);
+		printk(" %016lx", nr->gpr[i]);
+
+		i++;
+		if ((i % 4) == 0)
+			printk("\n");
+	}
+
+	printk("Hi    : (value lost)\n");
+	printk("Lo    : (value lost)\n");
+
+	/*
+	 * Saved cp0 registers
+	 */
+	printk("epc   : %016lx ", nr->epc);
+	print_symbol("%s ", nr->epc);
+	printk("%s\n", print_tainted());
+	printk("ErrEPC: %016lx ", nr->error_epc);
+	print_symbol("%s\n", nr->error_epc);
+	printk("ra    : %016lx ", nr->gpr[31]);
+	print_symbol("%s\n", nr->gpr[31]);
+	printk("Status: %08lx         ", nr->sr);
+
+	if (nr->sr & ST0_KX)
+		printk("KX ");
+	if (nr->sr & ST0_SX)
+		printk("SX 	");
+	if (nr->sr & ST0_UX)
+		printk("UX ");
+
+	switch (nr->sr & ST0_KSU) {
+	case KSU_USER:
+		printk("USER ");
+		break;
+	case KSU_SUPERVISOR:
+		printk("SUPERVISOR ");
+		break;
+	case KSU_KERNEL:
+		printk("KERNEL ");
+		break;
+	default:
+		printk("BAD_MODE ");
+		break;
+	}
+
+	if (nr->sr & ST0_ERL)
+		printk("ERL ");
+	if (nr->sr & ST0_EXL)
+		printk("EXL ");
+	if (nr->sr & ST0_IE)
+		printk("IE ");
+	printk("\n");
+
+	printk("Cause : %08lx\n", nr->cause);
+	printk("PrId  : %08x\n", read_c0_prid());
+	printk("BadVA : %016lx\n", nr->badva);
+	printk("CErr  : %016lx\n", nr->cache_err);
+	printk("NMI_SR: %016lx\n", nr->nmi_sr);
+
+	printk("\n");
+}
+
+void nmi_dump_hub_irq(nasid_t nasid, int slice)
+{
+	hubreg_t mask0, mask1, pend0, pend1;
+
+	if (slice == 0) {				/* Slice A */
+		mask0 = REMOTE_HUB_L(nasid, PI_INT_MASK0_A);
+		mask1 = REMOTE_HUB_L(nasid, PI_INT_MASK1_A);
+	} else {					/* Slice B */
+		mask0 = REMOTE_HUB_L(nasid, PI_INT_MASK0_B);
+		mask1 = REMOTE_HUB_L(nasid, PI_INT_MASK1_B);
+	}
+
+	pend0 = REMOTE_HUB_L(nasid, PI_INT_PEND0);
+	pend1 = REMOTE_HUB_L(nasid, PI_INT_PEND1);
+
+	printk("PI_INT_MASK0: %16lx PI_INT_MASK1: %16lx\n", mask0, mask1);
+	printk("PI_INT_PEND0: %16lx PI_INT_PEND1: %16lx\n", pend0, pend1);
+	printk("\n\n");
+}
+
+/*
+ * Copy the cpu registers which have been saved in the IP27prom format
+ * into the eframe format for the node under consideration.
+ */
+void nmi_node_eframe_save(cnodeid_t  cnode)
+{
+	nasid_t nasid;
+	int slice;
+
+	/* Make sure that we have a valid node */
+	if (cnode == CNODEID_NONE)
+		return;
+
+	nasid = COMPACT_TO_NASID_NODEID(cnode);
+	if (nasid == INVALID_NASID)
+		return;
+
+	/* Save the registers into eframe for each cpu */
+	for (slice = 0; slice < NODE_NUM_CPUS(slice); slice++) {
+		nmi_cpu_eframe_save(nasid, slice);
+		nmi_dump_hub_irq(nasid, slice);
+	}
+}
+
+/*
+ * Save the nmi cpu registers for all cpus in the system.
+ */
+void
+nmi_eframes_save(void)
+{
+	cnodeid_t	cnode;
+
+	for_each_online_node(cnode)
+		nmi_node_eframe_save(cnode);
+}
+
+void
+cont_nmi_dump(void)
+{
+#ifndef REAL_NMI_SIGNAL
+	static atomic_t nmied_cpus = ATOMIC_INIT(0);
+
+	atomic_inc(&nmied_cpus);
+#endif
+	/*
+	 * Use enter_panic_mode to allow only 1 cpu to proceed
+	 */
+	enter_panic_mode();
+
+#ifdef REAL_NMI_SIGNAL
+	/*
+	 * Wait up to 15 seconds for the other cpus to respond to the NMI.
+	 * If a cpu has not responded after 10 sec, send it 1 additional NMI.
+	 * This is for 2 reasons:
+	 *	- sometimes a MMSC fail to NMI all cpus.
+	 *	- on 512p SN0 system, the MMSC will only send NMIs to
+	 *	  half the cpus. Unfortunately, we don't know which cpus may be
+	 *	  NMIed - it depends on how the site chooses to configure.
+	 *
+	 * Note: it has been measure that it takes the MMSC up to 2.3 secs to
+	 * send NMIs to all cpus on a 256p system.
+	 */
+	for (i=0; i < 1500; i++) {
+		for_each_online_node(node)
+			if (NODEPDA(node)->dump_count == 0)
+				break;
+		if (node == MAX_NUMNODES)
+			break;
+		if (i == 1000) {
+			for_each_online_node(node)
+				if (NODEPDA(node)->dump_count == 0) {
+					cpu = node_to_first_cpu(node);
+					for (n=0; n < CNODE_NUM_CPUS(node); cpu++, n++) {
+						CPUMASK_SETB(nmied_cpus, cpu);
+						/*
+						 * cputonasid, cputoslice
+						 * needs kernel cpuid
+						 */
+						SEND_NMI((cputonasid(cpu)), (cputoslice(cpu)));
+					}
+				}
+
+		}
+		udelay(10000);
+	}
+#else
+	while (atomic_read(&nmied_cpus) != num_online_cpus());
+#endif
+
+	/*
+	 * Save the nmi cpu registers for all cpu in the eframe format.
+	 */
+	nmi_eframes_save();
+	LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
+}
diff --git a/arch/mips/sgi-ip27/ip27-reset.c b/arch/mips/sgi-ip27/ip27-reset.c
new file mode 100644
index 0000000..2e16be9
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-reset.c
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ *
+ * Reset an IP27.
+ *
+ * Copyright (C) 1997, 1998, 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/smp.h>
+#include <linux/mmzone.h>
+#include <linux/nodemask.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <asm/sgialib.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/gda.h>
+#include <asm/sn/sn0/hub.h>
+
+void machine_restart(char *command) __attribute__((noreturn));
+void machine_halt(void) __attribute__((noreturn));
+void machine_power_off(void) __attribute__((noreturn));
+
+#define noreturn while(1);				/* Silence gcc.  */
+
+/* XXX How to pass the reboot command to the firmware??? */
+static void ip27_machine_restart(char *command)
+{
+#if 0
+	int i;
+#endif
+
+	printk("Reboot started from CPU %d\n", smp_processor_id());
+#ifdef CONFIG_SMP
+	smp_send_stop();
+#endif
+#if 0
+	for_each_online_node(i)
+		REMOTE_HUB_S(COMPACT_TO_NASID_NODEID(i), PROMOP_REG,
+							PROMOP_REBOOT);
+#else
+	LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
+#endif
+	noreturn;
+}
+
+static void ip27_machine_halt(void)
+{
+	int i;
+
+#ifdef CONFIG_SMP
+	smp_send_stop();
+#endif
+	for_each_online_node(i)
+		REMOTE_HUB_S(COMPACT_TO_NASID_NODEID(i), PROMOP_REG,
+							PROMOP_RESTART);
+	LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
+	noreturn;
+}
+
+static void ip27_machine_power_off(void)
+{
+	/* To do ...  */
+	noreturn;
+}
+
+void ip27_reboot_setup(void)
+{
+	_machine_restart = ip27_machine_restart;
+	_machine_halt = ip27_machine_halt;
+	_machine_power_off = ip27_machine_power_off;
+}
diff --git a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c
new file mode 100644
index 0000000..17f768c
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-smp.c
@@ -0,0 +1,225 @@
+/*
+ * 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) 2000 - 2001 by Kanoj Sarcar (kanoj@sgi.com)
+ * Copyright (C) 2000 - 2001 by Silicon Graphics, Inc.
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/nodemask.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/gda.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/launch.h>
+#include <asm/sn/mapped_kernel.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/types.h>
+#include <asm/sn/sn0/hubpi.h>
+#include <asm/sn/sn0/hubio.h>
+#include <asm/sn/sn0/ip27.h>
+
+/*
+ * Takes as first input the PROM assigned cpu id, and the kernel
+ * assigned cpu id as the second.
+ */
+static void alloc_cpupda(cpuid_t cpu, int cpunum)
+{
+	cnodeid_t node = get_cpu_cnode(cpu);
+	nasid_t nasid = COMPACT_TO_NASID_NODEID(node);
+
+	cputonasid(cpunum) = nasid;
+	cpu_data[cpunum].p_nodeid = node;
+	cputoslice(cpunum) = get_cpu_slice(cpu);
+}
+
+static nasid_t get_actual_nasid(lboard_t *brd)
+{
+	klhub_t *hub;
+
+	if (!brd)
+		return INVALID_NASID;
+
+	/* find out if we are a completely disabled brd. */
+	hub  = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
+	if (!hub)
+		return INVALID_NASID;
+	if (!(hub->hub_info.flags & KLINFO_ENABLE))	/* disabled node brd */
+		return hub->hub_info.physid;
+	else
+		return brd->brd_nasid;
+}
+
+static int do_cpumask(cnodeid_t cnode, nasid_t nasid, int highest)
+{
+	static int tot_cpus_found = 0;
+	lboard_t *brd;
+	klcpu_t *acpu;
+	int cpus_found = 0;
+	cpuid_t cpuid;
+
+	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27);
+
+	do {
+		acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU);
+		while (acpu) {
+			cpuid = acpu->cpu_info.virtid;
+			/* cnode is not valid for completely disabled brds */
+			if (get_actual_nasid(brd) == brd->brd_nasid)
+				cpuid_to_compact_node[cpuid] = cnode;
+			if (cpuid > highest)
+				highest = cpuid;
+			/* Only let it join in if it's marked enabled */
+			if ((acpu->cpu_info.flags & KLINFO_ENABLE) &&
+			    (tot_cpus_found != NR_CPUS)) {
+				cpu_set(cpuid, phys_cpu_present_map);
+				alloc_cpupda(cpuid, tot_cpus_found);
+				cpus_found++;
+				tot_cpus_found++;
+			}
+			acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu,
+								KLSTRUCT_CPU);
+		}
+		brd = KLCF_NEXT(brd);
+		if (!brd)
+			break;
+
+		brd = find_lboard(brd, KLTYPE_IP27);
+	} while (brd);
+
+	return highest;
+}
+
+void cpu_node_probe(void)
+{
+	int i, highest = 0;
+	gda_t *gdap = GDA;
+
+	/*
+	 * Initialize the arrays to invalid nodeid (-1)
+	 */
+	for (i = 0; i < MAX_COMPACT_NODES; i++)
+		compact_to_nasid_node[i] = INVALID_NASID;
+	for (i = 0; i < MAX_NASIDS; i++)
+		nasid_to_compact_node[i] = INVALID_CNODEID;
+	for (i = 0; i < MAXCPUS; i++)
+		cpuid_to_compact_node[i] = INVALID_CNODEID;
+
+	/*
+	 * MCD - this whole "compact node" stuff can probably be dropped,
+	 * as we can handle sparse numbering now
+	 */
+	nodes_clear(node_online_map);
+	for (i = 0; i < MAX_COMPACT_NODES; i++) {
+		nasid_t nasid = gdap->g_nasidtable[i];
+		if (nasid == INVALID_NASID)
+			break;
+		compact_to_nasid_node[i] = nasid;
+		nasid_to_compact_node[nasid] = i;
+		node_set_online(num_online_nodes());
+		highest = do_cpumask(i, nasid, highest);
+	}
+
+	printk("Discovered %d cpus on %d nodes\n", highest + 1, num_online_nodes());
+}
+
+static void intr_clear_bits(nasid_t nasid, volatile hubreg_t *pend,
+	int base_level)
+{
+	volatile hubreg_t bits;
+	int i;
+
+	/* Check pending interrupts */
+	if ((bits = HUB_L(pend)) != 0)
+		for (i = 0; i < N_INTPEND_BITS; i++)
+			if (bits & (1 << i))
+				LOCAL_HUB_CLR_INTR(base_level + i);
+}
+
+static void intr_clear_all(nasid_t nasid)
+{
+	REMOTE_HUB_S(nasid, PI_INT_MASK0_A, 0);
+	REMOTE_HUB_S(nasid, PI_INT_MASK0_B, 0);
+	REMOTE_HUB_S(nasid, PI_INT_MASK1_A, 0);
+	REMOTE_HUB_S(nasid, PI_INT_MASK1_B, 0);
+	intr_clear_bits(nasid, REMOTE_HUB_ADDR(nasid, PI_INT_PEND0),
+	                INT_PEND0_BASELVL);
+	intr_clear_bits(nasid, REMOTE_HUB_ADDR(nasid, PI_INT_PEND1),
+	                INT_PEND1_BASELVL);
+}
+
+void __init prom_prepare_cpus(unsigned int max_cpus)
+{
+	cnodeid_t	cnode;
+
+	for_each_online_node(cnode)
+		intr_clear_all(COMPACT_TO_NASID_NODEID(cnode));
+
+	replicate_kernel_text();
+
+	/*
+	 * Assumption to be fixed: we're always booted on logical / physical
+	 * processor 0.  While we're always running on logical processor 0
+	 * this still means this is physical processor zero; it might for
+	 * example be disabled in the firwware.
+	 */
+	alloc_cpupda(0, 0);
+}
+
+/*
+ * Launch a slave into smp_bootstrap().  It doesn't take an argument, and we
+ * set sp to the kernel stack of the newly created idle process, gp to the proc
+ * struct so that current_thread_info() will work.
+ */
+void __init prom_boot_secondary(int cpu, struct task_struct *idle)
+{
+	unsigned long gp = (unsigned long) idle->thread_info;
+	unsigned long sp = gp + THREAD_SIZE - 32;
+
+	LAUNCH_SLAVE(cputonasid(cpu),cputoslice(cpu),
+		(launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap),
+		0, (void *) sp, (void *) gp);
+}
+
+void prom_init_secondary(void)
+{
+	per_cpu_init();
+	local_irq_enable();
+}
+
+void __init prom_cpus_done(void)
+{
+}
+
+void prom_smp_finish(void)
+{
+}
+
+void core_send_ipi(int destid, unsigned int action)
+{
+	int irq;
+
+	switch (action) {
+	case SMP_RESCHEDULE_YOURSELF:
+		irq = CPU_RESCHED_A_IRQ;
+		break;
+	case SMP_CALL_FUNCTION:
+		irq = CPU_CALL_A_IRQ;
+		break;
+	default:
+		panic("sendintr");
+	}
+
+	irq += cputoslice(destid);
+
+	/*
+	 * Convert the compact hub number to the NASID to get the correct
+	 * part of the address space.  Then set the interrupt bit associated
+	 * with the CPU we want to send the interrupt to.
+	 */
+	REMOTE_HUB_SEND_INTR(COMPACT_TO_NASID_NODEID(cpu_to_node(destid)), irq);
+}
diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c
new file mode 100644
index 0000000..8c1b96f
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-timer.c
@@ -0,0 +1,243 @@
+/*
+ * Copytight (C) 1999, 2000, 05 Ralf Baechle (ralf@linux-mips.org)
+ * Copytight (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/bcd.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/param.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/mm.h>
+
+#include <asm/time.h>
+#include <asm/pgtable.h>
+#include <asm/sgialib.h>
+#include <asm/sn/ioc3.h>
+#include <asm/m48t35.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/sn0/ip27.h>
+#include <asm/sn/sn0/hub.h>
+
+/*
+ * This is a hack; we really need to figure these values out dynamically
+ *
+ * Since 800 ns works very well with various HUB frequencies, such as
+ * 360, 380, 390 and 400 MHZ, we use 800 ns rtc cycle time.
+ *
+ * Ralf: which clock rate is used to feed the counter?
+ */
+#define NSEC_PER_CYCLE		800
+#define CYCLES_PER_SEC		(NSEC_PER_SEC/NSEC_PER_CYCLE)
+#define CYCLES_PER_JIFFY	(CYCLES_PER_SEC/HZ)
+
+#define TICK_SIZE (tick_nsec / 1000)
+
+static unsigned long ct_cur[NR_CPUS];	/* What counter should be at next timer irq */
+static long last_rtc_update;		/* Last time the rtc clock got updated */
+
+extern volatile unsigned long wall_jiffies;
+
+#if 0
+static int set_rtc_mmss(unsigned long nowtime)
+{
+	int retval = 0;
+	int real_seconds, real_minutes, cmos_minutes;
+	struct m48t35_rtc *rtc;
+	nasid_t nid;
+
+	nid = get_nasid();
+	rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base +
+							IOC3_BYTEBUS_DEV0);
+
+	rtc->control |= M48T35_RTC_READ;
+	cmos_minutes = BCD2BIN(rtc->min);
+	rtc->control &= ~M48T35_RTC_READ;
+
+	/*
+	 * Since we're only adjusting minutes and seconds, don't interfere with
+	 * hour overflow. This avoids messing with unknown time zones but
+	 * requires your RTC not to be off by more than 15 minutes
+	 */
+	real_seconds = nowtime % 60;
+	real_minutes = nowtime / 60;
+	if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
+		real_minutes += 30;	/* correct for half hour time zone */
+	real_minutes %= 60;
+
+	if (abs(real_minutes - cmos_minutes) < 30) {
+		real_seconds = BIN2BCD(real_seconds);
+		real_minutes = BIN2BCD(real_minutes);
+		rtc->control |= M48T35_RTC_SET;
+		rtc->sec = real_seconds;
+		rtc->min = real_minutes;
+		rtc->control &= ~M48T35_RTC_SET;
+	} else {
+		printk(KERN_WARNING
+		       "set_rtc_mmss: can't update from %d to %d\n",
+		       cmos_minutes, real_minutes);
+		retval = -1;
+	}
+
+	return retval;
+}
+#endif
+
+void ip27_rt_timer_interrupt(struct pt_regs *regs)
+{
+	int cpu = smp_processor_id();
+	int cpuA = cputoslice(cpu) == 0;
+	int irq = 9;				/* XXX Assign number */
+
+	irq_enter();
+	write_seqlock(&xtime_lock);
+
+again:
+	LOCAL_HUB_S(cpuA ? PI_RT_PEND_A : PI_RT_PEND_B, 0);	/* Ack  */
+	ct_cur[cpu] += CYCLES_PER_JIFFY;
+	LOCAL_HUB_S(cpuA ? PI_RT_COMPARE_A : PI_RT_COMPARE_B, ct_cur[cpu]);
+
+	if (LOCAL_HUB_L(PI_RT_COUNT) >= ct_cur[cpu])
+		goto again;
+
+	kstat_this_cpu.irqs[irq]++;		/* kstat only for bootcpu? */
+
+	if (cpu == 0)
+		do_timer(regs);
+
+	update_process_times(user_mode(regs));
+
+	/*
+	 * If we have an externally synchronized Linux clock, then update
+	 * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
+	 * called as close as possible to when a second starts.
+	 */
+	if ((time_status & STA_UNSYNC) == 0 &&
+	    xtime.tv_sec > last_rtc_update + 660 &&
+	    (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
+	    (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
+		if (rtc_set_time(xtime.tv_sec) == 0) {
+			last_rtc_update = xtime.tv_sec;
+		} else {
+			last_rtc_update = xtime.tv_sec - 600;
+			/* do it again in 60 s */
+		}
+	}
+
+	write_sequnlock(&xtime_lock);
+	irq_exit();
+}
+
+unsigned long ip27_do_gettimeoffset(void)
+{
+	unsigned long ct_cur1;
+	ct_cur1 = REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT) + CYCLES_PER_JIFFY;
+	return (ct_cur1 - ct_cur[0]) * NSEC_PER_CYCLE / 1000;
+}
+
+/* Includes for ioc3_init().  */
+#include <asm/sn/types.h>
+#include <asm/sn/sn0/addrs.h>
+#include <asm/sn/sn0/hubni.h>
+#include <asm/sn/sn0/hubio.h>
+#include <asm/pci/bridge.h>
+
+static __init unsigned long get_m48t35_time(void)
+{
+        unsigned int year, month, date, hour, min, sec;
+	struct m48t35_rtc *rtc;
+	nasid_t nid;
+
+	nid = get_nasid();
+	rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base +
+							IOC3_BYTEBUS_DEV0);
+
+	rtc->control |= M48T35_RTC_READ;
+	sec = rtc->sec;
+	min = rtc->min;
+	hour = rtc->hour;
+	date = rtc->date;
+	month = rtc->month;
+	year = rtc->year;
+	rtc->control &= ~M48T35_RTC_READ;
+
+        sec = BCD2BIN(sec);
+        min = BCD2BIN(min);
+        hour = BCD2BIN(hour);
+        date = BCD2BIN(date);
+        month = BCD2BIN(month);
+        year = BCD2BIN(year);
+
+        year += 1970;
+
+        return mktime(year, month, date, hour, min, sec);
+}
+
+static void ip27_timer_setup(struct irqaction *irq)
+{
+	/* over-write the handler, we use our own way */
+	irq->handler = no_action;
+
+	/* setup irqaction */
+//	setup_irq(IP27_TIMER_IRQ, irq);		/* XXX Can't do this yet.  */
+}
+
+void __init ip27_time_init(void)
+{
+	xtime.tv_sec = get_m48t35_time();
+	xtime.tv_nsec = 0;
+
+	do_gettimeoffset = ip27_do_gettimeoffset;
+
+	board_timer_setup = ip27_timer_setup;
+}
+
+void __init cpu_time_init(void)
+{
+	lboard_t *board;
+	klcpu_t *cpu;
+	int cpuid;
+
+	/* Don't use ARCS.  ARCS is fragile.  Klconfig is simple and sane.  */
+	board = find_lboard(KL_CONFIG_INFO(get_nasid()), KLTYPE_IP27);
+	if (!board)
+		panic("Can't find board info for myself.");
+
+	cpuid = LOCAL_HUB_L(PI_CPU_NUM) ? IP27_CPU0_INDEX : IP27_CPU1_INDEX;
+	cpu = (klcpu_t *) KLCF_COMP(board, cpuid);
+	if (!cpu)
+		panic("No information about myself?");
+
+	printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed);
+
+	set_c0_status(SRB_TIMOCLK);
+}
+
+void __init hub_rtc_init(cnodeid_t cnode)
+{
+	/*
+	 * We only need to initialize the current node.
+	 * If this is not the current node then it is a cpuless
+	 * node and timeouts will not happen there.
+	 */
+	if (get_compact_nodeid() == cnode) {
+		int cpu = smp_processor_id();
+		LOCAL_HUB_S(PI_RT_EN_A, 1);
+		LOCAL_HUB_S(PI_RT_EN_B, 1);
+		LOCAL_HUB_S(PI_PROF_EN_A, 0);
+		LOCAL_HUB_S(PI_PROF_EN_B, 0);
+		ct_cur[cpu] = CYCLES_PER_JIFFY;
+		LOCAL_HUB_S(PI_RT_COMPARE_A, ct_cur[cpu]);
+		LOCAL_HUB_S(PI_RT_COUNT, 0);
+		LOCAL_HUB_S(PI_RT_PEND_A, 0);
+		LOCAL_HUB_S(PI_RT_COMPARE_B, ct_cur[cpu]);
+		LOCAL_HUB_S(PI_RT_COUNT, 0);
+		LOCAL_HUB_S(PI_RT_PEND_B, 0);
+	}
+}
diff --git a/arch/mips/sgi-ip27/ip27-xtalk.c b/arch/mips/sgi-ip27/ip27-xtalk.c
new file mode 100644
index 0000000..fc82f34
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-xtalk.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000 Silcon Graphics, Inc.
+ * Copyright (C) 2004 Christoph Hellwig.
+ *	Released under GPL v2.
+ *
+ * Generic XTALK initialization code
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/sn/types.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/hub.h>
+#include <asm/pci/bridge.h>
+#include <asm/xtalk/xtalk.h>
+
+
+#define XBOW_WIDGET_PART_NUM    0x0
+#define XXBOW_WIDGET_PART_NUM   0xd000  /* Xbow in Xbridge */
+#define BASE_XBOW_PORT  	8     /* Lowest external port */
+
+extern int bridge_probe(nasid_t nasid, int widget, int masterwid);
+
+static int __init probe_one_port(nasid_t nasid, int widget, int masterwid)
+{
+	widgetreg_t 		widget_id;
+	xwidget_part_num_t	partnum;
+
+	widget_id = *(volatile widgetreg_t *)
+		(RAW_NODE_SWIN_BASE(nasid, widget) + WIDGET_ID);
+	partnum = XWIDGET_PART_NUM(widget_id);
+
+	printk(KERN_INFO "Cpu %d, Nasid 0x%x, widget 0x%x (partnum 0x%x) is ",
+			smp_processor_id(), nasid, widget, partnum);
+
+	switch (partnum) {
+	case BRIDGE_WIDGET_PART_NUM:
+	case XBRIDGE_WIDGET_PART_NUM:
+		bridge_probe(nasid, widget, masterwid);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int __init xbow_probe(nasid_t nasid)
+{
+	lboard_t *brd;
+	klxbow_t *xbow_p;
+	unsigned masterwid, i;
+
+	printk("is xbow\n");
+
+	/*
+	 * found xbow, so may have multiple bridges
+	 * need to probe xbow
+	 */
+	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_MIDPLANE8);
+	if (!brd)
+		return -ENODEV;
+
+	xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW);
+	if (!xbow_p)
+		return -ENODEV;
+
+	/*
+	 * Okay, here's a xbow. Lets arbitrate and find
+	 * out if we should initialize it. Set enabled
+	 * hub connected at highest or lowest widget as
+	 * master.
+	 */
+#ifdef WIDGET_A
+	i = HUB_WIDGET_ID_MAX + 1;
+	do {
+		i--;
+	} while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||
+		 (!XBOW_PORT_IS_ENABLED(xbow_p, i)));
+#else
+	i = HUB_WIDGET_ID_MIN - 1;
+	do {
+		i++;
+	} while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||
+		 (!XBOW_PORT_IS_ENABLED(xbow_p, i)));
+#endif
+
+	masterwid = i;
+	if (nasid != XBOW_PORT_NASID(xbow_p, i))
+		return 1;
+
+	for (i = HUB_WIDGET_ID_MIN; i <= HUB_WIDGET_ID_MAX; i++) {
+		if (XBOW_PORT_IS_ENABLED(xbow_p, i) &&
+		    XBOW_PORT_TYPE_IO(xbow_p, i))
+			probe_one_port(nasid, i, masterwid);
+	}
+
+	return 0;
+}
+
+void __init xtalk_probe_node(cnodeid_t nid)
+{
+	volatile u64 		hubreg;
+	nasid_t	 		nasid;
+	xwidget_part_num_t	partnum;
+	widgetreg_t 		widget_id;
+
+	nasid = COMPACT_TO_NASID_NODEID(nid);
+	hubreg = REMOTE_HUB_L(nasid, IIO_LLP_CSR);
+
+	/* check whether the link is up */
+	if (!(hubreg & IIO_LLP_CSR_IS_UP))
+		return;
+
+	widget_id = *(volatile widgetreg_t *)
+                       (RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID);
+	partnum = XWIDGET_PART_NUM(widget_id);
+
+	printk(KERN_INFO "Cpu %d, Nasid 0x%x: partnum 0x%x is ",
+			smp_processor_id(), nasid, partnum);
+
+	switch (partnum) {
+	case BRIDGE_WIDGET_PART_NUM:
+		bridge_probe(nasid, 0x8, 0xa);
+		break;
+	case XBOW_WIDGET_PART_NUM:
+	case XXBOW_WIDGET_PART_NUM:
+		xbow_probe(nasid);
+		break;
+	default:
+		printk(" unknown widget??\n");
+		break;
+	}
+}
diff --git a/arch/mips/sgi-ip32/Makefile b/arch/mips/sgi-ip32/Makefile
new file mode 100644
index 0000000..470898f
--- /dev/null
+++ b/arch/mips/sgi-ip32/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for the SGI specific kernel interface routines
+# under Linux.
+#
+
+obj-y	+= ip32-berr.o ip32-irq.o ip32-irq-glue.o ip32-setup.o ip32-reset.o \
+	   crime.o ip32-memory.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/sgi-ip32/crime.c b/arch/mips/sgi-ip32/crime.c
new file mode 100644
index 0000000..eb3a16a
--- /dev/null
+++ b/arch/mips/sgi-ip32/crime.c
@@ -0,0 +1,103 @@
+/*
+ * 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) 2001, 2003 Keith M Wesolowski
+ * Copyright (C) 2005 Ilya A. Volynets <ilya@total-knowledge.com>
+ */
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/ptrace.h>
+#include <asm/page.h>
+#include <asm/ip32/crime.h>
+#include <asm/ip32/mace.h>
+
+struct sgi_crime *crime;
+struct sgi_mace *mace;
+
+void __init crime_init(void)
+{
+	unsigned int id, rev;
+	const int field = 2 * sizeof(unsigned long);
+
+	set_io_port_base((unsigned long) ioremap(MACEPCI_LOW_IO, 0x2000000));
+	crime = ioremap(CRIME_BASE, sizeof(struct sgi_crime));
+	mace = ioremap(MACE_BASE, sizeof(struct sgi_mace));
+
+	id = crime->id;
+	rev = id & CRIME_ID_REV;
+	id = (id & CRIME_ID_IDBITS) >> 4;
+	printk (KERN_INFO "CRIME id %1x rev %d at 0x%0*lx\n",
+		id, rev, field, (unsigned long) CRIME_BASE);
+}
+
+irqreturn_t
+crime_memerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned long stat, addr;
+	int fatal = 0;
+
+	stat = crime->mem_error_stat & CRIME_MEM_ERROR_STAT_MASK;
+	addr = crime->mem_error_addr & CRIME_MEM_ERROR_ADDR_MASK;
+
+	printk("CRIME memory error at 0x%08lx ST 0x%08lx<", addr, stat);
+
+	if (stat & CRIME_MEM_ERROR_INV)
+		printk("INV,");
+	if (stat & CRIME_MEM_ERROR_ECC) {
+		unsigned long ecc_syn =
+			crime->mem_ecc_syn & CRIME_MEM_ERROR_ECC_SYN_MASK;
+		unsigned long ecc_gen =
+			crime->mem_ecc_chk & CRIME_MEM_ERROR_ECC_CHK_MASK;
+		printk("ECC,SYN=0x%08lx,GEN=0x%08lx,", ecc_syn, ecc_gen);
+	}
+	if (stat & CRIME_MEM_ERROR_MULTIPLE) {
+		fatal = 1;
+		printk("MULTIPLE,");
+	}
+	if (stat & CRIME_MEM_ERROR_HARD_ERR) {
+		fatal = 1;
+		printk("HARD,");
+	}
+	if (stat & CRIME_MEM_ERROR_SOFT_ERR)
+		printk("SOFT,");
+	if (stat & CRIME_MEM_ERROR_CPU_ACCESS)
+		printk("CPU,");
+	if (stat & CRIME_MEM_ERROR_VICE_ACCESS)
+		printk("VICE,");
+	if (stat & CRIME_MEM_ERROR_GBE_ACCESS)
+		printk("GBE,");
+	if (stat & CRIME_MEM_ERROR_RE_ACCESS)
+		printk("RE,REID=0x%02lx,", (stat & CRIME_MEM_ERROR_RE_ID)>>8);
+	if (stat & CRIME_MEM_ERROR_MACE_ACCESS)
+		printk("MACE,MACEID=0x%02lx,", stat & CRIME_MEM_ERROR_MACE_ID);
+
+	crime->mem_error_stat = 0;
+
+	if (fatal) {
+		printk("FATAL>\n");
+		panic("Fatal memory error.");
+	} else
+		printk("NONFATAL>\n");
+
+	return IRQ_HANDLED;
+}
+
+irqreturn_t
+crime_cpuerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned long stat = crime->cpu_error_stat & CRIME_CPU_ERROR_MASK;
+	unsigned long addr = crime->cpu_error_addr & CRIME_CPU_ERROR_ADDR_MASK;
+
+	addr <<= 2;
+	printk ("CRIME CPU error at 0x%09lx status 0x%08lx\n", addr, stat);
+	crime->cpu_error_stat = 0;
+
+	return IRQ_HANDLED;
+}
diff --git a/arch/mips/sgi-ip32/ip32-berr.c b/arch/mips/sgi-ip32/ip32-berr.c
new file mode 100644
index 0000000..a278e91
--- /dev/null
+++ b/arch/mips/sgi-ip32/ip32-berr.c
@@ -0,0 +1,36 @@
+/*
+ * 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) 1994, 1995, 1996, 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 by Silicon Graphics
+ * Copyright (C) 2002  Maciej W. Rozycki
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <asm/traps.h>
+#include <asm/uaccess.h>
+#include <asm/addrspace.h>
+#include <asm/ptrace.h>
+#include <asm/tlbdebug.h>
+
+int ip32_be_handler(struct pt_regs *regs, int is_fixup)
+{
+	int data = regs->cp0_cause & 4;
+
+	if (is_fixup)
+		return MIPS_BE_FIXUP;
+
+	printk("Got %cbe at 0x%lx\n", data ? 'd' : 'i', regs->cp0_epc);
+	show_regs(regs);
+	dump_tlb_all();
+	while(1);
+	force_sig(SIGBUS, current);
+}
+
+void __init ip32_be_init(void)
+{
+	board_be_handler = ip32_be_handler;
+}
diff --git a/arch/mips/sgi-ip32/ip32-irq-glue.S b/arch/mips/sgi-ip32/ip32-irq-glue.S
new file mode 100644
index 0000000..200924e
--- /dev/null
+++ b/arch/mips/sgi-ip32/ip32-irq-glue.S
@@ -0,0 +1,86 @@
+/*
+ * Low level interrupt handler for the SGI O2 aka IP32 aka Moosehead
+ *
+ * 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) 2000 Harald Koerfgen
+ * Copyright (C) 2001 Keith M Wesolowski
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+#include <asm/addrspace.h>
+
+		.text
+		.set    noreorder
+		.set    noat
+		.align  5
+		NESTED(ip32_handle_int, PT_SIZE, ra)
+		.set    noat
+		SAVE_ALL
+		CLI			# TEST: interrupts should be off
+		.set    at
+		.set    noreorder
+
+		mfc0	s0,CP0_CAUSE
+
+		andi	t1, s0, IE_IRQ0
+		bnez	t1, handle_irq0
+		 andi	t1, s0, IE_IRQ1
+		bnez	t1, handle_irq1
+		 andi	t1, s0, IE_IRQ2
+		bnez	t1, handle_irq2
+		 andi	t1, s0, IE_IRQ3
+		bnez	t1, handle_irq3
+		 andi	t1, s0, IE_IRQ4
+		bnez	t1, handle_irq4
+		 andi	t1, s0, IE_IRQ5
+		bnez	t1, handle_irq5
+		 nop
+
+		/* Either someone has triggered the "software interrupts"
+		 * or we lost an interrupt somehow.  Ignore it.
+		 */
+		j	ret_from_irq
+		 nop
+
+handle_irq0:
+		jal	ip32_irq0
+		 move	a0, sp
+		j	ret_from_irq
+		 nop
+
+handle_irq1:
+		jal	ip32_irq1
+		 move	a0, sp
+		j	ret_from_irq
+		 nop
+
+handle_irq2:
+		jal	ip32_irq2
+		 move	a0, sp
+		j	ret_from_irq
+		 nop
+
+handle_irq3:
+		jal	ip32_irq3
+		 move	a0, sp
+		j	ret_from_irq
+		 nop
+
+handle_irq4:
+		jal	ip32_irq4
+		 move	a0, sp
+		j	ret_from_irq
+		 nop
+
+handle_irq5:
+		jal	ip32_irq5
+		move	a0, sp
+		j	ret_from_irq
+		 nop
+
+		END(ip32_handle_int)
diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c
new file mode 100644
index 0000000..fc3a8e9
--- /dev/null
+++ b/arch/mips/sgi-ip32/ip32-irq.c
@@ -0,0 +1,590 @@
+/*
+ * Code to handle IP32 IRQs
+ *
+ * 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) 2000 Harald Koerfgen
+ * Copyright (C) 2001 Keith M Wesolowski
+ */
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/bitops.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/random.h>
+#include <linux/sched.h>
+
+#include <asm/mipsregs.h>
+#include <asm/signal.h>
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/ip32/crime.h>
+#include <asm/ip32/mace.h>
+#include <asm/ip32/ip32_ints.h>
+
+/* issue a PIO read to make sure no PIO writes are pending */
+static void inline flush_crime_bus(void)
+{
+	volatile unsigned long junk = crime->control;
+}
+
+static void inline flush_mace_bus(void)
+{
+	volatile unsigned long junk = mace->perif.ctrl.misc;
+}
+
+#undef DEBUG_IRQ
+#ifdef DEBUG_IRQ
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+/* O2 irq map
+ *
+ * IP0 -> software (ignored)
+ * IP1 -> software (ignored)
+ * IP2 -> (irq0) C crime 1.1 all interrupts; crime 1.5 ???
+ * IP3 -> (irq1) X unknown
+ * IP4 -> (irq2) X unknown
+ * IP5 -> (irq3) X unknown
+ * IP6 -> (irq4) X unknown
+ * IP7 -> (irq5) 0 CPU count/compare timer (system timer)
+ *
+ * crime: (C)
+ *
+ * CRIME_INT_STAT 31:0:
+ *
+ * 0  -> 1  Video in 1
+ * 1  -> 2  Video in 2
+ * 2  -> 3  Video out
+ * 3  -> 4  Mace ethernet
+ * 4  -> S  SuperIO sub-interrupt
+ * 5  -> M  Miscellaneous sub-interrupt
+ * 6  -> A  Audio sub-interrupt
+ * 7  -> 8  PCI bridge errors
+ * 8  -> 9  PCI SCSI aic7xxx 0
+ * 9  -> 10 PCI SCSI aic7xxx 1
+ * 10 -> 11 PCI slot 0
+ * 11 -> 12 unused (PCI slot 1)
+ * 12 -> 13 unused (PCI slot 2)
+ * 13 -> 14 unused (PCI shared 0)
+ * 14 -> 15 unused (PCI shared 1)
+ * 15 -> 16 unused (PCI shared 2)
+ * 16 -> 17 GBE0 (E)
+ * 17 -> 18 GBE1 (E)
+ * 18 -> 19 GBE2 (E)
+ * 19 -> 20 GBE3 (E)
+ * 20 -> 21 CPU errors
+ * 21 -> 22 Memory errors
+ * 22 -> 23 RE empty edge (E)
+ * 23 -> 24 RE full edge (E)
+ * 24 -> 25 RE idle edge (E)
+ * 25 -> 26 RE empty level
+ * 26 -> 27 RE full level
+ * 27 -> 28 RE idle level
+ * 28 -> 29 unused (software 0) (E)
+ * 29 -> 30 unused (software 1) (E)
+ * 30 -> 31 unused (software 2) - crime 1.5 CPU SysCorError (E)
+ * 31 -> 32 VICE
+ *
+ * S, M, A: Use the MACE ISA interrupt register
+ * MACE_ISA_INT_STAT 31:0
+ *
+ * 0-7 -> 33-40 Audio
+ * 8 -> 41 RTC
+ * 9 -> 42 Keyboard
+ * 10 -> X Keyboard polled
+ * 11 -> 44 Mouse
+ * 12 -> X Mouse polled
+ * 13-15 -> 46-48 Count/compare timers
+ * 16-19 -> 49-52 Parallel (16 E)
+ * 20-25 -> 53-58 Serial 1 (22 E)
+ * 26-31 -> 59-64 Serial 2 (28 E)
+ *
+ * Note that this means IRQs 5-7, 43, and 45 do not exist.  This is a
+ * different IRQ map than IRIX uses, but that's OK as Linux irq handling
+ * is quite different anyway.
+ */
+
+/*
+ * IRQ spinlock - Ralf says not to disable CPU interrupts,
+ * and I think he knows better.
+ */
+static DEFINE_SPINLOCK(ip32_irq_lock);
+
+/* Some initial interrupts to set up */
+extern irqreturn_t crime_memerr_intr (int irq, void *dev_id,
+				      struct pt_regs *regs);
+extern irqreturn_t crime_cpuerr_intr (int irq, void *dev_id,
+				      struct pt_regs *regs);
+
+struct irqaction memerr_irq = { crime_memerr_intr, SA_INTERRUPT,
+			CPU_MASK_NONE, "CRIME memory error", NULL, NULL };
+struct irqaction cpuerr_irq = { crime_cpuerr_intr, SA_INTERRUPT,
+			CPU_MASK_NONE, "CRIME CPU error", NULL, NULL };
+
+extern void ip32_handle_int(void);
+
+/*
+ * For interrupts wired from a single device to the CPU.  Only the clock
+ * uses this it seems, which is IRQ 0 and IP7.
+ */
+
+static void enable_cpu_irq(unsigned int irq)
+{
+	set_c0_status(STATUSF_IP7);
+}
+
+static unsigned int startup_cpu_irq(unsigned int irq)
+{
+	enable_cpu_irq(irq);
+	return 0;
+}
+
+static void disable_cpu_irq(unsigned int irq)
+{
+	clear_c0_status(STATUSF_IP7);
+}
+
+static void end_cpu_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		enable_cpu_irq (irq);
+}
+
+#define shutdown_cpu_irq disable_cpu_irq
+#define mask_and_ack_cpu_irq disable_cpu_irq
+
+static struct hw_interrupt_type ip32_cpu_interrupt = {
+	"IP32 CPU",
+	startup_cpu_irq,
+	shutdown_cpu_irq,
+	enable_cpu_irq,
+	disable_cpu_irq,
+	mask_and_ack_cpu_irq,
+	end_cpu_irq,
+	NULL
+};
+
+/*
+ * This is for pure CRIME interrupts - ie not MACE.  The advantage?
+ * We get to split the register in half and do faster lookups.
+ */
+
+static uint64_t crime_mask;
+
+static void enable_crime_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ip32_irq_lock, flags);
+	crime_mask |= 1 << (irq - 1);
+	crime->imask = crime_mask;
+	spin_unlock_irqrestore(&ip32_irq_lock, flags);
+}
+
+static unsigned int startup_crime_irq(unsigned int irq)
+{
+	enable_crime_irq(irq);
+	return 0; /* This is probably not right; we could have pending irqs */
+}
+
+static void disable_crime_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ip32_irq_lock, flags);
+	crime_mask &= ~(1 << (irq - 1));
+	crime->imask = crime_mask;
+	flush_crime_bus();
+	spin_unlock_irqrestore(&ip32_irq_lock, flags);
+}
+
+static void mask_and_ack_crime_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	/* Edge triggered interrupts must be cleared. */
+	if ((irq >= CRIME_GBE0_IRQ && irq <= CRIME_GBE3_IRQ)
+	    || (irq >= CRIME_RE_EMPTY_E_IRQ && irq <= CRIME_RE_IDLE_E_IRQ)
+	    || (irq >= CRIME_SOFT0_IRQ && irq <= CRIME_SOFT2_IRQ)) {
+	        uint64_t crime_int;
+		spin_lock_irqsave(&ip32_irq_lock, flags);
+		crime_int = crime->hard_int;
+		crime_int &= ~(1 << (irq - 1));
+		crime->hard_int = crime_int;
+		spin_unlock_irqrestore(&ip32_irq_lock, flags);
+	}
+	disable_crime_irq(irq);
+}
+
+static void end_crime_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		enable_crime_irq(irq);
+}
+
+#define shutdown_crime_irq disable_crime_irq
+
+static struct hw_interrupt_type ip32_crime_interrupt = {
+	"IP32 CRIME",
+	startup_crime_irq,
+	shutdown_crime_irq,
+	enable_crime_irq,
+	disable_crime_irq,
+	mask_and_ack_crime_irq,
+	end_crime_irq,
+	NULL
+};
+
+/*
+ * This is for MACE PCI interrupts.  We can decrease bus traffic by masking
+ * as close to the source as possible.  This also means we can take the
+ * next chunk of the CRIME register in one piece.
+ */
+
+static unsigned long macepci_mask;
+
+static void enable_macepci_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ip32_irq_lock, flags);
+	macepci_mask |= MACEPCI_CONTROL_INT(irq - 9);
+	mace->pci.control = macepci_mask;
+	crime_mask |= 1 << (irq - 1);
+	crime->imask = crime_mask;
+	spin_unlock_irqrestore(&ip32_irq_lock, flags);
+}
+
+static unsigned int startup_macepci_irq(unsigned int irq)
+{
+  	enable_macepci_irq (irq);
+	return 0;
+}
+
+static void disable_macepci_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ip32_irq_lock, flags);
+	crime_mask &= ~(1 << (irq - 1));
+	crime->imask = crime_mask;
+	flush_crime_bus();
+	macepci_mask &= ~MACEPCI_CONTROL_INT(irq - 9);
+	mace->pci.control = macepci_mask;
+	flush_mace_bus();
+	spin_unlock_irqrestore(&ip32_irq_lock, flags);
+}
+
+static void end_macepci_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_macepci_irq(irq);
+}
+
+#define shutdown_macepci_irq disable_macepci_irq
+#define mask_and_ack_macepci_irq disable_macepci_irq
+
+static struct hw_interrupt_type ip32_macepci_interrupt = {
+	"IP32 MACE PCI",
+	startup_macepci_irq,
+	shutdown_macepci_irq,
+	enable_macepci_irq,
+	disable_macepci_irq,
+	mask_and_ack_macepci_irq,
+	end_macepci_irq,
+	NULL
+};
+
+/* This is used for MACE ISA interrupts.  That means bits 4-6 in the
+ * CRIME register.
+ */
+
+#define MACEISA_AUDIO_INT	(MACEISA_AUDIO_SW_INT |		\
+				 MACEISA_AUDIO_SC_INT |		\
+				 MACEISA_AUDIO1_DMAT_INT |	\
+				 MACEISA_AUDIO1_OF_INT |	\
+				 MACEISA_AUDIO2_DMAT_INT |	\
+				 MACEISA_AUDIO2_MERR_INT |	\
+				 MACEISA_AUDIO3_DMAT_INT |	\
+				 MACEISA_AUDIO3_MERR_INT)
+#define MACEISA_MISC_INT	(MACEISA_RTC_INT |		\
+				 MACEISA_KEYB_INT |		\
+				 MACEISA_KEYB_POLL_INT |	\
+				 MACEISA_MOUSE_INT |		\
+				 MACEISA_MOUSE_POLL_INT |	\
+				 MACEISA_TIMER0_INT |		\
+				 MACEISA_TIMER1_INT |		\
+				 MACEISA_TIMER2_INT)
+#define MACEISA_SUPERIO_INT	(MACEISA_PARALLEL_INT |		\
+				 MACEISA_PAR_CTXA_INT |		\
+				 MACEISA_PAR_CTXB_INT |		\
+				 MACEISA_PAR_MERR_INT |		\
+				 MACEISA_SERIAL1_INT |		\
+				 MACEISA_SERIAL1_TDMAT_INT |	\
+				 MACEISA_SERIAL1_TDMAPR_INT |	\
+				 MACEISA_SERIAL1_TDMAME_INT |	\
+				 MACEISA_SERIAL1_RDMAT_INT |	\
+				 MACEISA_SERIAL1_RDMAOR_INT |	\
+				 MACEISA_SERIAL2_INT |		\
+				 MACEISA_SERIAL2_TDMAT_INT |	\
+				 MACEISA_SERIAL2_TDMAPR_INT |	\
+				 MACEISA_SERIAL2_TDMAME_INT |	\
+				 MACEISA_SERIAL2_RDMAT_INT |	\
+				 MACEISA_SERIAL2_RDMAOR_INT)
+
+static unsigned long maceisa_mask;
+
+static void enable_maceisa_irq (unsigned int irq)
+{
+	unsigned int crime_int = 0;
+	unsigned long flags;
+
+	DBG ("maceisa enable: %u\n", irq);
+
+	switch (irq) {
+	case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ:
+		crime_int = MACE_AUDIO_INT;
+		break;
+	case MACEISA_RTC_IRQ ... MACEISA_TIMER2_IRQ:
+		crime_int = MACE_MISC_INT;
+		break;
+	case MACEISA_PARALLEL_IRQ ... MACEISA_SERIAL2_RDMAOR_IRQ:
+		crime_int = MACE_SUPERIO_INT;
+		break;
+	}
+	DBG ("crime_int %08x enabled\n", crime_int);
+	spin_lock_irqsave(&ip32_irq_lock, flags);
+	crime_mask |= crime_int;
+	crime->imask = crime_mask;
+	maceisa_mask |= 1 << (irq - 33);
+	mace->perif.ctrl.imask = maceisa_mask;
+	spin_unlock_irqrestore(&ip32_irq_lock, flags);
+}
+
+static unsigned int startup_maceisa_irq(unsigned int irq)
+{
+	enable_maceisa_irq(irq);
+	return 0;
+}
+
+static void disable_maceisa_irq(unsigned int irq)
+{
+	unsigned int crime_int = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ip32_irq_lock, flags);
+	maceisa_mask &= ~(1 << (irq - 33));
+        if(!(maceisa_mask & MACEISA_AUDIO_INT))
+		crime_int |= MACE_AUDIO_INT;
+        if(!(maceisa_mask & MACEISA_MISC_INT))
+		crime_int |= MACE_MISC_INT;
+        if(!(maceisa_mask & MACEISA_SUPERIO_INT))
+		crime_int |= MACE_SUPERIO_INT;
+	crime_mask &= ~crime_int;
+	crime->imask = crime_mask;
+	flush_crime_bus();
+	mace->perif.ctrl.imask = maceisa_mask;
+	flush_mace_bus();
+	spin_unlock_irqrestore(&ip32_irq_lock, flags);
+}
+
+static void mask_and_ack_maceisa_irq(unsigned int irq)
+{
+	unsigned long mace_int, flags;
+
+	switch (irq) {
+	case MACEISA_PARALLEL_IRQ:
+	case MACEISA_SERIAL1_TDMAPR_IRQ:
+	case MACEISA_SERIAL2_TDMAPR_IRQ:
+		/* edge triggered */
+		spin_lock_irqsave(&ip32_irq_lock, flags);
+		mace_int = mace->perif.ctrl.istat;
+		mace_int &= ~(1 << (irq - 33));
+		mace->perif.ctrl.istat = mace_int;
+		spin_unlock_irqrestore(&ip32_irq_lock, flags);
+		break;
+	}
+	disable_maceisa_irq(irq);
+}
+
+static void end_maceisa_irq(unsigned irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		enable_maceisa_irq(irq);
+}
+
+#define shutdown_maceisa_irq disable_maceisa_irq
+
+static struct hw_interrupt_type ip32_maceisa_interrupt = {
+	"IP32 MACE ISA",
+	startup_maceisa_irq,
+	shutdown_maceisa_irq,
+	enable_maceisa_irq,
+	disable_maceisa_irq,
+	mask_and_ack_maceisa_irq,
+	end_maceisa_irq,
+	NULL
+};
+
+/* This is used for regular non-ISA, non-PCI MACE interrupts.  That means
+ * bits 0-3 and 7 in the CRIME register.
+ */
+
+static void enable_mace_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ip32_irq_lock, flags);
+	crime_mask |= 1 << (irq - 1);
+	crime->imask = crime_mask;
+	spin_unlock_irqrestore(&ip32_irq_lock, flags);
+}
+
+static unsigned int startup_mace_irq(unsigned int irq)
+{
+	enable_mace_irq(irq);
+	return 0;
+}
+
+static void disable_mace_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ip32_irq_lock, flags);
+	crime_mask &= ~(1 << (irq - 1));
+	crime->imask = crime_mask;
+	flush_crime_bus();
+	spin_unlock_irqrestore(&ip32_irq_lock, flags);
+}
+
+static void end_mace_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_mace_irq(irq);
+}
+
+#define shutdown_mace_irq disable_mace_irq
+#define mask_and_ack_mace_irq disable_mace_irq
+
+static struct hw_interrupt_type ip32_mace_interrupt = {
+	"IP32 MACE",
+	startup_mace_irq,
+	shutdown_mace_irq,
+	enable_mace_irq,
+	disable_mace_irq,
+	mask_and_ack_mace_irq,
+	end_mace_irq,
+	NULL
+};
+
+static void ip32_unknown_interrupt(struct pt_regs *regs)
+{
+	printk ("Unknown interrupt occurred!\n");
+	printk ("cp0_status: %08x\n", read_c0_status());
+	printk ("cp0_cause: %08x\n", read_c0_cause());
+	printk ("CRIME intr mask: %016lx\n", crime->imask);
+	printk ("CRIME intr status: %016lx\n", crime->istat);
+	printk ("CRIME hardware intr register: %016lx\n", crime->hard_int);
+	printk ("MACE ISA intr mask: %08lx\n", mace->perif.ctrl.imask);
+	printk ("MACE ISA intr status: %08lx\n", mace->perif.ctrl.istat);
+	printk ("MACE PCI control register: %08x\n", mace->pci.control);
+
+	printk("Register dump:\n");
+	show_regs(regs);
+
+	printk("Please mail this report to linux-mips@linux-mips.org\n");
+	printk("Spinning...");
+	while(1) ;
+}
+
+/* CRIME 1.1 appears to deliver all interrupts to this one pin. */
+/* change this to loop over all edge-triggered irqs, exception masked out ones */
+void ip32_irq0(struct pt_regs *regs)
+{
+	uint64_t crime_int;
+	int irq = 0;
+
+	crime_int = crime->istat & crime_mask;
+	irq = ffs(crime_int);
+	crime_int = 1 << (irq - 1);
+
+	if (crime_int & CRIME_MACEISA_INT_MASK) {
+		unsigned long mace_int = mace->perif.ctrl.istat;
+		irq = ffs(mace_int & maceisa_mask) + 32;
+	}
+	DBG("*irq %u*\n", irq);
+	do_IRQ(irq, regs);
+}
+
+void ip32_irq1(struct pt_regs *regs)
+{
+	ip32_unknown_interrupt(regs);
+}
+
+void ip32_irq2(struct pt_regs *regs)
+{
+	ip32_unknown_interrupt(regs);
+}
+
+void ip32_irq3(struct pt_regs *regs)
+{
+	ip32_unknown_interrupt(regs);
+}
+
+void ip32_irq4(struct pt_regs *regs)
+{
+	ip32_unknown_interrupt(regs);
+}
+
+void ip32_irq5(struct pt_regs *regs)
+{
+	ll_timer_interrupt(IP32_R4K_TIMER_IRQ, regs);
+}
+
+void __init arch_init_irq(void)
+{
+	unsigned int irq;
+
+	/* Install our interrupt handler, then clear and disable all
+	 * CRIME and MACE interrupts. */
+	crime->imask = 0;
+	crime->hard_int = 0;
+	crime->soft_int = 0;
+	mace->perif.ctrl.istat = 0;
+	mace->perif.ctrl.imask = 0;
+	set_except_vector(0, ip32_handle_int);
+
+	for (irq = 0; irq <= IP32_IRQ_MAX; irq++) {
+		hw_irq_controller *controller;
+
+		if (irq == IP32_R4K_TIMER_IRQ)
+			controller = &ip32_cpu_interrupt;
+		else if (irq <= MACE_PCI_BRIDGE_IRQ && irq >= MACE_VID_IN1_IRQ)
+			controller = &ip32_mace_interrupt;
+		else if (irq <= MACEPCI_SHARED2_IRQ && irq >= MACEPCI_SCSI0_IRQ)
+			controller = &ip32_macepci_interrupt;
+		else if (irq <= CRIME_VICE_IRQ && irq >= CRIME_GBE0_IRQ)
+			controller = &ip32_crime_interrupt;
+		else
+			controller = &ip32_maceisa_interrupt;
+
+		irq_desc[irq].status = IRQ_DISABLED;
+		irq_desc[irq].action = 0;
+		irq_desc[irq].depth = 0;
+		irq_desc[irq].handler = controller;
+	}
+	setup_irq(CRIME_MEMERR_IRQ, &memerr_irq);
+	setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq);
+
+#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
+	change_c0_status(ST0_IM, ALLINTS);
+}
diff --git a/arch/mips/sgi-ip32/ip32-memory.c b/arch/mips/sgi-ip32/ip32-memory.c
new file mode 100644
index 0000000..fc76ca9
--- /dev/null
+++ b/arch/mips/sgi-ip32/ip32-memory.c
@@ -0,0 +1,49 @@
+/*
+ * 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) 2003 Keith M Wesolowski
+ * Copyright (C) 2005 Ilya A. Volynets (Total Knowledge)
+ */
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+
+#include <asm/ip32/crime.h>
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+
+extern void crime_init(void);
+
+void __init prom_meminit (void)
+{
+	u64 base, size;
+	int bank;
+
+	crime_init();
+
+	for (bank=0; bank < CRIME_MAXBANKS; bank++) {
+		u64 bankctl = crime->bank_ctrl[bank];
+		base = (bankctl & CRIME_MEM_BANK_CONTROL_ADDR) << 25;
+		if (bank != 0 && base == 0)
+			continue;
+		size = (bankctl & CRIME_MEM_BANK_CONTROL_SDRAM_SIZE) ? 128 : 32;
+		size <<= 20;
+		if (base + size > (256 << 20))
+			base += CRIME_HI_MEM_BASE;
+
+		printk("CRIME MC: bank %u base 0x%016lx size %luMB\n",
+			bank, base, size);
+		add_memory_region (base, size, BOOT_MEM_RAM);
+	}
+}
+
+
+unsigned long __init prom_free_prom_memory (void)
+{
+	return 0;
+}
diff --git a/arch/mips/sgi-ip32/ip32-reset.c b/arch/mips/sgi-ip32/ip32-reset.c
new file mode 100644
index 0000000..281f090
--- /dev/null
+++ b/arch/mips/sgi-ip32/ip32-reset.c
@@ -0,0 +1,202 @@
+/*
+ * 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) 2001 Keith M Wesolowski
+ * Copyright (C) 2001 Paul Mundt
+ * Copyright (C) 2003 Guido Guenther <agx@sigxcpu.org>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/notifier.h>
+#include <linux/delay.h>
+#include <linux/ds17287rtc.h>
+#include <linux/interrupt.h>
+
+#include <asm/addrspace.h>
+#include <asm/irq.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <asm/wbflush.h>
+#include <asm/ip32/mace.h>
+#include <asm/ip32/crime.h>
+#include <asm/ip32/ip32_ints.h>
+
+#define POWERDOWN_TIMEOUT	120
+/*
+ * Blink frequency during reboot grace period and when paniced.
+ */
+#define POWERDOWN_FREQ		(HZ / 4)
+#define PANIC_FREQ		(HZ / 8)
+
+static struct timer_list power_timer, blink_timer, debounce_timer;
+static int has_paniced, shuting_down;
+
+static void ip32_machine_restart(char *command) __attribute__((noreturn));
+static void ip32_machine_halt(void) __attribute__((noreturn));
+static void ip32_machine_power_off(void) __attribute__((noreturn));
+
+static void ip32_machine_restart(char *cmd)
+{
+	crime->control = CRIME_CONTROL_HARD_RESET;
+	while (1);
+}
+
+static inline void ip32_machine_halt(void)
+{
+	ip32_machine_power_off();
+}
+
+static void ip32_machine_power_off(void)
+{
+	volatile unsigned char reg_a, xctrl_a, xctrl_b;
+
+	disable_irq(MACEISA_RTC_IRQ);
+	reg_a = CMOS_READ(RTC_REG_A);
+
+	/* setup for kickstart & wake-up (DS12287 Ref. Man. p. 19) */
+	reg_a &= ~DS_REGA_DV2;
+	reg_a |= DS_REGA_DV1;
+
+	CMOS_WRITE(reg_a | DS_REGA_DV0, RTC_REG_A);
+	wbflush();
+	xctrl_b = CMOS_READ(DS_B1_XCTRL4B)
+		   | DS_XCTRL4B_ABE | DS_XCTRL4B_KFE;
+	CMOS_WRITE(xctrl_b, DS_B1_XCTRL4B);
+	xctrl_a = CMOS_READ(DS_B1_XCTRL4A) & ~DS_XCTRL4A_IFS;
+	CMOS_WRITE(xctrl_a, DS_B1_XCTRL4A);
+	wbflush();
+	/* adios amigos... */
+	CMOS_WRITE(xctrl_a | DS_XCTRL4A_PAB, DS_B1_XCTRL4A);
+	CMOS_WRITE(reg_a, RTC_REG_A);
+	wbflush();
+	while (1);
+}
+
+static void power_timeout(unsigned long data)
+{
+	ip32_machine_power_off();
+}
+
+static void blink_timeout(unsigned long data)
+{
+	unsigned long led = mace->perif.ctrl.misc ^ MACEISA_LED_RED;
+	mace->perif.ctrl.misc = led;
+	mod_timer(&blink_timer, jiffies + data);
+}
+
+static void debounce(unsigned long data)
+{
+	volatile unsigned char reg_a, reg_c, xctrl_a;
+
+	reg_c = CMOS_READ(RTC_INTR_FLAGS);
+	CMOS_WRITE(reg_a | DS_REGA_DV0, RTC_REG_A);
+	wbflush();
+	xctrl_a = CMOS_READ(DS_B1_XCTRL4A);
+	if ((xctrl_a & DS_XCTRL4A_IFS) || (reg_c & RTC_IRQF )) {
+		/* Interrupt still being sent. */
+		debounce_timer.expires = jiffies + 50;
+		add_timer(&debounce_timer);
+
+		/* clear interrupt source */
+		CMOS_WRITE(xctrl_a & ~DS_XCTRL4A_IFS, DS_B1_XCTRL4A);
+		CMOS_WRITE(reg_a & ~DS_REGA_DV0, RTC_REG_A);
+		return;
+	}
+	CMOS_WRITE(reg_a & ~DS_REGA_DV0, RTC_REG_A);
+
+	if (has_paniced)
+		ip32_machine_restart(NULL);
+
+	enable_irq(MACEISA_RTC_IRQ);
+}
+
+static inline void ip32_power_button(void)
+{
+	if (has_paniced)
+		return;
+
+	if (shuting_down || kill_proc(1, SIGINT, 1)) {
+		/* No init process or button pressed twice.  */
+		ip32_machine_power_off();
+	}
+
+	shuting_down = 1;
+	blink_timer.data = POWERDOWN_FREQ;
+	blink_timeout(POWERDOWN_FREQ);
+
+	init_timer(&power_timer);
+	power_timer.function = power_timeout;
+	power_timer.expires = jiffies + POWERDOWN_TIMEOUT * HZ;
+	add_timer(&power_timer);
+}
+
+static irqreturn_t ip32_rtc_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+	volatile unsigned char reg_c;
+
+	reg_c = CMOS_READ(RTC_INTR_FLAGS);
+	if (!(reg_c & RTC_IRQF)) {
+		printk(KERN_WARNING 
+			"%s: RTC IRQ without RTC_IRQF\n", __FUNCTION__);
+	}
+	/* Wait until interrupt goes away */
+	disable_irq(MACEISA_RTC_IRQ);
+	init_timer(&debounce_timer);
+	debounce_timer.function = debounce;
+	debounce_timer.expires = jiffies + 50;
+	add_timer(&debounce_timer);
+
+	printk(KERN_DEBUG "Power button pressed\n");
+	ip32_power_button();
+	return IRQ_HANDLED;
+}
+
+static int panic_event(struct notifier_block *this, unsigned long event,
+		       void *ptr)
+{
+	unsigned long led;
+
+	if (has_paniced)
+		return NOTIFY_DONE;
+	has_paniced = 1;
+
+	/* turn off the green LED */
+	led = mace->perif.ctrl.misc | MACEISA_LED_GREEN;
+	mace->perif.ctrl.misc = led;
+
+	blink_timer.data = PANIC_FREQ;
+	blink_timeout(PANIC_FREQ);
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block panic_block = {
+	.notifier_call = panic_event,
+};
+
+static __init int ip32_reboot_setup(void)
+{
+	/* turn on the green led only */
+	unsigned long led = mace->perif.ctrl.misc;
+	led |= MACEISA_LED_RED;
+	led &= ~MACEISA_LED_GREEN;
+	mace->perif.ctrl.misc = led;
+
+	_machine_restart = ip32_machine_restart;
+	_machine_halt = ip32_machine_halt;
+	_machine_power_off = ip32_machine_power_off;
+
+	init_timer(&blink_timer);
+	blink_timer.function = blink_timeout;
+	notifier_chain_register(&panic_notifier_list, &panic_block);
+
+	request_irq(MACEISA_RTC_IRQ, ip32_rtc_int, 0, "rtc", NULL);
+
+	return 0;
+}
+
+subsys_initcall(ip32_reboot_setup);
diff --git a/arch/mips/sgi-ip32/ip32-setup.c b/arch/mips/sgi-ip32/ip32-setup.c
new file mode 100644
index 0000000..8d270be
--- /dev/null
+++ b/arch/mips/sgi-ip32/ip32-setup.c
@@ -0,0 +1,159 @@
+/*
+ * IP32 basic setup
+ *
+ * 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) 2000 Harald Koerfgen
+ * Copyright (C) 2002, 2003, 2005 Ilya A. Volynets
+ */
+#include <linux/config.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/mc146818rtc.h>
+#include <linux/param.h>
+#include <linux/sched.h>
+
+#include <asm/bootinfo.h>
+#include <asm/mc146818-time.h>
+#include <asm/mipsregs.h>
+#include <asm/mmu_context.h>
+#include <asm/sgialib.h>
+#include <asm/time.h>
+#include <asm/traps.h>
+#include <asm/io.h>
+#include <asm/ip32/crime.h>
+#include <asm/ip32/mace.h>
+#include <asm/ip32/ip32_ints.h>
+
+extern void ip32_be_init(void);
+extern void crime_init(void);
+
+#ifdef CONFIG_SGI_O2MACE_ETH
+/*
+ * This is taken care of in here 'cause they say using Arc later on is
+ * problematic
+ */
+extern char o2meth_eaddr[8];
+static inline unsigned char str2hexnum(unsigned char c)
+{
+	if (c >= '0' && c <= '9')
+		return c - '0';
+	if (c >= 'a' && c <= 'f')
+		return c - 'a' + 10;
+	return 0; /* foo */
+}
+
+static inline void str2eaddr(unsigned char *ea, unsigned char *str)
+{
+	int i;
+
+	for (i = 0; i < 6; i++) {
+		unsigned char num;
+
+		if(*str == ':')
+			str++;
+		num = str2hexnum(*str++) << 4;
+		num |= (str2hexnum(*str++));
+		ea[i] = num;
+	}
+}
+#endif
+
+#ifdef CONFIG_SERIAL_8250
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+extern int early_serial_setup(struct uart_port *port);
+
+#define STD_COM_FLAGS (ASYNC_SKIP_TEST)
+#define BASE_BAUD (1843200 / 16)
+
+#endif /* CONFIG_SERIAL_8250 */
+
+/* An arbitrary time; this can be decreased if reliability looks good */
+#define WAIT_MS 10
+
+void __init ip32_time_init(void)
+{
+	printk(KERN_INFO "Calibrating system timer... ");
+	write_c0_count(0);
+	crime->timer = 0;
+	while (crime->timer < CRIME_MASTER_FREQ * WAIT_MS / 1000) ;
+	mips_hpt_frequency = read_c0_count() * 1000 / WAIT_MS;
+	printk("%d MHz CPU detected\n", mips_hpt_frequency * 2 / 1000000);
+}
+
+void __init ip32_timer_setup(struct irqaction *irq)
+{
+	irq->handler = no_action;
+	setup_irq(IP32_R4K_TIMER_IRQ, irq);
+}
+
+static int __init ip32_setup(void)
+{
+	board_be_init = ip32_be_init;
+
+	rtc_get_time = mc146818_get_cmos_time;
+	rtc_set_mmss = mc146818_set_rtc_mmss;
+
+	board_time_init = ip32_time_init;
+	board_timer_setup = ip32_timer_setup;
+
+#ifdef CONFIG_SERIAL_8250
+ 	{
+		static struct uart_port o2_serial[2];
+
+		memset(o2_serial, 0, sizeof(o2_serial));
+		o2_serial[0].type	= PORT_16550A;
+		o2_serial[0].line	= 0;
+		o2_serial[0].irq	= MACEISA_SERIAL1_IRQ;
+		o2_serial[0].flags	= STD_COM_FLAGS;
+		o2_serial[0].uartclk	= BASE_BAUD * 16;
+		o2_serial[0].iotype	= UPIO_MEM;
+		o2_serial[0].membase	= (char *)&mace->isa.serial1;
+		o2_serial[0].fifosize	= 14;
+                /* How much to shift register offset by. Each UART register
+		 * is replicated over 256 byte space */
+		o2_serial[0].regshift	= 8;
+		o2_serial[1].type	= PORT_16550A;
+		o2_serial[1].line	= 1;
+		o2_serial[1].irq	= MACEISA_SERIAL2_IRQ;
+		o2_serial[1].flags	= STD_COM_FLAGS;
+		o2_serial[1].uartclk	= BASE_BAUD * 16;
+		o2_serial[1].iotype	= UPIO_MEM;
+		o2_serial[1].membase	= (char *)&mace->isa.serial2;
+		o2_serial[1].fifosize	= 14;
+		o2_serial[1].regshift	= 8;
+
+		early_serial_setup(&o2_serial[0]);
+		early_serial_setup(&o2_serial[1]);
+	}
+#endif
+#ifdef CONFIG_SGI_O2MACE_ETH
+	{
+		char *mac = ArcGetEnvironmentVariable("eaddr");
+		str2eaddr(o2meth_eaddr, mac);
+	}
+#endif
+
+#if defined(CONFIG_SERIAL_CORE_CONSOLE)
+	{
+		char* con = ArcGetEnvironmentVariable("console");
+		if (con && *con == 'd') {
+			static char options[8];
+			char *baud = ArcGetEnvironmentVariable("dbaud");
+			if (baud)
+				strcpy(options, baud);
+			add_preferred_console("ttyS", *(con + 1) == '2' ? 1 : 0,
+					      baud ? options : NULL);
+		}
+	}
+#endif
+
+	return 0;
+}
+
+early_initcall(ip32_setup);
diff --git a/arch/mips/sibyte/cfe/Makefile b/arch/mips/sibyte/cfe/Makefile
new file mode 100644
index 0000000..059d84a
--- /dev/null
+++ b/arch/mips/sibyte/cfe/Makefile
@@ -0,0 +1,3 @@
+lib-y					= cfe_api.o setup.o
+lib-$(CONFIG_SMP)			+= smp.o
+lib-$(CONFIG_SIBYTE_CFE_CONSOLE)	+= console.o
diff --git a/arch/mips/sibyte/cfe/cfe_api.c b/arch/mips/sibyte/cfe/cfe_api.c
new file mode 100644
index 0000000..c021360
--- /dev/null
+++ b/arch/mips/sibyte/cfe/cfe_api.c
@@ -0,0 +1,502 @@
+/*
+ * Copyright (C) 2000, 2001, 2002 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*  *********************************************************************
+    *
+    *  Broadcom Common Firmware Environment (CFE)
+    *
+    *  Device Function stubs			File: cfe_api.c
+    *
+    *  This module contains device function stubs (small routines to
+    *  call the standard "iocb" interface entry point to CFE).
+    *  There should be one routine here per iocb function call.
+    *
+    *  Authors:  Mitch Lichtenberg, Chris Demetriou
+    *
+    ********************************************************************* */
+
+#include "cfe_api.h"
+#include "cfe_api_int.h"
+
+/* Cast from a native pointer to a cfe_xptr_t and back.	 */
+#define XPTR_FROM_NATIVE(n)	((cfe_xptr_t) (intptr_t) (n))
+#define NATIVE_FROM_XPTR(x)	((void *) (intptr_t) (x))
+
+#ifdef CFE_API_IMPL_NAMESPACE
+#define cfe_iocb_dispatch(a)		__cfe_iocb_dispatch(a)
+#endif
+int cfe_iocb_dispatch(cfe_xiocb_t * xiocb);
+
+#if defined(CFE_API_common) || defined(CFE_API_ALL)
+/*
+ * Declare the dispatch function with args of "intptr_t".
+ * This makes sure whatever model we're compiling in
+ * puts the pointers in a single register.  For example,
+ * combining -mlong64 and -mips1 or -mips2 would lead to
+ * trouble, since the handle and IOCB pointer will be
+ * passed in two registers each, and CFE expects one.
+ */
+
+static int (*cfe_dispfunc) (intptr_t handle, intptr_t xiocb) = 0;
+static cfe_xuint_t cfe_handle = 0;
+
+int cfe_init(cfe_xuint_t handle, cfe_xuint_t ept)
+{
+	cfe_dispfunc = NATIVE_FROM_XPTR(ept);
+	cfe_handle = handle;
+	return 0;
+}
+
+int cfe_iocb_dispatch(cfe_xiocb_t * xiocb)
+{
+	if (!cfe_dispfunc)
+		return -1;
+	return (*cfe_dispfunc) ((intptr_t) cfe_handle, (intptr_t) xiocb);
+}
+#endif				/* CFE_API_common || CFE_API_ALL */
+
+#if defined(CFE_API_close) || defined(CFE_API_ALL)
+int cfe_close(int handle)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_DEV_CLOSE;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = handle;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = 0;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	return xiocb.xiocb_status;
+
+}
+#endif				/* CFE_API_close || CFE_API_ALL */
+
+#if defined(CFE_API_cpu_start) || defined(CFE_API_ALL)
+int cfe_cpu_start(int cpu, void (*fn) (void), long sp, long gp, long a1)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_cpuctl_t);
+	xiocb.plist.xiocb_cpuctl.cpu_number = cpu;
+	xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_START;
+	xiocb.plist.xiocb_cpuctl.gp_val = gp;
+	xiocb.plist.xiocb_cpuctl.sp_val = sp;
+	xiocb.plist.xiocb_cpuctl.a1_val = a1;
+	xiocb.plist.xiocb_cpuctl.start_addr = (long) fn;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	return xiocb.xiocb_status;
+}
+#endif				/* CFE_API_cpu_start || CFE_API_ALL */
+
+#if defined(CFE_API_cpu_stop) || defined(CFE_API_ALL)
+int cfe_cpu_stop(int cpu)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_cpuctl_t);
+	xiocb.plist.xiocb_cpuctl.cpu_number = cpu;
+	xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_STOP;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	return xiocb.xiocb_status;
+}
+#endif				/* CFE_API_cpu_stop || CFE_API_ALL */
+
+#if defined(CFE_API_enumenv) || defined(CFE_API_ALL)
+int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_ENV_SET;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_envbuf_t);
+	xiocb.plist.xiocb_envbuf.enum_idx = idx;
+	xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name);
+	xiocb.plist.xiocb_envbuf.name_length = namelen;
+	xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val);
+	xiocb.plist.xiocb_envbuf.val_length = vallen;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	return xiocb.xiocb_status;
+}
+#endif				/* CFE_API_enumenv || CFE_API_ALL */
+
+#if defined(CFE_API_enummem) || defined(CFE_API_ALL)
+int
+cfe_enummem(int idx, int flags, cfe_xuint_t * start, cfe_xuint_t * length,
+	    cfe_xuint_t * type)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_FW_MEMENUM;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = flags;
+	xiocb.xiocb_psize = sizeof(xiocb_meminfo_t);
+	xiocb.plist.xiocb_meminfo.mi_idx = idx;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	if (xiocb.xiocb_status < 0)
+		return xiocb.xiocb_status;
+
+	*start = xiocb.plist.xiocb_meminfo.mi_addr;
+	*length = xiocb.plist.xiocb_meminfo.mi_size;
+	*type = xiocb.plist.xiocb_meminfo.mi_type;
+
+	return 0;
+}
+#endif				/* CFE_API_enummem || CFE_API_ALL */
+
+#if defined(CFE_API_exit) || defined(CFE_API_ALL)
+int cfe_exit(int warm, int status)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_FW_RESTART;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = warm ? CFE_FLG_WARMSTART : 0;
+	xiocb.xiocb_psize = sizeof(xiocb_exitstat_t);
+	xiocb.plist.xiocb_exitstat.status = status;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	return xiocb.xiocb_status;
+}
+#endif				/* CFE_API_exit || CFE_API_ALL */
+
+#if defined(CFE_API_flushcache) || defined(CFE_API_ALL)
+int cfe_flushcache(int flg)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_FW_FLUSHCACHE;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = flg;
+	xiocb.xiocb_psize = 0;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	return xiocb.xiocb_status;
+}
+#endif				/* CFE_API_flushcache || CFE_API_ALL */
+
+#if defined(CFE_API_getdevinfo) || defined(CFE_API_ALL)
+int cfe_getdevinfo(char *name)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_DEV_GETINFO;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_buffer_t);
+	xiocb.plist.xiocb_buffer.buf_offset = 0;
+	xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name);
+	xiocb.plist.xiocb_buffer.buf_length = cfe_strlen(name);
+
+	cfe_iocb_dispatch(&xiocb);
+
+	if (xiocb.xiocb_status < 0)
+		return xiocb.xiocb_status;
+	return xiocb.plist.xiocb_buffer.buf_devflags;
+}
+#endif				/* CFE_API_getdevinfo || CFE_API_ALL */
+
+#if defined(CFE_API_getenv) || defined(CFE_API_ALL)
+int cfe_getenv(char *name, char *dest, int destlen)
+{
+	cfe_xiocb_t xiocb;
+
+	*dest = 0;
+
+	xiocb.xiocb_fcode = CFE_CMD_ENV_GET;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_envbuf_t);
+	xiocb.plist.xiocb_envbuf.enum_idx = 0;
+	xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name);
+	xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name);
+	xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(dest);
+	xiocb.plist.xiocb_envbuf.val_length = destlen;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	return xiocb.xiocb_status;
+}
+#endif				/* CFE_API_getenv || CFE_API_ALL */
+
+#if defined(CFE_API_getfwinfo) || defined(CFE_API_ALL)
+int cfe_getfwinfo(cfe_fwinfo_t * info)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_FW_GETINFO;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_fwinfo_t);
+
+	cfe_iocb_dispatch(&xiocb);
+
+	if (xiocb.xiocb_status < 0)
+		return xiocb.xiocb_status;
+
+	info->fwi_version = xiocb.plist.xiocb_fwinfo.fwi_version;
+	info->fwi_totalmem = xiocb.plist.xiocb_fwinfo.fwi_totalmem;
+	info->fwi_flags = xiocb.plist.xiocb_fwinfo.fwi_flags;
+	info->fwi_boardid = xiocb.plist.xiocb_fwinfo.fwi_boardid;
+	info->fwi_bootarea_va = xiocb.plist.xiocb_fwinfo.fwi_bootarea_va;
+	info->fwi_bootarea_pa = xiocb.plist.xiocb_fwinfo.fwi_bootarea_pa;
+	info->fwi_bootarea_size =
+	    xiocb.plist.xiocb_fwinfo.fwi_bootarea_size;
+#if 0
+	info->fwi_reserved1 = xiocb.plist.xiocb_fwinfo.fwi_reserved1;
+	info->fwi_reserved2 = xiocb.plist.xiocb_fwinfo.fwi_reserved2;
+	info->fwi_reserved3 = xiocb.plist.xiocb_fwinfo.fwi_reserved3;
+#endif
+
+	return 0;
+}
+#endif				/* CFE_API_getfwinfo || CFE_API_ALL */
+
+#if defined(CFE_API_getstdhandle) || defined(CFE_API_ALL)
+int cfe_getstdhandle(int flg)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_DEV_GETHANDLE;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = flg;
+	xiocb.xiocb_psize = 0;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	if (xiocb.xiocb_status < 0)
+		return xiocb.xiocb_status;
+	return xiocb.xiocb_handle;
+}
+#endif				/* CFE_API_getstdhandle || CFE_API_ALL */
+
+#if defined(CFE_API_getticks) || defined(CFE_API_ALL)
+int64_t
+#ifdef CFE_API_IMPL_NAMESPACE
+__cfe_getticks(void)
+#else
+cfe_getticks(void)
+#endif
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_FW_GETTIME;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_time_t);
+	xiocb.plist.xiocb_time.ticks = 0;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	return xiocb.plist.xiocb_time.ticks;
+
+}
+#endif				/* CFE_API_getticks || CFE_API_ALL */
+
+#if defined(CFE_API_inpstat) || defined(CFE_API_ALL)
+int cfe_inpstat(int handle)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_DEV_INPSTAT;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = handle;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_inpstat_t);
+	xiocb.plist.xiocb_inpstat.inp_status = 0;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	if (xiocb.xiocb_status < 0)
+		return xiocb.xiocb_status;
+	return xiocb.plist.xiocb_inpstat.inp_status;
+}
+#endif				/* CFE_API_inpstat || CFE_API_ALL */
+
+#if defined(CFE_API_ioctl) || defined(CFE_API_ALL)
+int
+cfe_ioctl(int handle, unsigned int ioctlnum, unsigned char *buffer,
+	  int length, int *retlen, cfe_xuint_t offset)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_DEV_IOCTL;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = handle;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_buffer_t);
+	xiocb.plist.xiocb_buffer.buf_offset = offset;
+	xiocb.plist.xiocb_buffer.buf_ioctlcmd = ioctlnum;
+	xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer);
+	xiocb.plist.xiocb_buffer.buf_length = length;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	if (retlen)
+		*retlen = xiocb.plist.xiocb_buffer.buf_retlen;
+	return xiocb.xiocb_status;
+}
+#endif				/* CFE_API_ioctl || CFE_API_ALL */
+
+#if defined(CFE_API_open) || defined(CFE_API_ALL)
+int cfe_open(char *name)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_DEV_OPEN;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_buffer_t);
+	xiocb.plist.xiocb_buffer.buf_offset = 0;
+	xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name);
+	xiocb.plist.xiocb_buffer.buf_length = cfe_strlen(name);
+
+	cfe_iocb_dispatch(&xiocb);
+
+	if (xiocb.xiocb_status < 0)
+		return xiocb.xiocb_status;
+	return xiocb.xiocb_handle;
+}
+#endif				/* CFE_API_open || CFE_API_ALL */
+
+#if defined(CFE_API_read) || defined(CFE_API_ALL)
+int cfe_read(int handle, unsigned char *buffer, int length)
+{
+	return cfe_readblk(handle, 0, buffer, length);
+}
+#endif				/* CFE_API_read || CFE_API_ALL */
+
+#if defined(CFE_API_readblk) || defined(CFE_API_ALL)
+int
+cfe_readblk(int handle, cfe_xint_t offset, unsigned char *buffer,
+	    int length)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_DEV_READ;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = handle;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_buffer_t);
+	xiocb.plist.xiocb_buffer.buf_offset = offset;
+	xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer);
+	xiocb.plist.xiocb_buffer.buf_length = length;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	if (xiocb.xiocb_status < 0)
+		return xiocb.xiocb_status;
+	return xiocb.plist.xiocb_buffer.buf_retlen;
+}
+#endif				/* CFE_API_readblk || CFE_API_ALL */
+
+#if defined(CFE_API_setenv) || defined(CFE_API_ALL)
+int cfe_setenv(char *name, char *val)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_ENV_SET;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_envbuf_t);
+	xiocb.plist.xiocb_envbuf.enum_idx = 0;
+	xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name);
+	xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name);
+	xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val);
+	xiocb.plist.xiocb_envbuf.val_length = cfe_strlen(val);
+
+	cfe_iocb_dispatch(&xiocb);
+
+	return xiocb.xiocb_status;
+}
+#endif				/* CFE_API_setenv || CFE_API_ALL */
+
+#if (defined(CFE_API_strlen) || defined(CFE_API_ALL)) \
+    && !defined(CFE_API_STRLEN_CUSTOM)
+int cfe_strlen(char *name)
+{
+	int count = 0;
+
+	while (*name++)
+		count++;
+
+	return count;
+}
+#endif				/* CFE_API_strlen || CFE_API_ALL */
+
+#if defined(CFE_API_write) || defined(CFE_API_ALL)
+int cfe_write(int handle, unsigned char *buffer, int length)
+{
+	return cfe_writeblk(handle, 0, buffer, length);
+}
+#endif				/* CFE_API_write || CFE_API_ALL */
+
+#if defined(CFE_API_writeblk) || defined(CFE_API_ALL)
+int
+cfe_writeblk(int handle, cfe_xint_t offset, unsigned char *buffer,
+	     int length)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_DEV_WRITE;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = handle;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_buffer_t);
+	xiocb.plist.xiocb_buffer.buf_offset = offset;
+	xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer);
+	xiocb.plist.xiocb_buffer.buf_length = length;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	if (xiocb.xiocb_status < 0)
+		return xiocb.xiocb_status;
+	return xiocb.plist.xiocb_buffer.buf_retlen;
+}
+#endif				/* CFE_API_writeblk || CFE_API_ALL */
diff --git a/arch/mips/sibyte/cfe/cfe_api.h b/arch/mips/sibyte/cfe/cfe_api.h
new file mode 100644
index 0000000..d8230cc
--- /dev/null
+++ b/arch/mips/sibyte/cfe/cfe_api.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2000, 2001, 2002 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*  *********************************************************************
+    *
+    *  Broadcom Common Firmware Environment (CFE)
+    *
+    *  Device function prototypes		File: cfe_api.h
+    *
+    *  This file contains declarations for doing callbacks to
+    *  cfe from an application.  It should be the only header
+    *  needed by the application to use this library
+    *
+    *  Authors:  Mitch Lichtenberg, Chris Demetriou
+    *
+    ********************************************************************* */
+
+#ifndef CFE_API_H
+#define CFE_API_H
+
+/*
+ * Apply customizations here for different OSes.  These need to:
+ *	* typedef uint64_t, int64_t, intptr_t, uintptr_t.
+ *	* define cfe_strlen() if use of an existing function is desired.
+ *	* define CFE_API_IMPL_NAMESPACE if API functions are to use
+ *	  names in the implementation namespace.
+ * Also, optionally, if the build environment does not do so automatically,
+ * CFE_API_* can be defined here as desired.
+ */
+/* Begin customization. */
+#include <linux/types.h>
+#include <linux/string.h>
+
+typedef long intptr_t;
+
+#define cfe_strlen strlen
+
+#define CFE_API_ALL
+#define CFE_API_STRLEN_CUSTOM
+/* End customization. */
+
+
+/*  *********************************************************************
+    *  Constants
+    ********************************************************************* */
+
+/* Seal indicating CFE's presence, passed to user program. */
+#define CFE_EPTSEAL 0x43464531
+
+#define CFE_MI_RESERVED	0	/* memory is reserved, do not use */
+#define CFE_MI_AVAILABLE 1	/* memory is available */
+
+#define CFE_FLG_WARMSTART     0x00000001
+#define CFE_FLG_FULL_ARENA    0x00000001
+#define CFE_FLG_ENV_PERMANENT 0x00000001
+
+#define CFE_CPU_CMD_START 1
+#define CFE_CPU_CMD_STOP 0
+
+#define CFE_STDHANDLE_CONSOLE	0
+
+#define CFE_DEV_NETWORK 	1
+#define CFE_DEV_DISK		2
+#define CFE_DEV_FLASH		3
+#define CFE_DEV_SERIAL		4
+#define CFE_DEV_CPU		5
+#define CFE_DEV_NVRAM		6
+#define CFE_DEV_CLOCK           7
+#define CFE_DEV_OTHER		8
+#define CFE_DEV_MASK		0x0F
+
+#define CFE_CACHE_FLUSH_D	1
+#define CFE_CACHE_INVAL_I	2
+#define CFE_CACHE_INVAL_D	4
+#define CFE_CACHE_INVAL_L2	8
+
+#define CFE_FWI_64BIT		0x00000001
+#define CFE_FWI_32BIT		0x00000002
+#define CFE_FWI_RELOC		0x00000004
+#define CFE_FWI_UNCACHED	0x00000008
+#define CFE_FWI_MULTICPU	0x00000010
+#define CFE_FWI_FUNCSIM		0x00000020
+#define CFE_FWI_RTLSIM		0x00000040
+
+typedef struct {
+	int64_t fwi_version;		/* major, minor, eco version */
+	int64_t fwi_totalmem;		/* total installed mem */
+	int64_t fwi_flags;		/* various flags */
+	int64_t fwi_boardid;		/* board ID */
+	int64_t fwi_bootarea_va;	/* VA of boot area */
+	int64_t fwi_bootarea_pa;	/* PA of boot area */
+	int64_t fwi_bootarea_size;	/* size of boot area */
+} cfe_fwinfo_t;
+
+
+/*
+ * cfe_strlen is handled specially: If already defined, it has been
+ * overridden in this environment with a standard strlen-like function.
+ */
+#ifdef cfe_strlen
+# define CFE_API_STRLEN_CUSTOM
+#else
+# ifdef CFE_API_IMPL_NAMESPACE
+#  define cfe_strlen(a)			__cfe_strlen(a)
+# endif
+int cfe_strlen(char *name);
+#endif
+
+/*
+ * Defines and prototypes for functions which take no arguments.
+ */
+#ifdef CFE_API_IMPL_NAMESPACE
+int64_t __cfe_getticks(void);
+#define cfe_getticks()			__cfe_getticks()
+#else
+int64_t cfe_getticks(void);
+#endif
+
+/*
+ * Defines and prototypes for the rest of the functions.
+ */
+#ifdef CFE_API_IMPL_NAMESPACE
+#define cfe_close(a)			__cfe_close(a)
+#define cfe_cpu_start(a,b,c,d,e)	__cfe_cpu_start(a,b,c,d,e)
+#define cfe_cpu_stop(a)			__cfe_cpu_stop(a)
+#define cfe_enumenv(a,b,d,e,f)		__cfe_enumenv(a,b,d,e,f)
+#define cfe_enummem(a,b,c,d,e)		__cfe_enummem(a,b,c,d,e)
+#define cfe_exit(a,b)			__cfe_exit(a,b)
+#define cfe_flushcache(a)		__cfe_cacheflush(a)
+#define cfe_getdevinfo(a)		__cfe_getdevinfo(a)
+#define cfe_getenv(a,b,c)		__cfe_getenv(a,b,c)
+#define cfe_getfwinfo(a)		__cfe_getfwinfo(a)
+#define cfe_getstdhandle(a)		__cfe_getstdhandle(a)
+#define cfe_init(a,b)			__cfe_init(a,b)
+#define cfe_inpstat(a)			__cfe_inpstat(a)
+#define cfe_ioctl(a,b,c,d,e,f)		__cfe_ioctl(a,b,c,d,e,f)
+#define cfe_open(a)			__cfe_open(a)
+#define cfe_read(a,b,c)			__cfe_read(a,b,c)
+#define cfe_readblk(a,b,c,d)		__cfe_readblk(a,b,c,d)
+#define cfe_setenv(a,b)			__cfe_setenv(a,b)
+#define cfe_write(a,b,c)		__cfe_write(a,b,c)
+#define cfe_writeblk(a,b,c,d)		__cfe_writeblk(a,b,c,d)
+#endif				/* CFE_API_IMPL_NAMESPACE */
+
+int cfe_close(int handle);
+int cfe_cpu_start(int cpu, void (*fn) (void), long sp, long gp, long a1);
+int cfe_cpu_stop(int cpu);
+int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen);
+int cfe_enummem(int idx, int flags, uint64_t * start, uint64_t * length,
+		uint64_t * type);
+int cfe_exit(int warm, int status);
+int cfe_flushcache(int flg);
+int cfe_getdevinfo(char *name);
+int cfe_getenv(char *name, char *dest, int destlen);
+int cfe_getfwinfo(cfe_fwinfo_t * info);
+int cfe_getstdhandle(int flg);
+int cfe_init(uint64_t handle, uint64_t ept);
+int cfe_inpstat(int handle);
+int cfe_ioctl(int handle, unsigned int ioctlnum, unsigned char *buffer,
+	      int length, int *retlen, uint64_t offset);
+int cfe_open(char *name);
+int cfe_read(int handle, unsigned char *buffer, int length);
+int cfe_readblk(int handle, int64_t offset, unsigned char *buffer,
+		int length);
+int cfe_setenv(char *name, char *val);
+int cfe_write(int handle, unsigned char *buffer, int length);
+int cfe_writeblk(int handle, int64_t offset, unsigned char *buffer,
+		 int length);
+
+#endif				/* CFE_API_H */
diff --git a/arch/mips/sibyte/cfe/cfe_api_int.h b/arch/mips/sibyte/cfe/cfe_api_int.h
new file mode 100644
index 0000000..f7e5a64
--- /dev/null
+++ b/arch/mips/sibyte/cfe/cfe_api_int.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2000, 2001, 2002 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*  *********************************************************************
+    *
+    *  Broadcom Common Firmware Environment (CFE)
+    *
+    *  Device function prototypes		File: cfe_api_int.h
+    *
+    *  This header defines all internal types and macros for the
+    *  library.  This is stuff that's not exported to an app
+    *  using the library.
+    *
+    *  Authors:  Mitch Lichtenberg, Chris Demetriou
+    *
+    ********************************************************************* */
+
+#ifndef CFE_API_INT_H
+#define CFE_API_INT_H
+
+/*  *********************************************************************
+    *  Constants
+    ********************************************************************* */
+
+#define CFE_CMD_FW_GETINFO	0
+#define CFE_CMD_FW_RESTART	1
+#define CFE_CMD_FW_BOOT		2
+#define CFE_CMD_FW_CPUCTL	3
+#define CFE_CMD_FW_GETTIME      4
+#define CFE_CMD_FW_MEMENUM	5
+#define CFE_CMD_FW_FLUSHCACHE	6
+
+#define CFE_CMD_DEV_GETHANDLE	9
+#define CFE_CMD_DEV_ENUM	10
+#define CFE_CMD_DEV_OPEN	11
+#define CFE_CMD_DEV_INPSTAT	12
+#define CFE_CMD_DEV_READ	13
+#define CFE_CMD_DEV_WRITE	14
+#define CFE_CMD_DEV_IOCTL	15
+#define CFE_CMD_DEV_CLOSE	16
+#define CFE_CMD_DEV_GETINFO	17
+
+#define CFE_CMD_ENV_ENUM	20
+#define CFE_CMD_ENV_GET		22
+#define CFE_CMD_ENV_SET		23
+#define CFE_CMD_ENV_DEL		24
+
+#define CFE_CMD_MAX		32
+
+#define CFE_CMD_VENDOR_USE	0x8000	/* codes above this are for customer use */
+
+/*  *********************************************************************
+    *  Structures
+    ********************************************************************* */
+
+typedef uint64_t cfe_xuint_t;
+typedef int64_t cfe_xint_t;
+typedef int64_t cfe_xptr_t;
+
+typedef struct xiocb_buffer_s {
+	cfe_xuint_t buf_offset;		/* offset on device (bytes) */
+	cfe_xptr_t  buf_ptr;		/* pointer to a buffer */
+	cfe_xuint_t buf_length;		/* length of this buffer */
+	cfe_xuint_t buf_retlen;		/* returned length (for read ops) */
+	cfe_xuint_t buf_ioctlcmd;	/* IOCTL command (used only for IOCTLs) */
+} xiocb_buffer_t;
+
+#define buf_devflags buf_ioctlcmd	/* returned device info flags */
+
+typedef struct xiocb_inpstat_s {
+	cfe_xuint_t inp_status;		/* 1 means input available */
+} xiocb_inpstat_t;
+
+typedef struct xiocb_envbuf_s {
+	cfe_xint_t enum_idx;		/* 0-based enumeration index */
+	cfe_xptr_t name_ptr;		/* name string buffer */
+	cfe_xint_t name_length;		/* size of name buffer */
+	cfe_xptr_t val_ptr;		/* value string buffer */
+	cfe_xint_t val_length;		/* size of value string buffer */
+} xiocb_envbuf_t;
+
+typedef struct xiocb_cpuctl_s {
+	cfe_xuint_t cpu_number;		/* cpu number to control */
+	cfe_xuint_t cpu_command;	/* command to issue to CPU */
+	cfe_xuint_t start_addr;		/* CPU start address */
+	cfe_xuint_t gp_val;		/* starting GP value */
+	cfe_xuint_t sp_val;		/* starting SP value */
+	cfe_xuint_t a1_val;		/* starting A1 value */
+} xiocb_cpuctl_t;
+
+typedef struct xiocb_time_s {
+	cfe_xint_t ticks;		/* current time in ticks */
+} xiocb_time_t;
+
+typedef struct xiocb_exitstat_s {
+	cfe_xint_t status;
+} xiocb_exitstat_t;
+
+typedef struct xiocb_meminfo_s {
+	cfe_xint_t mi_idx;		/* 0-based enumeration index */
+	cfe_xint_t mi_type;		/* type of memory block */
+	cfe_xuint_t mi_addr;		/* physical start address */
+	cfe_xuint_t mi_size;		/* block size */
+} xiocb_meminfo_t;
+
+typedef struct xiocb_fwinfo_s {
+	cfe_xint_t fwi_version;		/* major, minor, eco version */
+	cfe_xint_t fwi_totalmem;	/* total installed mem */
+	cfe_xint_t fwi_flags;		/* various flags */
+	cfe_xint_t fwi_boardid;		/* board ID */
+	cfe_xint_t fwi_bootarea_va;	/* VA of boot area */
+	cfe_xint_t fwi_bootarea_pa;	/* PA of boot area */
+	cfe_xint_t fwi_bootarea_size;	/* size of boot area */
+	cfe_xint_t fwi_reserved1;
+	cfe_xint_t fwi_reserved2;
+	cfe_xint_t fwi_reserved3;
+} xiocb_fwinfo_t;
+
+typedef struct cfe_xiocb_s {
+	cfe_xuint_t xiocb_fcode;	/* IOCB function code */
+	cfe_xint_t xiocb_status;	/* return status */
+	cfe_xint_t xiocb_handle;	/* file/device handle */
+	cfe_xuint_t xiocb_flags;	/* flags for this IOCB */
+	cfe_xuint_t xiocb_psize;	/* size of parameter list */
+	union {
+		xiocb_buffer_t xiocb_buffer;	/* buffer parameters */
+		xiocb_inpstat_t xiocb_inpstat;	/* input status parameters */
+		xiocb_envbuf_t xiocb_envbuf;	/* environment function parameters */
+		xiocb_cpuctl_t xiocb_cpuctl;	/* CPU control parameters */
+		xiocb_time_t xiocb_time;	/* timer parameters */
+		xiocb_meminfo_t xiocb_meminfo;	/* memory arena info parameters */
+		xiocb_fwinfo_t xiocb_fwinfo;	/* firmware information */
+		xiocb_exitstat_t xiocb_exitstat;	/* Exit Status */
+	} plist;
+} cfe_xiocb_t;
+
+#endif				/* CFE_API_INT_H */
diff --git a/arch/mips/sibyte/cfe/cfe_error.h b/arch/mips/sibyte/cfe/cfe_error.h
new file mode 100644
index 0000000..77eb493
--- /dev/null
+++ b/arch/mips/sibyte/cfe/cfe_error.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2000, 2001, 2002 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*  *********************************************************************
+    *  
+    *  Broadcom Common Firmware Environment (CFE)
+    *  
+    *  Error codes				File: cfe_error.h
+    *  
+    *  CFE's global error code list is here.
+    *  
+    *  Author:  Mitch Lichtenberg
+    *  
+    ********************************************************************* */
+
+
+#define CFE_OK			 0
+#define CFE_ERR                 -1	/* generic error */
+#define CFE_ERR_INV_COMMAND	-2
+#define CFE_ERR_EOF		-3
+#define CFE_ERR_IOERR		-4
+#define CFE_ERR_NOMEM		-5
+#define CFE_ERR_DEVNOTFOUND	-6
+#define CFE_ERR_DEVOPEN		-7
+#define CFE_ERR_INV_PARAM	-8
+#define CFE_ERR_ENVNOTFOUND	-9
+#define CFE_ERR_ENVREADONLY	-10
+
+#define CFE_ERR_NOTELF		-11
+#define CFE_ERR_NOT32BIT 	-12
+#define CFE_ERR_WRONGENDIAN 	-13
+#define CFE_ERR_BADELFVERS 	-14
+#define CFE_ERR_NOTMIPS 	-15
+#define CFE_ERR_BADELFFMT 	-16
+#define CFE_ERR_BADADDR 	-17
+
+#define CFE_ERR_FILENOTFOUND	-18
+#define CFE_ERR_UNSUPPORTED	-19
+
+#define CFE_ERR_HOSTUNKNOWN	-20
+
+#define CFE_ERR_TIMEOUT		-21
+
+#define CFE_ERR_PROTOCOLERR	-22
+
+#define CFE_ERR_NETDOWN		-23
+#define CFE_ERR_NONAMESERVER	-24
+
+#define CFE_ERR_NOHANDLES	-25
+#define CFE_ERR_ALREADYBOUND	-26
+
+#define CFE_ERR_CANNOTSET	-27
+#define CFE_ERR_NOMORE		-28
+#define CFE_ERR_BADFILESYS	-29
+#define CFE_ERR_FSNOTAVAIL	-30
+
+#define CFE_ERR_INVBOOTBLOCK	-31
+#define CFE_ERR_WRONGDEVTYPE	-32
+#define CFE_ERR_BBCHECKSUM	-33
+#define CFE_ERR_BOOTPROGCHKSUM	-34
+
+#define CFE_ERR_LDRNOTAVAIL	-35
+
+#define CFE_ERR_NOTREADY	-36
+
+#define CFE_ERR_GETMEM          -37
+#define CFE_ERR_SETMEM          -38
+
+#define CFE_ERR_NOTCONN		-39
+#define CFE_ERR_ADDRINUSE	-40
diff --git a/arch/mips/sibyte/cfe/console.c b/arch/mips/sibyte/cfe/console.c
new file mode 100644
index 0000000..53a5c1e
--- /dev/null
+++ b/arch/mips/sibyte/cfe/console.c
@@ -0,0 +1,80 @@
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/console.h>
+
+#include <asm/sibyte/board.h>
+
+#include "cfe_api.h"
+#include "cfe_error.h"
+
+extern int cfe_cons_handle;
+
+static void cfe_console_write(struct console *cons, const char *str,
+		       unsigned int count)
+{
+	int i, last, written;
+
+	for (i=0,last=0; i<count; i++) {
+		if (!str[i])
+			/* XXXKW can/should this ever happen? */
+			return;
+		if (str[i] == '\n') {
+			do {
+				written = cfe_write(cfe_cons_handle, &str[last], i-last);
+				if (written < 0)
+					;
+				last += written;
+			} while (last < i);
+			while (cfe_write(cfe_cons_handle, "\r", 1) <= 0)
+				;
+		}
+	}
+	if (last != count) {
+		do {
+			written = cfe_write(cfe_cons_handle, &str[last], count-last);
+			if (written < 0)
+				;
+			last += written;
+		} while (last < count);
+	}
+			
+}
+
+static int cfe_console_setup(struct console *cons, char *str)
+{
+	char consdev[32];
+	/* XXXKW think about interaction with 'console=' cmdline arg */
+	/* If none of the console options are configured, the build will break. */
+	if (cfe_getenv("BOOT_CONSOLE", consdev, 32) >= 0) {
+#ifdef CONFIG_SIBYTE_SB1250_DUART
+		if (!strcmp(consdev, "uart0")) {
+			setleds("u0cn");
+		} else if (!strcmp(consdev, "uart1")) {
+			setleds("u1cn");
+#endif
+#ifdef CONFIG_VGA_CONSOLE
+		} else if (!strcmp(consdev, "pcconsole0")) {
+			setleds("pccn");
+#endif
+		} else
+			return -ENODEV;
+	}
+	return 0;
+}
+
+static struct console sb1250_cfe_cons = {
+	.name		= "cfe",
+	.write		= cfe_console_write,
+	.setup		= cfe_console_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= -1,
+};
+
+static int __init sb1250_cfe_console_init(void)
+{
+	register_console(&sb1250_cfe_cons);
+	return 0;
+}
+
+console_initcall(sb1250_cfe_console_init);
diff --git a/arch/mips/sibyte/cfe/setup.c b/arch/mips/sibyte/cfe/setup.c
new file mode 100644
index 0000000..d6d0364
--- /dev/null
+++ b/arch/mips/sibyte/cfe/setup.c
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/linkage.h>
+#include <linux/mm.h>
+#include <linux/blkdev.h>
+#include <linux/bootmem.h>
+#include <linux/smp.h>
+
+#include <asm/bootinfo.h>
+#include <asm/reboot.h>
+#include <asm/sibyte/board.h>
+
+#include "cfe_api.h"
+#include "cfe_error.h"
+
+/* Max ram addressable in 32-bit segments */
+#ifdef CONFIG_MIPS64
+#define MAX_RAM_SIZE (~0ULL)
+#else
+#ifdef CONFIG_HIGHMEM
+#ifdef CONFIG_64BIT_PHYS_ADDR
+#define MAX_RAM_SIZE (~0ULL)
+#else
+#define MAX_RAM_SIZE (0xffffffffULL)
+#endif
+#else
+#define MAX_RAM_SIZE (0x1fffffffULL)
+#endif
+#endif
+
+#define SIBYTE_MAX_MEM_REGIONS 8
+phys_t board_mem_region_addrs[SIBYTE_MAX_MEM_REGIONS];
+phys_t board_mem_region_sizes[SIBYTE_MAX_MEM_REGIONS];
+unsigned int board_mem_region_count;
+
+int cfe_cons_handle;
+
+#ifdef CONFIG_BLK_DEV_INITRD
+extern unsigned long initrd_start, initrd_end;
+#endif
+
+#ifdef CONFIG_KGDB
+extern int kgdb_port;
+#endif
+
+static void ATTRIB_NORET cfe_linux_exit(void *arg)
+{
+	int warm = *(int *)arg;
+
+	if (smp_processor_id()) {
+		static int reboot_smp;
+
+		/* Don't repeat the process from another CPU */
+		if (!reboot_smp) {
+			/* Get CPU 0 to do the cfe_exit */
+			reboot_smp = 1;
+			smp_call_function(cfe_linux_exit, arg, 1, 0);
+		}
+	} else {
+		printk("Passing control back to CFE...\n");
+		cfe_exit(warm, 0);
+		printk("cfe_exit returned??\n");
+	}
+	while (1);
+}
+
+static void ATTRIB_NORET cfe_linux_restart(char *command)
+{
+	static const int zero;
+
+	cfe_linux_exit((void *)&zero);
+}
+
+static void ATTRIB_NORET cfe_linux_halt(void)
+{
+	static const int one = 1;
+
+	cfe_linux_exit((void *)&one);
+}
+
+static __init void prom_meminit(void)
+{
+	u64 addr, size, type; /* regardless of 64BIT_PHYS_ADDR */
+	int mem_flags = 0;
+	unsigned int idx;
+	int rd_flag;
+#ifdef CONFIG_BLK_DEV_INITRD
+	unsigned long initrd_pstart;
+	unsigned long initrd_pend;
+
+	initrd_pstart = CPHYSADDR(initrd_start);
+	initrd_pend = CPHYSADDR(initrd_end);
+	if (initrd_start &&
+	    ((initrd_pstart > MAX_RAM_SIZE)
+	     || (initrd_pend > MAX_RAM_SIZE))) {
+		panic("initrd out of addressable memory");
+	}
+
+#endif /* INITRD */
+
+	for (idx = 0; cfe_enummem(idx, mem_flags, &addr, &size, &type) != CFE_ERR_NOMORE;
+	     idx++) {
+		rd_flag = 0;
+		if (type == CFE_MI_AVAILABLE) {
+			/*
+			 * See if this block contains (any portion of) the
+			 * ramdisk
+			 */
+#ifdef CONFIG_BLK_DEV_INITRD
+			if (initrd_start) {
+				if ((initrd_pstart > addr) &&
+				    (initrd_pstart < (addr + size))) {
+					add_memory_region(addr,
+					                  initrd_pstart - addr,
+					                  BOOT_MEM_RAM);
+					rd_flag = 1;
+				}
+				if ((initrd_pend > addr) &&
+				    (initrd_pend < (addr + size))) {
+					add_memory_region(initrd_pend,
+						(addr + size) - initrd_pend,
+						 BOOT_MEM_RAM);
+					rd_flag = 1;
+				}
+			}
+#endif
+			if (!rd_flag) {
+				if (addr > MAX_RAM_SIZE)
+					continue;
+				if (addr+size > MAX_RAM_SIZE)
+					size = MAX_RAM_SIZE - (addr+size) + 1;
+				/*
+				 * memcpy/__copy_user prefetch, which
+				 * will cause a bus error for
+				 * KSEG/KUSEG addrs not backed by RAM.
+				 * Hence, reserve some padding for the
+				 * prefetch distance.
+				 */
+				if (size > 512)
+					size -= 512;
+				add_memory_region(addr, size, BOOT_MEM_RAM);
+			}
+			board_mem_region_addrs[board_mem_region_count] = addr;
+			board_mem_region_sizes[board_mem_region_count] = size;
+			board_mem_region_count++;
+			if (board_mem_region_count ==
+			    SIBYTE_MAX_MEM_REGIONS) {
+				/*
+				 * Too many regions.  Need to configure more
+				 */
+				while(1);
+			}
+		}
+	}
+#ifdef CONFIG_BLK_DEV_INITRD
+	if (initrd_start) {
+		add_memory_region(initrd_pstart, initrd_pend - initrd_pstart,
+				  BOOT_MEM_RESERVED);
+	}
+#endif
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+static int __init initrd_setup(char *str)
+{
+	char rdarg[64];
+	int idx;
+	char *tmp, *endptr;
+	unsigned long initrd_size;
+
+	/* Make a copy of the initrd argument so we can smash it up here */
+	for (idx = 0; idx < sizeof(rdarg)-1; idx++) {
+		if (!str[idx] || (str[idx] == ' ')) break;
+		rdarg[idx] = str[idx];
+	}
+
+	rdarg[idx] = 0;
+	str = rdarg;
+
+	/*
+	 *Initrd location comes in the form "<hex size of ramdisk in bytes>@<location in memory>"
+	 *  e.g. initrd=3abfd@80010000.  This is set up by the loader.
+	 */
+	for (tmp = str; *tmp != '@'; tmp++) {
+		if (!*tmp) {
+			goto fail;
+		}
+	}
+	*tmp = 0;
+	tmp++;
+	if (!*tmp) {
+		goto fail;
+	}
+	initrd_size = simple_strtoul(str, &endptr, 16);
+	if (*endptr) {
+		*(tmp-1) = '@';
+		goto fail;
+	}
+	*(tmp-1) = '@';
+	initrd_start = simple_strtoul(tmp, &endptr, 16);
+	if (*endptr) {
+		goto fail;
+	}
+	initrd_end = initrd_start + initrd_size;
+	prom_printf("Found initrd of %lx@%lx\n", initrd_size, initrd_start);
+	return 1;
+ fail:
+	prom_printf("Bad initrd argument.  Disabling initrd\n");
+	initrd_start = 0;
+	initrd_end = 0;
+	return 1;
+}
+
+#endif
+
+/*
+ * prom_init is called just after the cpu type is determined, from setup_arch()
+ */
+void __init prom_init(void)
+{
+	uint64_t cfe_ept, cfe_handle;
+	unsigned int cfe_eptseal;
+	int argc = fw_arg0;
+	char **envp = (char **) fw_arg2;
+	int *prom_vec = (int *) fw_arg3;
+#ifdef CONFIG_KGDB
+	char *arg;
+#endif
+
+	_machine_restart   = cfe_linux_restart;
+	_machine_halt      = cfe_linux_halt;
+	_machine_power_off = cfe_linux_halt;
+
+	/*
+	 * Check if a loader was used; if NOT, the 4 arguments are
+	 * what CFE gives us (handle, 0, EPT and EPTSEAL)
+	 */
+	if (argc < 0) {
+		cfe_handle = (uint64_t)(long)argc;
+		cfe_ept = (long)envp;
+		cfe_eptseal = (uint32_t)(unsigned long)prom_vec;
+	} else {
+		if ((int32_t)(long)prom_vec < 0) {
+			/*
+			 * Old loader; all it gives us is the handle,
+			 * so use the "known" entrypoint and assume
+			 * the seal.
+			 */
+			cfe_handle = (uint64_t)(long)prom_vec;
+			cfe_ept = (uint64_t)((int32_t)0x9fc00500);
+			cfe_eptseal = CFE_EPTSEAL;
+		} else {
+			/*
+			 * Newer loaders bundle the handle/ept/eptseal
+			 * Note: prom_vec is in the loader's useg
+			 * which is still alive in the TLB.
+			 */
+			cfe_handle = (uint64_t)((int32_t *)prom_vec)[0];
+			cfe_ept = (uint64_t)((int32_t *)prom_vec)[2];
+			cfe_eptseal = (unsigned int)((uint32_t *)prom_vec)[3];
+		}
+	}
+	if (cfe_eptseal != CFE_EPTSEAL) {
+		/* too early for panic to do any good */
+		prom_printf("CFE's entrypoint seal doesn't match. Spinning.");
+		while (1) ;
+	}
+	cfe_init(cfe_handle, cfe_ept);
+	/* 
+	 * Get the handle for (at least) prom_putchar, possibly for
+	 * boot console
+	 */
+	cfe_cons_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE);
+	if (cfe_getenv("LINUX_CMDLINE", arcs_cmdline, CL_SIZE) < 0) {
+		if (argc < 0) {
+			/*
+			 * It's OK for direct boot to not provide a
+			 *  command line
+			 */
+			strcpy(arcs_cmdline, "root=/dev/ram0 ");
+#ifdef CONFIG_SIBYTE_PTSWARM
+			strcat(arcs_cmdline, "console=ttyS0,115200 ");
+#endif
+		} else {
+			/* The loader should have set the command line */
+			/* too early for panic to do any good */
+			prom_printf("LINUX_CMDLINE not defined in cfe.");
+			while (1) ;
+		}
+	}
+
+#ifdef CONFIG_KGDB
+	if ((arg = strstr(arcs_cmdline,"kgdb=duart")) != NULL)
+		kgdb_port = (arg[10] == '0') ? 0 : 1;
+	else
+		kgdb_port = 1;
+#endif
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	{
+		char *ptr;
+		/* Need to find out early whether we've got an initrd.  So scan
+		   the list looking now */
+		for (ptr = arcs_cmdline; *ptr; ptr++) {
+			while (*ptr == ' ') {
+				ptr++;
+			}
+			if (!strncmp(ptr, "initrd=", 7)) {
+				initrd_setup(ptr+7);
+				break;
+			} else {
+				while (*ptr && (*ptr != ' ')) {
+					ptr++;
+				}
+			}
+		}
+	}
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/* Not sure this is needed, but it's the safe way. */
+	arcs_cmdline[CL_SIZE-1] = 0;
+
+	mips_machgroup = MACH_GROUP_SIBYTE;
+	prom_meminit();
+}
+
+unsigned long __init prom_free_prom_memory(void)
+{
+	/* Not sure what I'm supposed to do here.  Nothing, I think */
+	return 0;
+}
+
+void prom_putchar(char c)
+{
+	int ret;
+
+	while ((ret = cfe_write(cfe_cons_handle, &c, 1)) == 0)
+		;
+}
diff --git a/arch/mips/sibyte/cfe/smp.c b/arch/mips/sibyte/cfe/smp.c
new file mode 100644
index 0000000..7339219
--- /dev/null
+++ b/arch/mips/sibyte/cfe/smp.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <asm/processor.h>
+
+#include "cfe_api.h"
+#include "cfe_error.h"
+
+/*
+ * Use CFE to find out how many CPUs are available, setting up
+ * phys_cpu_present_map and the logical/physical mappings.
+ * XXXKW will the boot CPU ever not be physical 0?
+ *
+ * Common setup before any secondaries are started
+ */
+void __init prom_prepare_cpus(unsigned int max_cpus)
+{
+	int i, num;
+
+	cpus_clear(phys_cpu_present_map);
+	cpu_set(0, phys_cpu_present_map);
+	__cpu_number_map[0] = 0;
+	__cpu_logical_map[0] = 0;
+
+	for (i=1, num=0; i<NR_CPUS; i++) {
+		if (cfe_cpu_stop(i) == 0) {
+			cpu_set(i, phys_cpu_present_map);
+			__cpu_number_map[i] = ++num;
+			__cpu_logical_map[num] = i;
+		}
+	}
+	printk("Detected %i available secondary CPU(s)\n", num);
+}
+
+/*
+ * Setup the PC, SP, and GP of a secondary processor and start it
+ * running!
+ */
+void prom_boot_secondary(int cpu, struct task_struct *idle)
+{
+	int retval;
+	
+	retval = cfe_cpu_start(cpu_logical_map(cpu), &smp_bootstrap,
+			       __KSTK_TOS(idle),
+			       (unsigned long)idle->thread_info, 0);
+	if (retval != 0)
+		printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval);
+}
+
+/*
+ * Code to run on secondary just after probing the CPU
+ */
+void prom_init_secondary(void)
+{
+	extern void sb1250_smp_init(void);
+	sb1250_smp_init();
+}
+
+/*
+ * Do any tidying up before marking online and running the idle
+ * loop
+ */
+void prom_smp_finish(void)
+{
+	extern void sb1250_smp_finish(void);
+	sb1250_smp_finish();
+}
+
+/*
+ * Final cleanup after all secondaries booted
+ */
+void prom_cpus_done(void)
+{
+}
diff --git a/arch/mips/sibyte/sb1250/Makefile b/arch/mips/sibyte/sb1250/Makefile
new file mode 100644
index 0000000..a8af846
--- /dev/null
+++ b/arch/mips/sibyte/sb1250/Makefile
@@ -0,0 +1,8 @@
+obj-y := setup.o irq.o irq_handler.o time.o
+
+obj-$(CONFIG_SMP)			+= smp.o
+obj-$(CONFIG_SIBYTE_TBPROF)		+= bcm1250_tbprof.o
+obj-$(CONFIG_SIBYTE_STANDALONE)		+= prom.o
+obj-$(CONFIG_SIBYTE_BUS_WATCHER)	+= bus_watcher.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/sibyte/sb1250/bcm1250_tbprof.c b/arch/mips/sibyte/sb1250/bcm1250_tbprof.c
new file mode 100644
index 0000000..7f813ae
--- /dev/null
+++ b/arch/mips/sibyte/sb1250/bcm1250_tbprof.c
@@ -0,0 +1,390 @@
+/*
+ * Copyright (C) 2001, 2002, 2003 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#define SBPROF_TB_DEBUG 0
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/reboot.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_scd.h>
+#include <asm/sibyte/sb1250_int.h>
+#include <asm/sibyte/trace_prof.h>
+
+#define DEVNAME "bcm1250_tbprof"
+
+static struct sbprof_tb sbp;
+
+#define TB_FULL (sbp.next_tb_sample == MAX_TB_SAMPLES)
+
+/************************************************************************
+ * Support for ZBbus sampling using the trace buffer
+ *
+ * We use the SCD performance counter interrupt, caused by a Zclk counter
+ * overflow, to trigger the start of tracing.
+ *
+ * We set the trace buffer to sample everything and freeze on
+ * overflow.
+ *
+ * We map the interrupt for trace_buffer_freeze to handle it on CPU 0.
+ *
+ ************************************************************************/
+
+static u_int64_t tb_period;
+
+static void arm_tb(void)
+{
+        u_int64_t scdperfcnt;
+	u_int64_t next = (1ULL << 40) - tb_period;
+	u_int64_t tb_options = M_SCD_TRACE_CFG_FREEZE_FULL;
+	/* Generate an SCD_PERFCNT interrupt in TB_PERIOD Zclks to
+	   trigger start of trace.  XXX vary sampling period */
+	bus_writeq(0, IOADDR(A_SCD_PERF_CNT_1));
+	scdperfcnt = bus_readq(IOADDR(A_SCD_PERF_CNT_CFG));
+	/* Unfortunately, in Pass 2 we must clear all counters to knock down
+	   a previous interrupt request.  This means that bus profiling
+	   requires ALL of the SCD perf counters. */
+	bus_writeq((scdperfcnt & ~M_SPC_CFG_SRC1) | // keep counters 0,2,3 as is
+		   M_SPC_CFG_ENABLE |		 // enable counting
+		   M_SPC_CFG_CLEAR |		 // clear all counters
+		   V_SPC_CFG_SRC1(1),		 // counter 1 counts cycles
+		   IOADDR(A_SCD_PERF_CNT_CFG));
+	bus_writeq(next, IOADDR(A_SCD_PERF_CNT_1));
+	/* Reset the trace buffer */
+	bus_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
+#if 0 && defined(M_SCD_TRACE_CFG_FORCECNT)
+	/* XXXKW may want to expose control to the data-collector */
+	tb_options |= M_SCD_TRACE_CFG_FORCECNT;
+#endif
+	bus_writeq(tb_options, IOADDR(A_SCD_TRACE_CFG));
+	sbp.tb_armed = 1;
+}
+
+static irqreturn_t sbprof_tb_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	int i;
+	DBG(printk(DEVNAME ": tb_intr\n"));
+	if (sbp.next_tb_sample < MAX_TB_SAMPLES) {
+		/* XXX should use XKPHYS to make writes bypass L2 */
+		u_int64_t *p = sbp.sbprof_tbbuf[sbp.next_tb_sample++];
+		/* Read out trace */
+		bus_writeq(M_SCD_TRACE_CFG_START_READ, IOADDR(A_SCD_TRACE_CFG));
+		__asm__ __volatile__ ("sync" : : : "memory");
+		/* Loop runs backwards because bundles are read out in reverse order */
+		for (i = 256 * 6; i > 0; i -= 6) {
+			// Subscripts decrease to put bundle in the order
+			//   t0 lo, t0 hi, t1 lo, t1 hi, t2 lo, t2 hi
+			p[i-1] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t2 hi
+			p[i-2] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t2 lo
+			p[i-3] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t1 hi
+			p[i-4] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t1 lo
+			p[i-5] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t0 hi
+			p[i-6] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t0 lo
+		}
+		if (!sbp.tb_enable) {
+			DBG(printk(DEVNAME ": tb_intr shutdown\n"));
+			bus_writeq(M_SCD_TRACE_CFG_RESET,
+				   IOADDR(A_SCD_TRACE_CFG));
+			sbp.tb_armed = 0;
+			wake_up(&sbp.tb_sync);
+		} else {
+			arm_tb();	// knock down current interrupt and get another one later
+		}
+	} else {
+		/* No more trace buffer samples */
+		DBG(printk(DEVNAME ": tb_intr full\n"));
+		bus_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
+		sbp.tb_armed = 0;
+		if (!sbp.tb_enable) {
+			wake_up(&sbp.tb_sync);
+		}
+		wake_up(&sbp.tb_read);
+	}
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t sbprof_pc_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	printk(DEVNAME ": unexpected pc_intr");
+	return IRQ_NONE;
+}
+
+int sbprof_zbprof_start(struct file *filp)
+{
+	u_int64_t scdperfcnt;
+
+	if (sbp.tb_enable)
+		return -EBUSY;
+
+	DBG(printk(DEVNAME ": starting\n"));
+
+	sbp.tb_enable = 1;
+	sbp.next_tb_sample = 0;
+	filp->f_pos = 0;
+
+	if (request_irq
+	    (K_INT_TRACE_FREEZE, sbprof_tb_intr, 0, DEVNAME " trace freeze", &sbp)) {
+		return -EBUSY;
+	}
+	/* Make sure there isn't a perf-cnt interrupt waiting */
+	scdperfcnt = bus_readq(IOADDR(A_SCD_PERF_CNT_CFG));
+	/* Disable and clear counters, override SRC_1 */
+	bus_writeq((scdperfcnt & ~(M_SPC_CFG_SRC1 | M_SPC_CFG_ENABLE)) |
+		   M_SPC_CFG_ENABLE |
+		   M_SPC_CFG_CLEAR |
+		   V_SPC_CFG_SRC1(1),
+		   IOADDR(A_SCD_PERF_CNT_CFG));
+
+	/* We grab this interrupt to prevent others from trying to use
+           it, even though we don't want to service the interrupts
+           (they only feed into the trace-on-interrupt mechanism) */
+	if (request_irq
+	    (K_INT_PERF_CNT, sbprof_pc_intr, 0, DEVNAME " scd perfcnt", &sbp)) {
+		free_irq(K_INT_TRACE_FREEZE, &sbp);
+		return -EBUSY;
+	}
+
+	/* I need the core to mask these, but the interrupt mapper to
+	   pass them through.  I am exploiting my knowledge that
+	   cp0_status masks out IP[5]. krw */
+	bus_writeq(K_INT_MAP_I3,
+		   IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
+			  (K_INT_PERF_CNT << 3)));
+
+	/* Initialize address traps */
+	bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_0));
+	bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_1));
+	bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_2));
+	bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_3));
+
+	bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_0));
+	bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_1));
+	bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_2));
+	bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_3));
+
+	bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_0));
+	bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_1));
+	bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_2));
+	bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_3));
+
+	/* Initialize Trace Event 0-7 */
+	//				when interrupt
+	bus_writeq(M_SCD_TREVT_INTERRUPT, IOADDR(A_SCD_TRACE_EVENT_0));
+	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_1));
+	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_2));
+	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_3));
+	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_4));
+	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_5));
+	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_6));
+	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_7));
+
+	/* Initialize Trace Sequence 0-7 */
+	//				     Start on event 0 (interrupt)
+	bus_writeq(V_SCD_TRSEQ_FUNC_START | 0x0fff,
+		   IOADDR(A_SCD_TRACE_SEQUENCE_0));
+	//			  dsamp when d used | asamp when a used
+	bus_writeq(M_SCD_TRSEQ_ASAMPLE | M_SCD_TRSEQ_DSAMPLE |
+		   K_SCD_TRSEQ_TRIGGER_ALL,
+		   IOADDR(A_SCD_TRACE_SEQUENCE_1));
+	bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_2));
+	bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_3));
+	bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_4));
+	bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_5));
+	bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_6));
+	bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_7));
+
+	/* Now indicate the PERF_CNT interrupt as a trace-relevant interrupt */
+	bus_writeq((1ULL << K_INT_PERF_CNT),
+		   IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_TRACE)));
+
+	arm_tb();
+
+	DBG(printk(DEVNAME ": done starting\n"));
+
+	return 0;
+}
+
+int sbprof_zbprof_stop(void)
+{
+	DBG(printk(DEVNAME ": stopping\n"));
+
+	if (sbp.tb_enable) {
+		sbp.tb_enable = 0;
+		/* XXXKW there is a window here where the intr handler
+		   may run, see the disable, and do the wake_up before
+		   this sleep happens. */
+		if (sbp.tb_armed) {
+			DBG(printk(DEVNAME ": wait for disarm\n"));
+			interruptible_sleep_on(&sbp.tb_sync);
+			DBG(printk(DEVNAME ": disarm complete\n"));
+		}
+		free_irq(K_INT_TRACE_FREEZE, &sbp);
+		free_irq(K_INT_PERF_CNT, &sbp);
+	}
+
+	DBG(printk(DEVNAME ": done stopping\n"));
+
+	return 0;
+}
+
+static int sbprof_tb_open(struct inode *inode, struct file *filp)
+{
+	int minor;
+
+	minor = iminor(inode);
+	if (minor != 0) {
+		return -ENODEV;
+	}
+	if (sbp.open) {
+		return -EBUSY;
+	}
+
+	memset(&sbp, 0, sizeof(struct sbprof_tb));
+	sbp.sbprof_tbbuf = vmalloc(MAX_TBSAMPLE_BYTES);
+	if (!sbp.sbprof_tbbuf) {
+		return -ENOMEM;
+	}
+	memset(sbp.sbprof_tbbuf, 0, MAX_TBSAMPLE_BYTES);
+	init_waitqueue_head(&sbp.tb_sync);
+	init_waitqueue_head(&sbp.tb_read);
+	sbp.open = 1;
+
+	return 0;
+}
+
+static int sbprof_tb_release(struct inode *inode, struct file *filp)
+{
+	int minor;
+
+	minor = iminor(inode);
+	if (minor != 0 || !sbp.open) {
+		return -ENODEV;
+	}
+
+	if (sbp.tb_armed || sbp.tb_enable) {
+		sbprof_zbprof_stop();
+	}
+
+	vfree(sbp.sbprof_tbbuf);
+	sbp.open = 0;
+
+	return 0;
+}
+
+static ssize_t sbprof_tb_read(struct file *filp, char *buf,
+			      size_t size, loff_t *offp)
+{
+	int cur_sample, sample_off, cur_count, sample_left;
+	char *src;
+	int   count   =	 0;
+	char *dest    =	 buf;
+	long  cur_off = *offp;
+
+	count = 0;
+	cur_sample = cur_off / TB_SAMPLE_SIZE;
+	sample_off = cur_off % TB_SAMPLE_SIZE;
+	sample_left = TB_SAMPLE_SIZE - sample_off;
+	while (size && (cur_sample < sbp.next_tb_sample)) {
+		cur_count = size < sample_left ? size : sample_left;
+		src = (char *)(((long)sbp.sbprof_tbbuf[cur_sample])+sample_off);
+		copy_to_user(dest, src, cur_count);
+		DBG(printk(DEVNAME ": read from sample %d, %d bytes\n",
+			   cur_sample, cur_count));
+		size -= cur_count;
+		sample_left -= cur_count;
+		if (!sample_left) {
+			cur_sample++;
+			sample_off = 0;
+			sample_left = TB_SAMPLE_SIZE;
+		} else {
+			sample_off += cur_count;
+		}
+		cur_off += cur_count;
+		dest += cur_count;
+		count += cur_count;
+	}
+	*offp = cur_off;
+
+	return count;
+}
+
+static int sbprof_tb_ioctl(struct inode *inode,
+			   struct file *filp,
+			   unsigned int command,
+			   unsigned long arg)
+{
+	int error = 0;
+
+	switch (command) {
+	case SBPROF_ZBSTART:
+		error = sbprof_zbprof_start(filp);
+		break;
+	case SBPROF_ZBSTOP:
+		error = sbprof_zbprof_stop();
+		break;
+	case SBPROF_ZBWAITFULL:
+		interruptible_sleep_on(&sbp.tb_read);
+		/* XXXKW check if interrupted? */
+		return put_user(TB_FULL, (int *) arg);
+	default:
+		error = -EINVAL;
+		break;
+	}
+
+	return error;
+}
+
+static struct file_operations sbprof_tb_fops = {
+	.owner		= THIS_MODULE,
+	.open		= sbprof_tb_open,
+	.release	= sbprof_tb_release,
+	.read		= sbprof_tb_read,
+	.ioctl		= sbprof_tb_ioctl,
+	.mmap		= NULL,
+};
+
+static int __init sbprof_tb_init(void)
+{
+	if (register_chrdev(SBPROF_TB_MAJOR, DEVNAME, &sbprof_tb_fops)) {
+		printk(KERN_WARNING DEVNAME ": initialization failed (dev %d)\n",
+		       SBPROF_TB_MAJOR);
+		return -EIO;
+	}
+	sbp.open = 0;
+	tb_period = zbbus_mhz * 10000LL;
+	printk(KERN_INFO DEVNAME ": initialized - tb_period = %lld\n", tb_period);
+	return 0;
+}
+
+static void __exit sbprof_tb_cleanup(void)
+{
+	unregister_chrdev(SBPROF_TB_MAJOR, DEVNAME);
+}
+
+module_init(sbprof_tb_init);
+module_exit(sbprof_tb_cleanup);
diff --git a/arch/mips/sibyte/sb1250/bus_watcher.c b/arch/mips/sibyte/sb1250/bus_watcher.c
new file mode 100644
index 0000000..182a16f
--- /dev/null
+++ b/arch/mips/sibyte/sb1250/bus_watcher.c
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2002,2003 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/* 
+ * The Bus Watcher monitors internal bus transactions and maintains
+ * counts of transactions with error status, logging details and
+ * causing one of several interrupts.  This driver provides a handler
+ * for those interrupts which aggregates the counts (to avoid
+ * saturating the 8-bit counters) and provides a presence in
+ * /proc/bus_watcher if PROC_FS is on.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <asm/system.h>
+#include <asm/io.h>
+
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_int.h>
+#include <asm/sibyte/sb1250_scd.h>
+
+
+struct bw_stats_struct {
+	uint64_t status;
+	uint32_t l2_err;
+	uint32_t memio_err;
+	int status_printed;
+	unsigned long l2_cor_d;
+	unsigned long l2_bad_d;
+	unsigned long l2_cor_t;
+	unsigned long l2_bad_t;
+	unsigned long mem_cor_d;
+	unsigned long mem_bad_d;
+	unsigned long bus_error;
+} bw_stats;
+
+
+static void print_summary(uint32_t status, uint32_t l2_err,
+			  uint32_t memio_err)
+{
+	printk("Bus watcher error counters: %08x %08x\n", l2_err, memio_err);
+	printk("\nLast recorded signature:\n");
+	printk("Request %02x from %d, answered by %d with Dcode %d\n",
+	       (unsigned int)(G_SCD_BERR_TID(status) & 0x3f),
+	       (int)(G_SCD_BERR_TID(status) >> 6),
+	       (int)G_SCD_BERR_RID(status),
+	       (int)G_SCD_BERR_DCODE(status));
+}
+
+/*
+ * check_bus_watcher is exported for use in situations where we want
+ * to see the most recent status of the bus watcher, which might have
+ * already been destructively read out of the registers.
+ *
+ * notes: this is currently used by the cache error handler
+ *        should provide locking against the interrupt handler
+ */
+void check_bus_watcher(void)
+{
+	u32 status, l2_err, memio_err;
+
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+	/* Destructive read, clears register and interrupt */
+	status = csr_in32(IOADDR(A_SCD_BUS_ERR_STATUS));
+#else
+	/* Use non-destructive register */
+	status = csr_in32(IOADDR(A_SCD_BUS_ERR_STATUS_DEBUG));
+#endif
+	if (!(status & 0x7fffffff)) {
+		printk("Using last values reaped by bus watcher driver\n");
+		status = bw_stats.status;
+		l2_err = bw_stats.l2_err;
+		memio_err = bw_stats.memio_err;
+	} else {
+		l2_err = csr_in32(IOADDR(A_BUS_L2_ERRORS));
+		memio_err = csr_in32(IOADDR(A_BUS_MEM_IO_ERRORS));
+	}
+	if (status & ~(1UL << 31))
+		print_summary(status, l2_err, memio_err);
+	else
+		printk("Bus watcher indicates no error\n");
+}
+
+static int bw_print_buffer(char *page, struct bw_stats_struct *stats)
+{
+	int len;
+
+	len = sprintf(page, "SiByte Bus Watcher statistics\n");
+	len += sprintf(page+len, "-----------------------------\n");
+	len += sprintf(page+len, "L2-d-cor %8ld\nL2-d-bad %8ld\n",
+		       stats->l2_cor_d, stats->l2_bad_d);
+	len += sprintf(page+len, "L2-t-cor %8ld\nL2-t-bad %8ld\n",
+		       stats->l2_cor_t, stats->l2_bad_t);
+	len += sprintf(page+len, "MC-d-cor %8ld\nMC-d-bad %8ld\n",
+		       stats->mem_cor_d, stats->mem_bad_d);
+	len += sprintf(page+len, "IO-err   %8ld\n", stats->bus_error);
+	len += sprintf(page+len, "\nLast recorded signature:\n");
+	len += sprintf(page+len, "Request %02x from %d, answered by %d with Dcode %d\n",
+		       (unsigned int)(G_SCD_BERR_TID(stats->status) & 0x3f),
+		       (int)(G_SCD_BERR_TID(stats->status) >> 6),
+		       (int)G_SCD_BERR_RID(stats->status),
+		       (int)G_SCD_BERR_DCODE(stats->status));
+	/* XXXKW indicate multiple errors between printings, or stats
+           collection (or both)? */
+	if (stats->status & M_SCD_BERR_MULTERRS)
+		len += sprintf(page+len, "Multiple errors observed since last check.\n");
+	if (stats->status_printed) {
+		len += sprintf(page+len, "(no change since last printing)\n");
+	} else {
+		stats->status_printed = 1;
+	}
+
+	return len;
+}
+
+#ifdef CONFIG_PROC_FS
+
+/* For simplicity, I want to assume a single read is required each
+   time */
+static int bw_read_proc(char *page, char **start, off_t off,
+			int count, int *eof, void *data)
+{
+	int len;
+
+	if (off == 0) {
+		len = bw_print_buffer(page, data);
+		*start = page;
+	} else {
+		len = 0;
+		*eof = 1;
+	}
+	return len;
+}
+
+static void create_proc_decoder(struct bw_stats_struct *stats)
+{
+	struct proc_dir_entry *ent;
+	
+	ent = create_proc_read_entry("bus_watcher", S_IWUSR | S_IRUGO, NULL,
+				     bw_read_proc, stats);
+	if (!ent) {
+		printk(KERN_INFO "Unable to initialize bus_watcher /proc entry\n");
+		return;
+	}
+}
+
+#endif /* CONFIG_PROC_FS */
+
+/*
+ * sibyte_bw_int - handle bus watcher interrupts and accumulate counts
+ *
+ * notes: possible re-entry due to multiple sources
+ *        should check/indicate saturation
+ */
+static irqreturn_t sibyte_bw_int(int irq, void *data, struct pt_regs *regs)
+{
+	struct bw_stats_struct *stats = data;
+	unsigned long cntr;
+#ifdef CONFIG_SIBYTE_BW_TRACE
+	int i;
+#endif
+#ifndef CONFIG_PROC_FS
+	char bw_buf[1024];
+#endif
+
+#ifdef CONFIG_SIBYTE_BW_TRACE
+	csr_out32(M_SCD_TRACE_CFG_FREEZE, IOADDR(A_SCD_TRACE_CFG));
+	csr_out32(M_SCD_TRACE_CFG_START_READ, IOADDR(A_SCD_TRACE_CFG));
+
+	for (i=0; i<256*6; i++)
+		printk("%016llx\n",
+		       (unsigned long long)bus_readq(IOADDR(A_SCD_TRACE_READ)));
+
+	csr_out32(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
+	csr_out32(M_SCD_TRACE_CFG_START, IOADDR(A_SCD_TRACE_CFG));
+#endif
+
+	/* Destructive read, clears register and interrupt */
+	stats->status = csr_in32(IOADDR(A_SCD_BUS_ERR_STATUS));
+	stats->status_printed = 0;
+
+	stats->l2_err = cntr = csr_in32(IOADDR(A_BUS_L2_ERRORS));
+	stats->l2_cor_d += G_SCD_L2ECC_CORR_D(cntr);
+	stats->l2_bad_d += G_SCD_L2ECC_BAD_D(cntr);
+	stats->l2_cor_t += G_SCD_L2ECC_CORR_T(cntr);
+	stats->l2_bad_t += G_SCD_L2ECC_BAD_T(cntr);
+	csr_out32(0, IOADDR(A_BUS_L2_ERRORS));
+
+	stats->memio_err = cntr = csr_in32(IOADDR(A_BUS_MEM_IO_ERRORS));
+	stats->mem_cor_d += G_SCD_MEM_ECC_CORR(cntr);
+	stats->mem_bad_d += G_SCD_MEM_ECC_BAD(cntr);
+	stats->bus_error += G_SCD_MEM_BUSERR(cntr);
+	csr_out32(0, IOADDR(A_BUS_MEM_IO_ERRORS));
+
+#ifndef CONFIG_PROC_FS
+	bw_print_buffer(bw_buf, stats);
+	printk(bw_buf);
+#endif
+
+	return IRQ_HANDLED;
+}
+
+int __init sibyte_bus_watcher(void)
+{
+	memset(&bw_stats, 0, sizeof(struct bw_stats_struct));
+	bw_stats.status_printed = 1;
+
+	if (request_irq(K_INT_BAD_ECC, sibyte_bw_int, 0, "Bus watcher", &bw_stats)) {
+		printk("Failed to register bus watcher BAD_ECC irq\n");
+		return -1;
+	}
+	if (request_irq(K_INT_COR_ECC, sibyte_bw_int, 0, "Bus watcher", &bw_stats)) {
+		free_irq(K_INT_BAD_ECC, &bw_stats);
+		printk("Failed to register bus watcher COR_ECC irq\n");
+		return -1;
+	}
+	if (request_irq(K_INT_IO_BUS, sibyte_bw_int, 0, "Bus watcher", &bw_stats)) {
+		free_irq(K_INT_BAD_ECC, &bw_stats);
+		free_irq(K_INT_COR_ECC, &bw_stats);
+		printk("Failed to register bus watcher IO_BUS irq\n");
+		return -1;
+	}
+
+#ifdef CONFIG_PROC_FS
+	create_proc_decoder(&bw_stats);
+#endif
+
+#ifdef CONFIG_SIBYTE_BW_TRACE
+	csr_out32((M_SCD_TRSEQ_ASAMPLE | M_SCD_TRSEQ_DSAMPLE |
+		   K_SCD_TRSEQ_TRIGGER_ALL),
+		  IOADDR(A_SCD_TRACE_SEQUENCE_0));
+	csr_out32(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
+	csr_out32(M_SCD_TRACE_CFG_START, IOADDR(A_SCD_TRACE_CFG));
+#endif
+
+	return 0;
+}
+
+__initcall(sibyte_bus_watcher);
diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c
new file mode 100644
index 0000000..2728abb
--- /dev/null
+++ b/arch/mips/sibyte/sb1250/irq.c
@@ -0,0 +1,431 @@
+/*
+ * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/smp.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/errno.h>
+#include <asm/signal.h>
+#include <asm/system.h>
+#include <asm/ptrace.h>
+#include <asm/io.h>
+
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_int.h>
+#include <asm/sibyte/sb1250_uart.h>
+#include <asm/sibyte/sb1250_scd.h>
+#include <asm/sibyte/sb1250.h>
+
+/*
+ * These are the routines that handle all the low level interrupt stuff.
+ * Actions handled here are: initialization of the interrupt map, requesting of
+ * interrupt lines by handlers, dispatching if interrupts to handlers, probing
+ * for interrupt lines
+ */
+
+
+#define shutdown_sb1250_irq	disable_sb1250_irq
+static void end_sb1250_irq(unsigned int irq);
+static void enable_sb1250_irq(unsigned int irq);
+static void disable_sb1250_irq(unsigned int irq);
+static unsigned int startup_sb1250_irq(unsigned int irq);
+static void ack_sb1250_irq(unsigned int irq);
+#ifdef CONFIG_SMP
+static void sb1250_set_affinity(unsigned int irq, unsigned long mask);
+#endif
+
+#ifdef CONFIG_SIBYTE_HAS_LDT
+extern unsigned long ldt_eoi_space;
+#endif
+
+#ifdef CONFIG_KGDB
+static int kgdb_irq;
+
+/* Default to UART1 */
+int kgdb_port = 1;
+#ifdef CONFIG_SIBYTE_SB1250_DUART
+extern char sb1250_duart_present[];
+#endif
+#endif
+
+static struct hw_interrupt_type sb1250_irq_type = {
+	"SB1250-IMR",
+	startup_sb1250_irq,
+	shutdown_sb1250_irq,
+	enable_sb1250_irq,
+	disable_sb1250_irq,
+	ack_sb1250_irq,
+	end_sb1250_irq,
+#ifdef CONFIG_SMP
+	sb1250_set_affinity
+#else
+	NULL
+#endif
+};
+
+/* Store the CPU id (not the logical number) */
+int sb1250_irq_owner[SB1250_NR_IRQS];
+
+DEFINE_SPINLOCK(sb1250_imr_lock);
+
+void sb1250_mask_irq(int cpu, int irq)
+{
+	unsigned long flags;
+	u64 cur_ints;
+
+	spin_lock_irqsave(&sb1250_imr_lock, flags);
+	cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(cpu) +
+				      R_IMR_INTERRUPT_MASK));
+	cur_ints |= (((u64) 1) << irq);
+	__bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
+				      R_IMR_INTERRUPT_MASK));
+	spin_unlock_irqrestore(&sb1250_imr_lock, flags);
+}
+
+void sb1250_unmask_irq(int cpu, int irq)
+{
+	unsigned long flags;
+	u64 cur_ints;
+
+	spin_lock_irqsave(&sb1250_imr_lock, flags);
+	cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(cpu) +
+				      R_IMR_INTERRUPT_MASK));
+	cur_ints &= ~(((u64) 1) << irq);
+	__bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
+				      R_IMR_INTERRUPT_MASK));
+	spin_unlock_irqrestore(&sb1250_imr_lock, flags);
+}
+
+#ifdef CONFIG_SMP
+static void sb1250_set_affinity(unsigned int irq, unsigned long mask)
+{
+	int i = 0, old_cpu, cpu, int_on;
+	u64 cur_ints;
+	irq_desc_t *desc = irq_desc + irq;
+	unsigned long flags;
+
+	while (mask) {
+		if (mask & 1) {
+			mask >>= 1;
+			break;
+		}
+		mask >>= 1;
+		i++;
+	}
+
+	if (mask) {
+		printk("attempted to set irq affinity for irq %d to multiple CPUs\n", irq);
+		return;
+	}
+
+	/* Convert logical CPU to physical CPU */
+	cpu = cpu_logical_map(i);
+
+	/* Protect against other affinity changers and IMR manipulation */
+	spin_lock_irqsave(&desc->lock, flags);
+	spin_lock(&sb1250_imr_lock);
+
+	/* Swizzle each CPU's IMR (but leave the IP selection alone) */
+	old_cpu = sb1250_irq_owner[irq];
+	cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(old_cpu) +
+			       R_IMR_INTERRUPT_MASK));
+	int_on = !(cur_ints & (((u64) 1) << irq));
+	if (int_on) {
+		/* If it was on, mask it */
+		cur_ints |= (((u64) 1) << irq);
+		__bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(old_cpu) +
+					      R_IMR_INTERRUPT_MASK));
+	}
+	sb1250_irq_owner[irq] = cpu;
+	if (int_on) {
+		/* unmask for the new CPU */
+		cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(cpu) +
+				       R_IMR_INTERRUPT_MASK));
+		cur_ints &= ~(((u64) 1) << irq);
+		__bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
+					      R_IMR_INTERRUPT_MASK));
+	}
+	spin_unlock(&sb1250_imr_lock);
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+#endif
+
+
+/* Defined in arch/mips/sibyte/sb1250/irq_handler.S */
+extern void sb1250_irq_handler(void);
+
+/*****************************************************************************/
+
+static unsigned int startup_sb1250_irq(unsigned int irq)
+{
+	sb1250_unmask_irq(sb1250_irq_owner[irq], irq);
+
+	return 0;		/* never anything pending */
+}
+
+
+static void disable_sb1250_irq(unsigned int irq)
+{
+	sb1250_mask_irq(sb1250_irq_owner[irq], irq);
+}
+
+static void enable_sb1250_irq(unsigned int irq)
+{
+	sb1250_unmask_irq(sb1250_irq_owner[irq], irq);
+}
+
+
+static void ack_sb1250_irq(unsigned int irq)
+{
+#ifdef CONFIG_SIBYTE_HAS_LDT
+	u64 pending;
+
+	/*
+	 * If the interrupt was an HT interrupt, now is the time to
+	 * clear it.  NOTE: we assume the HT bridge was set up to
+	 * deliver the interrupts to all CPUs (which makes affinity
+	 * changing easier for us)
+	 */
+	pending = bus_readq(IOADDR(A_IMR_REGISTER(sb1250_irq_owner[irq],
+						  R_IMR_LDT_INTERRUPT)));
+	pending &= ((u64)1 << (irq));
+	if (pending) {
+		int i;
+		for (i=0; i<NR_CPUS; i++) {
+			int cpu;
+#ifdef CONFIG_SMP
+			cpu = cpu_logical_map(i);
+#else
+			cpu = i;
+#endif
+			/*
+			 * Clear for all CPUs so an affinity switch
+			 * doesn't find an old status
+			 */
+			bus_writeq(pending,
+				   IOADDR(A_IMR_REGISTER(cpu,
+						R_IMR_LDT_INTERRUPT_CLR)));
+		}
+
+		/*
+		 * Generate EOI.  For Pass 1 parts, EOI is a nop.  For
+		 * Pass 2, the LDT world may be edge-triggered, but
+		 * this EOI shouldn't hurt.  If they are
+		 * level-sensitive, the EOI is required.
+		 */
+		*(uint32_t *)(ldt_eoi_space+(irq<<16)+(7<<2)) = 0;
+	}
+#endif
+	sb1250_mask_irq(sb1250_irq_owner[irq], irq);
+}
+
+
+static void end_sb1250_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+		sb1250_unmask_irq(sb1250_irq_owner[irq], irq);
+	}
+}
+
+
+void __init init_sb1250_irqs(void)
+{
+	int i;
+
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = 0;
+		irq_desc[i].depth = 1;
+		if (i < SB1250_NR_IRQS) {
+			irq_desc[i].handler = &sb1250_irq_type;
+			sb1250_irq_owner[i] = 0;
+		} else {
+			irq_desc[i].handler = &no_irq_type;
+		}
+	}
+}
+
+
+static irqreturn_t  sb1250_dummy_handler(int irq, void *dev_id,
+	struct pt_regs *regs)
+{
+	return IRQ_NONE;
+}
+
+static struct irqaction sb1250_dummy_action = {
+	.handler = sb1250_dummy_handler,
+	.flags   = 0,
+	.mask    = CPU_MASK_NONE,
+	.name    = "sb1250-private",
+	.next    = NULL,
+	.dev_id  = 0
+};
+
+int sb1250_steal_irq(int irq)
+{
+	irq_desc_t *desc = irq_desc + irq;
+	unsigned long flags;
+	int retval = 0;
+
+	if (irq >= SB1250_NR_IRQS)
+		return -EINVAL;
+
+	spin_lock_irqsave(&desc->lock,flags);
+	/* Don't allow sharing at all for these */
+	if (desc->action != NULL)
+		retval = -EBUSY;
+	else {
+		desc->action = &sb1250_dummy_action;
+		desc->depth = 0;
+	}
+	spin_unlock_irqrestore(&desc->lock,flags);
+	return 0;
+}
+
+/*
+ *  arch_init_irq is called early in the boot sequence from init/main.c via
+ *  init_IRQ.  It is responsible for setting up the interrupt mapper and
+ *  installing the handler that will be responsible for dispatching interrupts
+ *  to the "right" place.
+ */
+/*
+ * For now, map all interrupts to IP[2].  We could save
+ * some cycles by parceling out system interrupts to different
+ * IP lines, but keep it simple for bringup.  We'll also direct
+ * all interrupts to a single CPU; we should probably route
+ * PCI and LDT to one cpu and everything else to the other
+ * to balance the load a bit.
+ *
+ * On the second cpu, everything is set to IP5, which is
+ * ignored, EXCEPT the mailbox interrupt.  That one is
+ * set to IP[2] so it is handled.  This is needed so we
+ * can do cross-cpu function calls, as requred by SMP
+ */
+
+#define IMR_IP2_VAL	K_INT_MAP_I0
+#define IMR_IP3_VAL	K_INT_MAP_I1
+#define IMR_IP4_VAL	K_INT_MAP_I2
+#define IMR_IP5_VAL	K_INT_MAP_I3
+#define IMR_IP6_VAL	K_INT_MAP_I4
+
+void __init arch_init_irq(void)
+{
+
+	unsigned int i;
+	u64 tmp;
+	unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
+		STATUSF_IP1 | STATUSF_IP0;
+
+	/* Default everything to IP2 */
+	for (i = 0; i < SB1250_NR_IRQS; i++) {	/* was I0 */
+		bus_writeq(IMR_IP2_VAL,
+			   IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
+				  (i << 3)));
+		bus_writeq(IMR_IP2_VAL,
+			   IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MAP_BASE) +
+				  (i << 3)));
+	}
+
+	init_sb1250_irqs();
+
+	/*
+	 * Map the high 16 bits of the mailbox registers to IP[3], for
+	 * inter-cpu messages
+	 */
+	/* Was I1 */
+	bus_writeq(IMR_IP3_VAL,
+		   IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
+			  (K_INT_MBOX_0 << 3)));
+	bus_writeq(IMR_IP3_VAL,
+		   IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MAP_BASE) +
+			  (K_INT_MBOX_0 << 3)));
+
+	/* Clear the mailboxes.  The firmware may leave them dirty */
+	bus_writeq(0xffffffffffffffffULL,
+		   IOADDR(A_IMR_REGISTER(0, R_IMR_MAILBOX_CLR_CPU)));
+	bus_writeq(0xffffffffffffffffULL,
+		   IOADDR(A_IMR_REGISTER(1, R_IMR_MAILBOX_CLR_CPU)));
+
+	/* Mask everything except the mailbox registers for both cpus */
+	tmp = ~((u64) 0) ^ (((u64) 1) << K_INT_MBOX_0);
+	bus_writeq(tmp, IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK)));
+	bus_writeq(tmp, IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MASK)));
+
+	sb1250_steal_irq(K_INT_MBOX_0);
+
+	/*
+	 * Note that the timer interrupts are also mapped, but this is
+	 * done in sb1250_time_init().  Also, the profiling driver 
+	 * does its own management of IP7.
+	 */
+
+#ifdef CONFIG_KGDB
+	imask |= STATUSF_IP6;
+#endif
+	/* Enable necessary IPs, disable the rest */
+	change_c0_status(ST0_IM, imask);
+	set_except_vector(0, sb1250_irq_handler);
+
+#ifdef CONFIG_KGDB
+	if (kgdb_flag) {
+		kgdb_irq = K_INT_UART_0 + kgdb_port;
+
+#ifdef CONFIG_SIBYTE_SB1250_DUART	
+		sb1250_duart_present[kgdb_port] = 0;
+#endif
+		/* Setup uart 1 settings, mapper */
+		bus_writeq(M_DUART_IMR_BRK, IOADDR(A_DUART_IMRREG(kgdb_port)));
+
+		sb1250_steal_irq(kgdb_irq);
+		bus_writeq(IMR_IP6_VAL,
+			   IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
+				  (kgdb_irq<<3)));
+		sb1250_unmask_irq(0, kgdb_irq);
+	}
+#endif
+}
+
+#ifdef CONFIG_KGDB
+
+#include <linux/delay.h>
+
+#define duart_out(reg, val)     csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port,reg)))
+#define duart_in(reg)           csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port,reg)))
+
+void sb1250_kgdb_interrupt(struct pt_regs *regs)
+{
+	/*
+	 * Clear break-change status (allow some time for the remote
+	 * host to stop the break, since we would see another
+	 * interrupt on the end-of-break too)
+	 */
+	kstat_this_cpu.irqs[kgdb_irq]++;
+	mdelay(500);
+	duart_out(R_DUART_CMD, V_DUART_MISC_CMD_RESET_BREAK_INT |
+				M_DUART_RX_EN | M_DUART_TX_EN);
+	set_async_breakpoint(&regs->cp0_epc);
+}
+
+#endif 	/* CONFIG_KGDB */
diff --git a/arch/mips/sibyte/sb1250/irq_handler.S b/arch/mips/sibyte/sb1250/irq_handler.S
new file mode 100644
index 0000000..60edc8f
--- /dev/null
+++ b/arch/mips/sibyte/sb1250/irq_handler.S
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * sb1250_handle_int() is the routine that is actually called when an interrupt
+ * occurs.  It is installed as the exception vector handler in arch_init_irq()
+ * in arch/mips/sibyte/sb1250/irq.c
+ *
+ * In the handle we figure out which interrupts need handling, and use that to
+ * call the dispatcher, which will take care of actually calling registered
+ * handlers
+ *
+ * Note that we take care of all raised interrupts in one go at the handler.
+ * This is more BSDish than the Indy code, and also, IMHO, more sane.
+ */
+#include <linux/config.h>
+
+#include <asm/addrspace.h>
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/sibyte/sb1250_defs.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_int.h>
+
+/*
+ * What a pain. We have to be really careful saving the upper 32 bits of any
+ * register across function calls if we don't want them trashed--since were
+ * running in -o32, the calling routing never saves the full 64 bits of a
+ * register across a function call.  Being the interrupt handler, we're
+ * guaranteed that interrupts are disabled during this code so we don't have
+ * to worry about random interrupts blasting the high 32 bits.
+ */
+
+	.text
+	.set	push
+	.set	noreorder
+	.set	noat
+	.set	mips64
+	.align	5
+	NESTED(sb1250_irq_handler, PT_SIZE, sp)
+	SAVE_ALL
+	CLI
+
+#ifdef CONFIG_SIBYTE_SB1250_PROF
+	/* Set compare to count to silence count/compare timer interrupts */
+	mfc0	t1, CP0_COUNT
+	mtc0	t1, CP0_COMPARE /* pause to clear IP[7] bit of cause ? */
+#endif
+	/* Read cause */
+	mfc0	s0, CP0_CAUSE
+
+#ifdef CONFIG_SIBYTE_SB1250_PROF
+	/* Cpu performance counter interrupt is routed to IP[7] */
+	andi	t1, s0, CAUSEF_IP7
+	beqz	t1, 0f
+	 srl	t1, s0, (CAUSEB_BD-2)  /* Shift BD bit to bit 2 */
+	and	t1, t1, 0x4		/* mask to get just BD bit */
+	mfc0	a0, CP0_EPC
+	jal	sbprof_cpu_intr
+	 addu	a0, a0, t1		/* a0 = EPC + (BD ? 4 :	0) */
+	j	ret_from_irq
+	 nop
+0:
+#endif
+
+	/* Timer interrupt is routed to IP[4] */
+	andi	t1, s0, CAUSEF_IP4
+	beqz	t1, 1f
+	 nop
+	jal	sb1250_timer_interrupt
+	 move	a0, sp			/* Pass the registers along */
+	j	ret_from_irq
+	 nop				# delay slot
+1:
+
+#ifdef CONFIG_SMP
+	/* Mailbox interrupt is routed to IP[3] */
+	andi	 t1, s0, CAUSEF_IP3
+	beqz	 t1, 2f
+	 nop
+	jal	 sb1250_mailbox_interrupt
+	 move    a0, sp
+	j	ret_from_irq
+	 nop				# delay slot
+2:
+#endif
+
+#ifdef CONFIG_KGDB
+	/* KGDB (uart 1) interrupt is routed to IP[6] */
+	andi	t1, s0, CAUSEF_IP6
+	beqz	t1, 1f
+	nop                            # delay slot
+	jal	sb1250_kgdb_interrupt
+         move	a0, sp
+	j	ret_from_irq
+	nop                            # delay slot
+1:
+#endif
+
+	and      t1, s0, CAUSEF_IP2
+	beqz     t1, 4f
+	 nop
+
+	/*
+	 * Default...we've hit an IP[2] interrupt, which means we've got to
+	 * check the 1250 interrupt registers to figure out what to do
+	 * Need to detect which CPU we're on, now that smp_affinity is supported.
+	 */
+	PTR_LA	v0, CKSEG1 + A_IMR_CPU0_BASE
+#ifdef CONFIG_SMP
+	lw	t1, TI_CPU($28)
+	sll	t1, IMR_REGISTER_SPACING_SHIFT
+	addu	v0, t1
+#endif
+	ld	s0, R_IMR_INTERRUPT_STATUS_BASE(v0)	/* read IP[2] status */
+
+	beqz	s0, 4f		/* No interrupts.  Return */
+	 move	a1, sp
+
+3:	dclz	s1, s0		/* Find the next interrupt */
+	dsubu	a0, zero, s1
+	daddiu	a0, a0, 63
+	jal	 do_IRQ
+	 nop
+
+4:	j        ret_from_irq
+	 nop
+
+	.set pop
+	END(sb1250_irq_handler)
diff --git a/arch/mips/sibyte/sb1250/prom.c b/arch/mips/sibyte/sb1250/prom.c
new file mode 100644
index 0000000..de62ab0
--- /dev/null
+++ b/arch/mips/sibyte/sb1250/prom.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/blkdev.h>
+#include <linux/bootmem.h>
+#include <linux/smp.h>
+#include <linux/initrd.h>
+
+#include <asm/bootinfo.h>
+#include <asm/reboot.h>
+
+#define MAX_RAM_SIZE ((CONFIG_SIBYTE_STANDALONE_RAM_SIZE * 1024 * 1024) - 1)
+
+static __init void prom_meminit(void)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+	unsigned long initrd_pstart;
+	unsigned long initrd_pend;
+
+	initrd_pstart = __pa(initrd_start);
+	initrd_pend = __pa(initrd_end);
+	if (initrd_start &&
+	    ((initrd_pstart > MAX_RAM_SIZE)
+	     || (initrd_pend > MAX_RAM_SIZE))) {
+		panic("initrd out of addressable memory");
+	}
+
+	add_memory_region(0, initrd_pstart,
+			  BOOT_MEM_RAM);
+	add_memory_region(initrd_pstart, initrd_pend - initrd_pstart,
+			  BOOT_MEM_RESERVED);
+	add_memory_region(initrd_pend,
+			  (CONFIG_SIBYTE_STANDALONE_RAM_SIZE * 1024 * 1024) - initrd_pend,
+			  BOOT_MEM_RAM);
+#else
+	add_memory_region(0, CONFIG_SIBYTE_STANDALONE_RAM_SIZE * 1024 * 1024,
+			  BOOT_MEM_RAM);
+#endif
+}
+
+void prom_cpu0_exit(void *unused)
+{
+        while (1) ;
+}
+
+static void prom_linux_exit(void)
+{
+#ifdef CONFIG_SMP
+	if (smp_processor_id()) {
+		smp_call_function(prom_cpu0_exit,NULL,1,1);
+	}
+#endif
+	while(1);
+}
+
+/*
+ * prom_init is called just after the cpu type is determined, from setup_arch()
+ */
+void __init prom_init(void)
+{
+	_machine_restart   = (void (*)(char *))prom_linux_exit;
+	_machine_halt      = prom_linux_exit;
+	_machine_power_off = prom_linux_exit;
+
+	strcpy(arcs_cmdline, "root=/dev/ram0 ");
+
+	mips_machgroup = MACH_GROUP_SIBYTE;
+	prom_meminit();
+}
+
+unsigned long __init prom_free_prom_memory(void)
+{
+	/* Not sure what I'm supposed to do here.  Nothing, I think */
+	return 0;
+}
+
+void prom_putchar(char c)
+{
+}
diff --git a/arch/mips/sibyte/sb1250/setup.c b/arch/mips/sibyte/sb1250/setup.c
new file mode 100644
index 0000000..f8c605b
--- /dev/null
+++ b/arch/mips/sibyte/sb1250/setup.c
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
+#include <asm/io.h>
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_scd.h>
+
+unsigned int sb1_pass;
+unsigned int soc_pass;
+unsigned int soc_type;
+unsigned int periph_rev;
+unsigned int zbbus_mhz;
+
+static char *soc_str;
+static char *pass_str;
+static unsigned int war_pass;	/* XXXKW don't overload PASS defines? */
+
+static inline int setup_bcm1250(void);
+static inline int setup_bcm112x(void);
+
+/* Setup code likely to be common to all SiByte platforms */
+
+static inline int sys_rev_decode(void)
+{
+	int ret = 0;
+
+	war_pass = soc_pass;
+	switch (soc_type) {
+	case K_SYS_SOC_TYPE_BCM1250:
+	case K_SYS_SOC_TYPE_BCM1250_ALT:
+	case K_SYS_SOC_TYPE_BCM1250_ALT2:
+		soc_str = "BCM1250";
+		ret = setup_bcm1250();
+		break;
+	case K_SYS_SOC_TYPE_BCM1120:
+		soc_str = "BCM1120";
+		ret = setup_bcm112x();
+		break;
+	case K_SYS_SOC_TYPE_BCM1125:
+		soc_str = "BCM1125";
+		ret = setup_bcm112x();
+		break;
+	case K_SYS_SOC_TYPE_BCM1125H:
+		soc_str = "BCM1125H";
+		ret = setup_bcm112x();
+		break;
+	default:
+		prom_printf("Unknown SOC type %x\n", soc_type);
+		ret = 1;
+		break;
+	}
+	return ret;
+}
+
+static inline int setup_bcm1250(void)
+{
+	int ret = 0;
+
+	switch (soc_pass) {
+	case K_SYS_REVISION_BCM1250_PASS1:
+		periph_rev = 1;
+		pass_str = "Pass 1";
+		break;
+	case K_SYS_REVISION_BCM1250_A10:
+		periph_rev = 2;
+		pass_str = "A8/A10";
+		/* XXXKW different war_pass? */
+		war_pass = K_SYS_REVISION_BCM1250_PASS2;
+		break;
+	case K_SYS_REVISION_BCM1250_PASS2_2:
+		periph_rev = 2;
+		pass_str = "B1";
+		break;
+	case K_SYS_REVISION_BCM1250_B2:
+		periph_rev = 2;
+		pass_str = "B2";
+		war_pass = K_SYS_REVISION_BCM1250_PASS2_2;
+		break;
+	case K_SYS_REVISION_BCM1250_PASS3:
+		periph_rev = 3;
+		pass_str = "C0";
+		break;
+	case K_SYS_REVISION_BCM1250_C1:
+		periph_rev = 3;
+		pass_str = "C1";
+		break;
+	default:
+		if (soc_pass < K_SYS_REVISION_BCM1250_PASS2_2) {
+			periph_rev = 2;
+			pass_str = "A0-A6";
+			war_pass = K_SYS_REVISION_BCM1250_PASS2;
+		} else {
+			prom_printf("Unknown BCM1250 rev %x\n", soc_pass);
+			ret = 1;
+		}
+		break;
+	}
+	return ret;
+}
+
+static inline int setup_bcm112x(void)
+{
+	int ret = 0;
+
+	switch (soc_pass) {
+	case 0:
+		/* Early build didn't have revid set */
+		periph_rev = 3;
+		pass_str = "A1";
+		war_pass = K_SYS_REVISION_BCM112x_A1;
+		break;
+	case K_SYS_REVISION_BCM112x_A1:
+		periph_rev = 3;
+		pass_str = "A1";
+		break;
+	case K_SYS_REVISION_BCM112x_A2:
+		periph_rev = 3;
+		pass_str = "A2";
+		break;
+	default:
+		prom_printf("Unknown %s rev %x\n", soc_str, soc_pass);
+		ret = 1;
+	}
+	return ret;
+}
+
+void sb1250_setup(void)
+{
+	uint64_t sys_rev;
+	int plldiv;
+	int bad_config = 0;
+
+	sb1_pass = read_c0_prid() & 0xff;
+	sys_rev = bus_readq(IOADDR(A_SCD_SYSTEM_REVISION));
+	soc_type = SYS_SOC_TYPE(sys_rev);
+	soc_pass = G_SYS_REVISION(sys_rev);
+
+	if (sys_rev_decode()) {
+		prom_printf("Restart after failure to identify SiByte chip\n");
+		machine_restart(NULL);
+	}
+
+	plldiv = G_SYS_PLL_DIV(bus_readq(IOADDR(A_SCD_SYSTEM_CFG)));
+	zbbus_mhz = ((plldiv >> 1) * 50) + ((plldiv & 1) * 25);
+
+	prom_printf("Broadcom SiByte %s %s @ %d MHz (SB1 rev %d)\n",
+		    soc_str, pass_str, zbbus_mhz * 2, sb1_pass);
+	prom_printf("Board type: %s\n", get_system_type());
+
+	switch(war_pass) {
+	case K_SYS_REVISION_BCM1250_PASS1:
+#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS
+		prom_printf("@@@@ This is a BCM1250 A0-A2 (Pass 1) board, and the kernel doesn't have the proper workarounds compiled in. @@@@\n");
+		bad_config = 1;
+#endif
+		break;
+	case K_SYS_REVISION_BCM1250_PASS2:
+		/* Pass 2 - easiest as default for now - so many numbers */
+#if !defined(CONFIG_SB1_PASS_2_WORKAROUNDS) || !defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS)
+		prom_printf("@@@@ This is a BCM1250 A3-A10 board, and the kernel doesn't have the proper workarounds compiled in. @@@@\n");
+		bad_config = 1;
+#endif
+#ifdef CONFIG_CPU_HAS_PREFETCH
+		prom_printf("@@@@ Prefetches may be enabled in this kernel, but are buggy on this board.  @@@@\n");
+		bad_config = 1;
+#endif
+		break;
+	case K_SYS_REVISION_BCM1250_PASS2_2:
+#ifndef CONFIG_SB1_PASS_2_WORKAROUNDS
+		prom_printf("@@@@ This is a BCM1250 B1/B2. board, and the kernel doesn't have the proper workarounds compiled in. @@@@\n");
+		bad_config = 1;
+#endif
+#if defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS) || !defined(CONFIG_CPU_HAS_PREFETCH)
+		prom_printf("@@@@ This is a BCM1250 B1/B2, but the kernel is conservatively configured for an 'A' stepping. @@@@\n");
+#endif
+		break;
+	default:
+		break;
+	}
+	if (bad_config) {
+		prom_printf("Invalid configuration for this chip.\n");
+		machine_restart(NULL);
+	}
+}
diff --git a/arch/mips/sibyte/sb1250/smp.c b/arch/mips/sibyte/sb1250/smp.c
new file mode 100644
index 0000000..be91b39
--- /dev/null
+++ b/arch/mips/sibyte/sb1250/smp.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2001, 2002, 2003 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/smp.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_int.h>
+
+static void *mailbox_set_regs[] = {
+	(void *)IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_SET_CPU),
+	(void *)IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_SET_CPU)
+};
+
+static void *mailbox_clear_regs[] = {
+	(void *)IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_CLR_CPU),
+	(void *)IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_CLR_CPU)
+};
+
+static void *mailbox_regs[] = {
+	(void *)IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_CPU),
+	(void *)IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_CPU)
+};
+
+/*
+ * SMP init and finish on secondary CPUs
+ */
+void sb1250_smp_init(void)
+{
+	unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
+		STATUSF_IP1 | STATUSF_IP0;
+
+	/* Set interrupt mask, but don't enable */
+	change_c0_status(ST0_IM, imask);
+}
+
+void sb1250_smp_finish(void)
+{
+	extern void sb1250_time_init(void);
+	sb1250_time_init();
+	local_irq_enable();
+}
+
+/*
+ * These are routines for dealing with the sb1250 smp capabilities
+ * independent of board/firmware
+ */
+
+/*
+ * Simple enough; everything is set up, so just poke the appropriate mailbox
+ * register, and we should be set
+ */
+void core_send_ipi(int cpu, unsigned int action)
+{
+	bus_writeq((((u64)action) << 48), mailbox_set_regs[cpu]);
+}
+
+void sb1250_mailbox_interrupt(struct pt_regs *regs)
+{
+	int cpu = smp_processor_id();
+	unsigned int action;
+
+	kstat_this_cpu.irqs[K_INT_MBOX_0]++;
+	/* Load the mailbox register to figure out what we're supposed to do */
+	action = (__bus_readq(mailbox_regs[cpu]) >> 48) & 0xffff;
+
+	/* Clear the mailbox to clear the interrupt */
+	__bus_writeq(((u64)action) << 48, mailbox_clear_regs[cpu]);
+
+	/*
+	 * Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the
+	 * interrupt will do the reschedule for us
+	 */
+
+	if (action & SMP_CALL_FUNCTION)
+		smp_call_function_interrupt();
+}
diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c
new file mode 100644
index 0000000..8b4c848
--- /dev/null
+++ b/arch/mips/sibyte/sb1250/time.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * These are routines to set up and handle interrupts from the
+ * sb1250 general purpose timer 0.  We're using the timer as a
+ * system clock, so we set it up to run at 100 Hz.  On every
+ * interrupt, we update our idea of what the time of day is,
+ * then call do_timer() in the architecture-independent kernel
+ * code to do general bookkeeping (e.g. update jiffies, run
+ * bottom halves, etc.)
+ */
+#include <linux/config.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/irq.h>
+#include <asm/ptrace.h>
+#include <asm/addrspace.h>
+#include <asm/time.h>
+#include <asm/io.h>
+
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_int.h>
+#include <asm/sibyte/sb1250_scd.h>
+
+
+#define IMR_IP2_VAL	K_INT_MAP_I0
+#define IMR_IP3_VAL	K_INT_MAP_I1
+#define IMR_IP4_VAL	K_INT_MAP_I2
+
+extern int sb1250_steal_irq(int irq);
+
+void sb1250_time_init(void)
+{
+	int cpu = smp_processor_id();
+	int irq = K_INT_TIMER_0+cpu;
+
+	/* Only have 4 general purpose timers */
+	if (cpu > 3) {
+		BUG();
+	}
+
+	if (!cpu) {
+		/* Use our own gettimeoffset() routine */
+		do_gettimeoffset = sb1250_gettimeoffset;
+	}
+
+	sb1250_mask_irq(cpu, irq);
+
+	/* Map the timer interrupt to ip[4] of this cpu */
+	bus_writeq(IMR_IP4_VAL,
+		   IOADDR(A_IMR_REGISTER(cpu, R_IMR_INTERRUPT_MAP_BASE) +
+			  (irq << 3)));
+
+	/* the general purpose timer ticks at 1 Mhz independent if the rest of the system */
+	/* Disable the timer and set up the count */
+	bus_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+#ifdef CONFIG_SIMULATION
+	bus_writeq(50000 / HZ,
+		   IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
+#else
+	bus_writeq(1000000/HZ,
+		   IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
+#endif
+
+	/* Set the timer running */
+	bus_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
+		   IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+
+	sb1250_unmask_irq(cpu, irq);
+	sb1250_steal_irq(irq);
+	/*
+	 * This interrupt is "special" in that it doesn't use the request_irq
+	 * way to hook the irq line.  The timer interrupt is initialized early
+	 * enough to make this a major pain, and it's also firing enough to
+	 * warrant a bit of special case code.  sb1250_timer_interrupt is
+	 * called directly from irq_handler.S when IP[4] is set during an
+	 * interrupt
+	 */
+}
+
+void sb1250_timer_interrupt(struct pt_regs *regs)
+{
+	extern asmlinkage void ll_local_timer_interrupt(int irq, struct pt_regs *regs);
+	int cpu = smp_processor_id();
+	int irq = K_INT_TIMER_0 + cpu;
+
+	/* Reset the timer */
+	__bus_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
+		     IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+
+	/*
+	 * CPU 0 handles the global timer interrupt job
+	 */
+	if (cpu == 0) {
+		ll_timer_interrupt(irq, regs);
+	}
+
+	/*
+	 * every CPU should do profiling and process accouting
+	 */
+	ll_local_timer_interrupt(irq, regs);
+}
+
+/*
+ * We use our own do_gettimeoffset() instead of the generic one,
+ * because the generic one does not work for SMP case.
+ * In addition, since we use general timer 0 for system time,
+ * we can get accurate intra-jiffy offset without calibration.
+ */
+unsigned long sb1250_gettimeoffset(void)
+{
+	unsigned long count =
+		bus_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT)));
+
+	return 1000000/HZ - count;
+ }
diff --git a/arch/mips/sibyte/swarm/Makefile b/arch/mips/sibyte/swarm/Makefile
new file mode 100644
index 0000000..2d62603
--- /dev/null
+++ b/arch/mips/sibyte/swarm/Makefile
@@ -0,0 +1,3 @@
+lib-y				= setup.o rtc_xicor1241.o rtc_m41t81.o
+
+lib-$(CONFIG_KGDB)		+= dbg_io.o
diff --git a/arch/mips/sibyte/swarm/dbg_io.c b/arch/mips/sibyte/swarm/dbg_io.c
new file mode 100644
index 0000000..75ce14c
--- /dev/null
+++ b/arch/mips/sibyte/swarm/dbg_io.c
@@ -0,0 +1,76 @@
+/*
+ * kgdb debug routines for SiByte boards.
+ *
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+/* -------------------- BEGINNING OF CONFIG --------------------- */
+
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_uart.h>
+#include <asm/sibyte/sb1250_int.h>
+#include <asm/addrspace.h>
+
+/*
+ * We use the second serial port for kgdb traffic.
+ * 	115200, 8, N, 1.
+ */
+
+#define	BAUD_RATE		115200
+#define	CLK_DIVISOR		V_DUART_BAUD_RATE(BAUD_RATE)
+#define	DATA_BITS		V_DUART_BITS_PER_CHAR_8		/* or 7    */
+#define	PARITY			V_DUART_PARITY_MODE_NONE	/* or even */
+#define	STOP_BITS		M_DUART_STOP_BIT_LEN_1		/* or 2    */
+
+static int duart_initialized = 0;	/* 0: need to be init'ed by kgdb */
+
+/* -------------------- END OF CONFIG --------------------- */
+extern int kgdb_port;
+
+#define	duart_out(reg, val)	csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port,reg)))
+#define duart_in(reg)		csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port,reg)))
+
+void putDebugChar(unsigned char c);
+unsigned char getDebugChar(void);
+static void
+duart_init(int clk_divisor, int data, int parity, int stop)
+{
+	duart_out(R_DUART_MODE_REG_1, data | parity);
+	duart_out(R_DUART_MODE_REG_2, stop);
+	duart_out(R_DUART_CLK_SEL, clk_divisor);
+
+	duart_out(R_DUART_CMD, M_DUART_RX_EN | M_DUART_TX_EN);	/* enable rx and tx */
+}
+
+void
+putDebugChar(unsigned char c)
+{
+	if (!duart_initialized) {
+		duart_initialized = 1;
+		duart_init(CLK_DIVISOR, DATA_BITS, PARITY, STOP_BITS);
+	}
+	while ((duart_in(R_DUART_STATUS) & M_DUART_TX_RDY) == 0);
+	duart_out(R_DUART_TX_HOLD, c);
+}
+
+unsigned char
+getDebugChar(void)
+{
+	if (!duart_initialized) {
+		duart_initialized = 1;
+		duart_init(CLK_DIVISOR, DATA_BITS, PARITY, STOP_BITS);
+	}
+	while ((duart_in(R_DUART_STATUS) & M_DUART_RX_RDY) == 0) ;
+	return duart_in(R_DUART_RX_HOLD);
+}
+
diff --git a/arch/mips/sibyte/swarm/rtc_m41t81.c b/arch/mips/sibyte/swarm/rtc_m41t81.c
new file mode 100644
index 0000000..0e633ee
--- /dev/null
+++ b/arch/mips/sibyte/swarm/rtc_m41t81.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom Corporation
+ *
+ * Copyright (C) 2002 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute	it and/or modify it
+ * under  the terms of	the GNU General	 Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+#include <linux/bcd.h>
+#include <linux/types.h>
+#include <linux/time.h>
+
+#include <asm/time.h>
+#include <asm/addrspace.h>
+#include <asm/io.h>
+
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_smbus.h>
+
+
+/* M41T81 definitions */
+
+/*
+ * Register bits
+ */
+
+#define M41T81REG_SC_ST		0x80		/* stop bit */
+#define M41T81REG_HR_CB		0x40		/* century bit */
+#define M41T81REG_HR_CEB	0x80		/* century enable bit */
+#define M41T81REG_CTL_S		0x20		/* sign bit */
+#define M41T81REG_CTL_FT	0x40		/* frequency test bit */
+#define M41T81REG_CTL_OUT	0x80		/* output level */
+#define M41T81REG_WD_RB0	0x01		/* watchdog resolution bit 0 */
+#define M41T81REG_WD_RB1	0x02		/* watchdog resolution bit 1 */
+#define M41T81REG_WD_BMB0	0x04		/* watchdog multiplier bit 0 */
+#define M41T81REG_WD_BMB1	0x08		/* watchdog multiplier bit 1 */
+#define M41T81REG_WD_BMB2	0x10		/* watchdog multiplier bit 2 */
+#define M41T81REG_WD_BMB3	0x20		/* watchdog multiplier bit 3 */
+#define M41T81REG_WD_BMB4	0x40		/* watchdog multiplier bit 4 */
+#define M41T81REG_AMO_ABE	0x20		/* alarm in "battery back-up mode" enable bit */
+#define M41T81REG_AMO_SQWE	0x40		/* square wave enable */
+#define M41T81REG_AMO_AFE	0x80		/* alarm flag enable flag */
+#define M41T81REG_ADT_RPT5	0x40		/* alarm repeat mode bit 5 */
+#define M41T81REG_ADT_RPT4	0x80		/* alarm repeat mode bit 4 */
+#define M41T81REG_AHR_RPT3	0x80		/* alarm repeat mode bit 3 */
+#define M41T81REG_AHR_HT	0x40		/* halt update bit */
+#define M41T81REG_AMN_RPT2	0x80		/* alarm repeat mode bit 2 */
+#define M41T81REG_ASC_RPT1	0x80		/* alarm repeat mode bit 1 */
+#define M41T81REG_FLG_AF	0x40		/* alarm flag (read only) */
+#define M41T81REG_FLG_WDF	0x80		/* watchdog flag (read only) */
+#define M41T81REG_SQW_RS0	0x10		/* sqw frequency bit 0 */
+#define M41T81REG_SQW_RS1	0x20		/* sqw frequency bit 1 */
+#define M41T81REG_SQW_RS2	0x40		/* sqw frequency bit 2 */
+#define M41T81REG_SQW_RS3	0x80		/* sqw frequency bit 3 */
+
+
+/*
+ * Register numbers
+ */
+
+#define M41T81REG_TSC	0x00		/* tenths/hundredths of second */
+#define M41T81REG_SC	0x01		/* seconds */
+#define M41T81REG_MN	0x02		/* minute */
+#define M41T81REG_HR	0x03		/* hour/century */
+#define M41T81REG_DY	0x04		/* day of week */
+#define M41T81REG_DT	0x05		/* date of month */
+#define M41T81REG_MO	0x06		/* month */
+#define M41T81REG_YR	0x07		/* year */
+#define M41T81REG_CTL	0x08		/* control */
+#define M41T81REG_WD	0x09		/* watchdog */
+#define M41T81REG_AMO	0x0A		/* alarm: month */
+#define M41T81REG_ADT	0x0B		/* alarm: date */
+#define M41T81REG_AHR	0x0C		/* alarm: hour */
+#define M41T81REG_AMN	0x0D		/* alarm: minute */
+#define M41T81REG_ASC	0x0E		/* alarm: second */
+#define M41T81REG_FLG	0x0F		/* flags */
+#define M41T81REG_SQW	0x13		/* square wave register */
+
+#define M41T81_CCR_ADDRESS	0x68
+#define SMB_CSR(reg) ((u8 *) (IOADDR(A_SMB_REGISTER(1, reg))))
+
+static int m41t81_read(uint8_t addr)
+{
+	while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+		;
+
+	bus_writeq(addr & 0xff, SMB_CSR(R_SMB_CMD));
+	bus_writeq((V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR1BYTE),
+		   SMB_CSR(R_SMB_START));
+
+	while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+		;
+
+	bus_writeq((V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE),
+		   SMB_CSR(R_SMB_START));
+
+	while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+		;
+
+	if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+		/* Clear error bit by writing a 1 */
+		bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+		return -1;
+	}
+
+	return (bus_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
+}
+
+static int m41t81_write(uint8_t addr, int b)
+{
+	while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+		;
+
+	bus_writeq((addr & 0xFF), SMB_CSR(R_SMB_CMD));
+	bus_writeq((b & 0xff), SMB_CSR(R_SMB_DATA));
+	bus_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR2BYTE,
+		   SMB_CSR(R_SMB_START));
+
+	while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+		;
+
+	if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+		/* Clear error bit by writing a 1 */
+		bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+		return -1;
+	} 
+
+	/* read the same byte again to make sure it is written */
+	bus_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE,
+		   SMB_CSR(R_SMB_START));
+
+	while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+		;
+	
+	return 0;
+}
+
+int m41t81_set_time(unsigned long t)
+{
+	struct rtc_time tm;
+
+	to_tm(t, &tm);
+
+	/*
+	 * Note the write order matters as it ensures the correctness.
+	 * When we write sec, 10th sec is clear.  It is reasonable to 
+	 * believe we should finish writing min within a second.
+	 */
+
+	tm.tm_sec = BIN2BCD(tm.tm_sec);
+	m41t81_write(M41T81REG_SC, tm.tm_sec);
+	
+	tm.tm_min = BIN2BCD(tm.tm_min);
+	m41t81_write(M41T81REG_MN, tm.tm_min);
+
+	tm.tm_hour = BIN2BCD(tm.tm_hour);
+	tm.tm_hour = (tm.tm_hour & 0x3f) | (m41t81_read(M41T81REG_HR) & 0xc0);
+	m41t81_write(M41T81REG_HR, tm.tm_hour);
+
+	/* tm_wday starts from 0 to 6 */
+	if (tm.tm_wday == 0) tm.tm_wday = 7;
+	tm.tm_wday = BIN2BCD(tm.tm_wday);
+	m41t81_write(M41T81REG_DY, tm.tm_wday);
+
+	tm.tm_mday = BIN2BCD(tm.tm_mday);
+	m41t81_write(M41T81REG_DT, tm.tm_mday);
+
+	/* tm_mon starts from 0, *ick* */
+	tm.tm_mon ++;
+	tm.tm_mon = BIN2BCD(tm.tm_mon);
+	m41t81_write(M41T81REG_MO, tm.tm_mon);
+
+	/* we don't do century, everything is beyond 2000 */
+	tm.tm_year %= 100;
+	tm.tm_year = BIN2BCD(tm.tm_year);
+	m41t81_write(M41T81REG_YR, tm.tm_year);
+
+	return 0;
+}
+
+unsigned long m41t81_get_time(void)
+{
+	unsigned int year, mon, day, hour, min, sec;
+
+	/* 
+	 * min is valid if two reads of sec are the same.
+	 */
+	for (;;) {
+		sec = m41t81_read(M41T81REG_SC);
+		min = m41t81_read(M41T81REG_MN);
+		if (sec == m41t81_read(M41T81REG_SC)) break;
+	}
+	hour = m41t81_read(M41T81REG_HR) & 0x3f;
+	day = m41t81_read(M41T81REG_DT);
+	mon = m41t81_read(M41T81REG_MO);
+	year = m41t81_read(M41T81REG_YR);
+
+	sec = BCD2BIN(sec);
+	min = BCD2BIN(min);
+	hour = BCD2BIN(hour);
+	day = BCD2BIN(day);
+	mon = BCD2BIN(mon);
+	year = BCD2BIN(year);
+
+	year += 2000;
+
+	return mktime(year, mon, day, hour, min, sec);
+}
+
+int m41t81_probe(void)
+{
+	unsigned int tmp;
+
+	/* enable chip if it is not enabled yet */
+	tmp = m41t81_read(M41T81REG_SC);
+	m41t81_write(M41T81REG_SC, tmp & 0x7f);
+
+	return (m41t81_read(M41T81REG_SC) != -1);
+}
diff --git a/arch/mips/sibyte/swarm/rtc_xicor1241.c b/arch/mips/sibyte/swarm/rtc_xicor1241.c
new file mode 100644
index 0000000..981d21f
--- /dev/null
+++ b/arch/mips/sibyte/swarm/rtc_xicor1241.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom Corporation
+ *
+ * Copyright (C) 2002 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/bcd.h>
+#include <linux/types.h>
+#include <linux/time.h>
+
+#include <asm/time.h>
+#include <asm/addrspace.h>
+#include <asm/io.h>
+
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_smbus.h>
+
+
+/* Xicor 1241 definitions */
+
+/*
+ * Register bits
+ */
+
+#define X1241REG_SR_BAT	0x80		/* currently on battery power */
+#define X1241REG_SR_RWEL 0x04		/* r/w latch is enabled, can write RTC */
+#define X1241REG_SR_WEL 0x02		/* r/w latch is unlocked, can enable r/w now */
+#define X1241REG_SR_RTCF 0x01		/* clock failed */
+#define X1241REG_BL_BP2 0x80		/* block protect 2 */
+#define X1241REG_BL_BP1 0x40		/* block protect 1 */
+#define X1241REG_BL_BP0 0x20		/* block protect 0 */
+#define X1241REG_BL_WD1	0x10
+#define X1241REG_BL_WD0	0x08
+#define X1241REG_HR_MIL 0x80		/* military time format */
+
+/*
+ * Register numbers
+ */
+
+#define X1241REG_BL	0x10		/* block protect bits */
+#define X1241REG_INT	0x11		/*  */
+#define X1241REG_SC	0x30		/* Seconds */
+#define X1241REG_MN	0x31		/* Minutes */
+#define X1241REG_HR	0x32		/* Hours */
+#define X1241REG_DT	0x33		/* Day of month */
+#define X1241REG_MO	0x34		/* Month */
+#define X1241REG_YR	0x35		/* Year */
+#define X1241REG_DW	0x36		/* Day of Week */
+#define X1241REG_Y2K	0x37		/* Year 2K */
+#define X1241REG_SR	0x3F		/* Status register */
+
+#define X1241_CCR_ADDRESS	0x6F
+
+#define SMB_CSR(reg) ((u8 *) (IOADDR(A_SMB_REGISTER(1, reg))))
+
+static int xicor_read(uint8_t addr)
+{
+        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                ;
+
+	bus_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
+	bus_writeq((addr & 0xff), SMB_CSR(R_SMB_DATA));
+	bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE),
+		   SMB_CSR(R_SMB_START));
+
+        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                ;
+
+	bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE),
+		   SMB_CSR(R_SMB_START));
+
+        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                ;
+
+        if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+                /* Clear error bit by writing a 1 */
+                bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+                return -1;
+        }
+
+	return (bus_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
+}
+
+static int xicor_write(uint8_t addr, int b)
+{
+        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                ;
+
+	bus_writeq(addr, SMB_CSR(R_SMB_CMD));
+	bus_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
+	bus_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
+		   SMB_CSR(R_SMB_START));
+
+        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                ;
+
+        if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+                /* Clear error bit by writing a 1 */
+                bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+                return -1;
+        } else {
+		return 0;
+	}
+}
+
+int xicor_set_time(unsigned long t)
+{
+	struct rtc_time tm;
+	int tmp;
+
+	to_tm(t, &tm);
+
+	/* unlock writes to the CCR */
+	xicor_write(X1241REG_SR, X1241REG_SR_WEL);
+	xicor_write(X1241REG_SR, X1241REG_SR_WEL | X1241REG_SR_RWEL);
+
+	/* trivial ones */
+	tm.tm_sec = BIN2BCD(tm.tm_sec);
+	xicor_write(X1241REG_SC, tm.tm_sec);
+
+	tm.tm_min = BIN2BCD(tm.tm_min);
+	xicor_write(X1241REG_MN, tm.tm_min);
+
+	tm.tm_mday = BIN2BCD(tm.tm_mday);
+	xicor_write(X1241REG_DT, tm.tm_mday);
+
+	/* tm_mon starts from 0, *ick* */
+	tm.tm_mon ++;
+	tm.tm_mon = BIN2BCD(tm.tm_mon);
+	xicor_write(X1241REG_MO, tm.tm_mon);
+
+	/* year is split */
+	tmp = tm.tm_year / 100;
+	tm.tm_year %= 100;
+	xicor_write(X1241REG_YR, tm.tm_year);
+	xicor_write(X1241REG_Y2K, tmp);
+
+	/* hour is the most tricky one */
+	tmp = xicor_read(X1241REG_HR);
+	if (tmp & X1241REG_HR_MIL) {
+		/* 24 hour format */
+		tm.tm_hour = BIN2BCD(tm.tm_hour);
+		tmp = (tmp & ~0x3f) | (tm.tm_hour & 0x3f);
+	} else {
+		/* 12 hour format, with 0x2 for pm */
+		tmp = tmp & ~0x3f;
+		if (tm.tm_hour >= 12) {
+			tmp |= 0x20;
+			tm.tm_hour -= 12;
+		}
+		tm.tm_hour = BIN2BCD(tm.tm_hour);
+		tmp |= tm.tm_hour;
+	}
+	xicor_write(X1241REG_HR, tmp);
+
+	xicor_write(X1241REG_SR, 0);
+
+	return 0;
+}
+
+unsigned long xicor_get_time(void)
+{
+	unsigned int year, mon, day, hour, min, sec, y2k;
+
+	sec = xicor_read(X1241REG_SC);
+	min = xicor_read(X1241REG_MN);
+	hour = xicor_read(X1241REG_HR);
+
+	if (hour & X1241REG_HR_MIL) {
+		hour &= 0x3f;
+	} else {
+		if (hour & 0x20)
+			hour = (hour & 0xf) + 0x12;
+	}
+
+	day = xicor_read(X1241REG_DT);
+	mon = xicor_read(X1241REG_MO);
+	year = xicor_read(X1241REG_YR);
+	y2k = xicor_read(X1241REG_Y2K);
+
+	sec = BCD2BIN(sec);
+	min = BCD2BIN(min);
+	hour = BCD2BIN(hour);
+	day = BCD2BIN(day);
+	mon = BCD2BIN(mon);
+	year = BCD2BIN(year);
+	y2k = BCD2BIN(y2k);
+
+	year += (y2k * 100);
+
+	return mktime(year, mon, day, hour, min, sec);
+}
+
+int xicor_probe(void)
+{
+	return (xicor_read(X1241REG_SC) != -1);
+}
diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c
new file mode 100644
index 0000000..457aeb7
--- /dev/null
+++ b/arch/mips/sibyte/swarm/setup.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * Setup code for the SWARM board
+ */
+
+#include <linux/config.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/blkdev.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+#include <linux/initrd.h>
+
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/time.h>
+#include <asm/traps.h>
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_genbus.h>
+#include <asm/sibyte/board.h>
+
+extern void sb1250_setup(void);
+
+extern int xicor_probe(void);
+extern int xicor_set_time(unsigned long);
+extern unsigned long xicor_get_time(void);
+
+extern int m41t81_probe(void);
+extern int m41t81_set_time(unsigned long);
+extern unsigned long m41t81_get_time(void);
+
+const char *get_system_type(void)
+{
+	return "SiByte " SIBYTE_BOARD_NAME;
+}
+
+void __init swarm_timer_setup(struct irqaction *irq)
+{
+        /*
+         * we don't set up irqaction, because we will deliver timer
+         * interrupts through low-level (direct) meachanism.
+         */
+
+        /* We only need to setup the generic timer */
+        sb1250_time_init();
+}
+
+int swarm_be_handler(struct pt_regs *regs, int is_fixup)
+{
+	if (!is_fixup && (regs->cp0_cause & 4)) {
+		/* Data bus error - print PA */
+#ifdef CONFIG_MIPS64
+		printk("DBE physical address: %010lx\n",
+		       __read_64bit_c0_register($26, 1));
+#else
+		printk("DBE physical address: %010llx\n",
+		       __read_64bit_c0_split($26, 1));
+#endif
+	}
+	return (is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL);
+}
+
+static int __init swarm_setup(void)
+{
+	sb1250_setup();
+
+	panic_timeout = 5;  /* For debug.  */
+
+	board_timer_setup = swarm_timer_setup;
+	board_be_handler = swarm_be_handler;
+
+	if (xicor_probe()) {
+		printk("swarm setup: Xicor 1241 RTC detected.\n");
+		rtc_get_time = xicor_get_time;
+		rtc_set_time = xicor_set_time;
+	}
+ 
+	if (m41t81_probe()) {
+		printk("swarm setup: M41T81 RTC detected.\n");
+		rtc_get_time = m41t81_get_time;
+		rtc_set_time = m41t81_set_time;
+	}
+
+	printk("This kernel optimized for "
+#ifdef CONFIG_SIMULATION
+	       "simulation"
+#else
+	       "board"
+#endif
+	       " runs "
+#ifdef CONFIG_SIBYTE_CFE
+	       "with"
+#else
+	       "without"
+#endif
+	       " CFE\n");
+
+#ifdef CONFIG_VT
+	screen_info = (struct screen_info) {
+		0, 0,           /* orig-x, orig-y */
+		0,              /* unused */
+		52,             /* orig_video_page */
+		3,              /* orig_video_mode */
+		80,             /* orig_video_cols */
+		4626, 3, 9,     /* unused, ega_bx, unused */
+		25,             /* orig_video_lines */
+		0x22,           /* orig_video_isVGA */
+		16              /* orig_video_points */
+       };
+       /* XXXKW for CFE, get lines/cols from environment */
+#endif
+
+	return 0;
+}
+
+early_initcall(swarm_setup);
+
+#ifdef LEDS_PHYS
+
+#ifdef CONFIG_SIBYTE_CARMEL
+/* XXXKW need to detect Monterey/LittleSur/etc */
+#undef LEDS_PHYS
+#define LEDS_PHYS MLEDS_PHYS
+#endif
+
+#define setled(index, c) \
+  ((unsigned char *)(IOADDR(LEDS_PHYS)+0x20))[(3-(index))<<3] = (c)
+void setleds(char *str)
+{
+	int i;
+	for (i = 0; i < 4; i++) {
+		if (!str[i]) {
+			setled(i, ' ');
+		} else {
+			setled(i, str[i]);
+		}
+	}
+}
+#endif
diff --git a/arch/mips/sibyte/swarm/time.c b/arch/mips/sibyte/swarm/time.c
new file mode 100644
index 0000000..c1f1a9de
--- /dev/null
+++ b/arch/mips/sibyte/swarm/time.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * Time routines for the swarm board.  We pass all the hard stuff
+ * through to the sb1250 handling code.  Only thing we really keep
+ * track of here is what time of day we think it is.  And we don't
+ * really even do a good job of that...
+ */
+
+
+#include <linux/bcd.h>
+#include <linux/init.h>
+#include <linux/time.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <asm/system.h>
+#include <asm/addrspace.h>
+#include <asm/io.h>
+
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_smbus.h>
+
+static unsigned long long sec_bias = 0;
+static unsigned int usec_bias = 0;
+
+/* Xicor 1241 definitions */
+
+/*
+ * Register bits
+ */
+
+#define X1241REG_SR_BAT	0x80		/* currently on battery power */
+#define X1241REG_SR_RWEL 0x04		/* r/w latch is enabled, can write RTC */
+#define X1241REG_SR_WEL 0x02		/* r/w latch is unlocked, can enable r/w now */
+#define X1241REG_SR_RTCF 0x01		/* clock failed */
+#define X1241REG_BL_BP2 0x80		/* block protect 2 */
+#define X1241REG_BL_BP1 0x40		/* block protect 1 */
+#define X1241REG_BL_BP0 0x20		/* block protect 0 */
+#define X1241REG_BL_WD1	0x10
+#define X1241REG_BL_WD0	0x08
+#define X1241REG_HR_MIL 0x80		/* military time format */
+
+/*
+ * Register numbers
+ */
+
+#define X1241REG_BL	0x10		/* block protect bits */
+#define X1241REG_INT	0x11		/*  */
+#define X1241REG_SC	0x30		/* Seconds */
+#define X1241REG_MN	0x31		/* Minutes */
+#define X1241REG_HR	0x32		/* Hours */
+#define X1241REG_DT	0x33		/* Day of month */
+#define X1241REG_MO	0x34		/* Month */
+#define X1241REG_YR	0x35		/* Year */
+#define X1241REG_DW	0x36		/* Day of Week */
+#define X1241REG_Y2K	0x37		/* Year 2K */
+#define X1241REG_SR	0x3F		/* Status register */
+
+#define X1241_CCR_ADDRESS	0x6F
+
+#define SMB_CSR(reg) (IOADDR(A_SMB_REGISTER(1, reg)))
+
+static int xicor_read(uint8_t addr)
+{
+        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                ;
+
+	bus_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
+	bus_writeq((addr & 0xff), SMB_CSR(R_SMB_DATA));
+	bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE),
+		   SMB_CSR(R_SMB_START));
+
+        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                ;
+
+	bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE),
+		   SMB_CSR(R_SMB_START));
+
+        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                ;
+
+        if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+                /* Clear error bit by writing a 1 */
+                bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+                return -1;
+        }
+
+	return (bus_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
+}
+
+static int xicor_write(uint8_t addr, int b)
+{
+        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                ;
+
+	bus_writeq(addr, SMB_CSR(R_SMB_CMD));
+	bus_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
+	bus_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
+		   SMB_CSR(R_SMB_START));
+
+        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                ;
+
+        if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+                /* Clear error bit by writing a 1 */
+                bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+                return -1;
+        } else {
+		return 0;
+	}
+}
+
+/*
+ * In order to set the CMOS clock precisely, set_rtc_mmss has to be
+ * called 500 ms after the second nowtime has started, because when
+ * nowtime is written into the registers of the CMOS clock, it will
+ * jump to the next second precisely 500 ms later. Check the Motorola
+ * MC146818A or Dallas DS12887 data sheet for details.
+ *
+ * BUG: This routine does not handle hour overflow properly; it just
+ *      sets the minutes. Usually you'll only notice that after reboot!
+ */
+int set_rtc_mmss(unsigned long nowtime)
+{
+	int retval = 0;
+	int real_seconds, real_minutes, cmos_minutes;
+
+	cmos_minutes = xicor_read(X1241REG_MN);
+	cmos_minutes = BCD2BIN(cmos_minutes);
+
+	/*
+	 * since we're only adjusting minutes and seconds,
+	 * don't interfere with hour overflow. This avoids
+	 * messing with unknown time zones but requires your
+	 * RTC not to be off by more than 15 minutes
+	 */
+	real_seconds = nowtime % 60;
+	real_minutes = nowtime / 60;
+	if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
+		real_minutes += 30;		/* correct for half hour time zone */
+	real_minutes %= 60;
+
+	/* unlock writes to the CCR */
+	xicor_write(X1241REG_SR, X1241REG_SR_WEL);
+	xicor_write(X1241REG_SR, X1241REG_SR_WEL | X1241REG_SR_RWEL);
+
+	if (abs(real_minutes - cmos_minutes) < 30) {
+		real_seconds = BIN2BCD(real_seconds);
+		real_minutes = BIN2BCD(real_minutes);
+		xicor_write(X1241REG_SC, real_seconds);
+		xicor_write(X1241REG_MN, real_minutes);
+	} else {
+		printk(KERN_WARNING
+		       "set_rtc_mmss: can't update from %d to %d\n",
+		       cmos_minutes, real_minutes);
+		retval = -1;
+	}
+
+	xicor_write(X1241REG_SR, 0);
+
+	printk("set_rtc_mmss: %02d:%02d\n", real_minutes, real_seconds);
+
+	return retval;
+}
+
+static unsigned long __init get_swarm_time(void)
+{
+	unsigned int year, mon, day, hour, min, sec, y2k;
+
+	sec = xicor_read(X1241REG_SC);
+	min = xicor_read(X1241REG_MN);
+	hour = xicor_read(X1241REG_HR);
+
+	if (hour & X1241REG_HR_MIL) {
+		hour &= 0x3f;
+	} else {
+		if (hour & 0x20)
+			hour = (hour & 0xf) + 0x12;
+	}
+
+	sec = BCD2BIN(sec);
+	min = BCD2BIN(min);
+	hour = BCD2BIN(hour);
+
+	day = xicor_read(X1241REG_DT);
+	mon = xicor_read(X1241REG_MO);
+	year = xicor_read(X1241REG_YR);
+	y2k = xicor_read(X1241REG_Y2K);
+
+	day = BCD2BIN(day);
+	mon = BCD2BIN(mon);
+	year = BCD2BIN(year);
+	y2k = BCD2BIN(y2k);
+
+	year += (y2k * 100);
+
+	return mktime(year, mon, day, hour, min, sec);
+}
+
+/*
+ *  Bring up the timer at 100 Hz.
+ */
+void __init swarm_time_init(void)
+{
+	unsigned int flags;
+	int status;
+
+	/* Set up the scd general purpose timer 0 to cpu 0 */
+	sb1250_time_init();
+
+	/* Establish communication with the Xicor 1241 RTC */
+	/* XXXKW how do I share the SMBus with the I2C subsystem? */
+
+	bus_writeq(K_SMB_FREQ_400KHZ, SMB_CSR(R_SMB_FREQ));
+	bus_writeq(0, SMB_CSR(R_SMB_CONTROL));
+
+	if ((status = xicor_read(X1241REG_SR_RTCF)) < 0) {
+		printk("x1241: couldn't detect on SWARM SMBus 1\n");
+	} else {
+		if (status & X1241REG_SR_RTCF)
+			printk("x1241: battery failed -- time is probably wrong\n");
+		write_seqlock_irqsave(&xtime_lock, flags);
+		xtime.tv_sec = get_swarm_time();
+		xtime.tv_nsec = 0;
+		write_sequnlock_irqrestore(&xtime_lock, flags);
+	}
+}
diff --git a/arch/mips/sni/Makefile b/arch/mips/sni/Makefile
new file mode 100644
index 0000000..1e5676e
--- /dev/null
+++ b/arch/mips/sni/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the SNI specific part of the kernel
+#
+
+obj-y	 	+= int-handler.o irq.o pcimt_scache.o reset.o setup.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/sni/int-handler.S b/arch/mips/sni/int-handler.S
new file mode 100644
index 0000000..2cdc09f
--- /dev/null
+++ b/arch/mips/sni/int-handler.S
@@ -0,0 +1,106 @@
+/*
+ * SNI RM200 PCI specific interrupt handler code.
+ *
+ * Copyright (C) 1994, 95, 96, 97, 98, 1999, 2000, 01 by Ralf Baechle
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/sni.h>
+#include <asm/stackframe.h>
+
+/*
+ * The PCI ASIC has the nasty property that it may delay writes if it is busy.
+ * As a consequence from writes that have not graduated when we exit from the
+ * interrupt handler we might catch a spurious interrupt.  To avoid this we
+ * force the PCI ASIC to graduate all writes by executing a read from the
+ * PCI bus.
+ */
+		.set	noreorder
+		.set	noat
+		.align	5
+		NESTED(sni_rm200_pci_handle_int, PT_SIZE, sp)
+		SAVE_ALL
+		CLI
+		.set	at
+
+		/* Blinken light ...  */
+		lb	t0, led_cache
+		addiu	t0, 1
+		sb	t0, led_cache
+		sb	t0, PCIMT_CSLED			# write only register
+		.data
+led_cache:	.byte	0
+		.text
+
+		mfc0	t0, CP0_STATUS
+		mfc0	t1, CP0_CAUSE
+		and	t0, t1
+
+		 andi	t1, t0, 0x0800			# hardware interrupt 1
+		bnez	t1, _hwint1
+		 andi	t1, t0, 0x4000			# hardware interrupt 4
+		bnez	t1, _hwint4
+		 andi	t1, t0, 0x2000			# hardware interrupt 3
+		bnez	t1, _hwint3
+		 andi	t1, t0, 0x1000			# hardware interrupt 2
+		bnez	t1, _hwint2
+		 andi	t1, t0, 0x8000			# hardware interrupt 5
+		bnez	t1, _hwint5
+		 andi	t1, t0, 0x0400			# hardware interrupt 0
+		bnez	t1, _hwint0
+		 nop
+
+		j	restore_all			# spurious interrupt
+		 nop
+
+ ##############################################################################
+
+/* hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug
+   button interrupts.  */
+_hwint0:	jal	pciasic_hwint0
+		 move	a0, sp
+		j	ret_from_irq
+		 nop
+
+/*
+ * hwint 1 deals with EISA and SCSI interrupts
+ */
+_hwint1:	jal	pciasic_hwint1
+		 move	a0, sp
+		j	ret_from_irq
+		 nop
+
+
+/*
+ * This interrupt was used for the com1 console on the first prototypes;
+ * it's unsed otherwise
+ */
+_hwint2:	jal	pciasic_hwint2
+		 move	a0, sp
+		j	ret_from_irq
+		 nop
+
+/*
+ * hwint 3 are the PCI interrupts A - D
+ */
+_hwint3:	jal	pciasic_hwint3
+		 move	a0, sp
+		j	ret_from_irq
+		 nop
+
+/*
+ * hwint 4 is used for only the onboard PCnet 32.
+ */
+_hwint4:	jal	pciasic_hwint4
+		 move	a0, sp
+		j	ret_from_irq
+		 nop
+
+/* hwint5 is the r4k count / compare interrupt  */
+_hwint5:	jal	pciasic_hwint5
+		 move	a0, sp
+		j	ret_from_irq
+		 nop
+
+		END(sni_rm200_pci_handle_int)
diff --git a/arch/mips/sni/irq.c b/arch/mips/sni/irq.c
new file mode 100644
index 0000000..62c760f
--- /dev/null
+++ b/arch/mips/sni/irq.c
@@ -0,0 +1,194 @@
+/*
+ * 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) 1992 Linus Torvalds
+ * Copyright (C) 1994 - 2000 Ralf Baechle
+ */
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+
+#include <asm/i8259.h>
+#include <asm/io.h>
+#include <asm/sni.h>
+
+DEFINE_SPINLOCK(pciasic_lock);
+
+extern asmlinkage void sni_rm200_pci_handle_int(void);
+
+static void enable_pciasic_irq(unsigned int irq)
+{
+	unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2);
+	unsigned long flags;
+
+	spin_lock_irqsave(&pciasic_lock, flags);
+	*(volatile u8 *) PCIMT_IRQSEL |= mask;
+	spin_unlock_irqrestore(&pciasic_lock, flags);
+}
+
+static unsigned int startup_pciasic_irq(unsigned int irq)
+{
+	enable_pciasic_irq(irq);
+	return 0; /* never anything pending */
+}
+
+#define shutdown_pciasic_irq	disable_pciasic_irq
+
+void disable_pciasic_irq(unsigned int irq)
+{
+	unsigned int mask = ~(1 << (irq - PCIMT_IRQ_INT2));
+	unsigned long flags;
+
+	spin_lock_irqsave(&pciasic_lock, flags);
+	*(volatile u8 *) PCIMT_IRQSEL &= mask;
+	spin_unlock_irqrestore(&pciasic_lock, flags);
+}
+
+#define mask_and_ack_pciasic_irq disable_pciasic_irq
+
+static void end_pciasic_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_pciasic_irq(irq);
+}
+
+static struct hw_interrupt_type pciasic_irq_type = {
+	"ASIC-PCI",
+	startup_pciasic_irq,
+	shutdown_pciasic_irq,
+	enable_pciasic_irq,
+	disable_pciasic_irq,
+	mask_and_ack_pciasic_irq,
+	end_pciasic_irq,
+	NULL
+};
+
+/*
+ * hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug
+ * button interrupts.  Later ...
+ */
+void pciasic_hwint0(struct pt_regs *regs)
+{
+	panic("Received int0 but no handler yet ...");
+}
+
+/* This interrupt was used for the com1 console on the first prototypes.  */
+void pciasic_hwint2(struct pt_regs *regs)
+{
+	/* I think this shouldn't happen on production machines.  */
+	panic("hwint2 and no handler yet");
+}
+
+/* hwint5 is the r4k count / compare interrupt  */
+void pciasic_hwint5(struct pt_regs *regs)
+{
+	panic("hwint5 and no handler yet");
+}
+
+static unsigned int ls1bit8(unsigned int x)
+{
+	int b = 7, s;
+
+	s = 4; if ((x & 0x0f) == 0) s = 0; b -= s; x <<= s;
+	s = 2; if ((x & 0x30) == 0) s = 0; b -= s; x <<= s;
+	s = 1; if ((x & 0x40) == 0) s = 0; b -= s;
+
+	return b;
+}
+
+/*
+ * hwint 1 deals with EISA and SCSI interrupts,
+ * 
+ * The EISA_INT bit in CSITPEND is high active, all others are low active.
+ */
+void pciasic_hwint1(struct pt_regs *regs)
+{
+	u8 pend = *(volatile char *)PCIMT_CSITPEND;
+	unsigned long flags;
+
+	if (pend & IT_EISA) {
+		int irq;
+		/*
+		 * Note: ASIC PCI's builtin interrupt achknowledge feature is
+		 * broken.  Using it may result in loss of some or all i8259
+		 * interupts, so don't use PCIMT_INT_ACKNOWLEDGE ...
+		 */
+		irq = i8259_irq();
+		if (unlikely(irq < 0))
+			return;
+
+		do_IRQ(irq, regs);
+	}
+
+	if (!(pend & IT_SCSI)) {
+		flags = read_c0_status();
+		clear_c0_status(ST0_IM);
+		do_IRQ(PCIMT_IRQ_SCSI, regs);
+		write_c0_status(flags);
+	}
+}
+
+/*
+ * hwint 3 should deal with the PCI A - D interrupts,
+ */
+void pciasic_hwint3(struct pt_regs *regs)
+{
+	u8 pend = *(volatile char *)PCIMT_CSITPEND;
+	int irq;
+
+	pend &= (IT_INTA | IT_INTB | IT_INTC | IT_INTD);
+	clear_c0_status(IE_IRQ3);
+	irq = PCIMT_IRQ_INT2 + ls1bit8(pend);
+	do_IRQ(irq, regs);
+	set_c0_status(IE_IRQ3);
+}
+
+/*
+ * hwint 4 is used for only the onboard PCnet 32.
+ */
+void pciasic_hwint4(struct pt_regs *regs)
+{
+	clear_c0_status(IE_IRQ4);
+	do_IRQ(PCIMT_IRQ_ETHERNET, regs);
+	set_c0_status(IE_IRQ4);
+}
+
+void __init init_pciasic(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&pciasic_lock, flags);
+	* (volatile u8 *) PCIMT_IRQSEL =
+		IT_EISA | IT_INTA | IT_INTB | IT_INTC | IT_INTD;
+	spin_unlock_irqrestore(&pciasic_lock, flags);
+}
+
+/*
+ * On systems with i8259-style interrupt controllers we assume for
+ * driver compatibility reasons interrupts 0 - 15 to be the i8295
+ * interrupts even if the hardware uses a different interrupt numbering.
+ */
+void __init arch_init_irq(void)
+{
+	int i;
+
+	set_except_vector(0, sni_rm200_pci_handle_int);
+
+	init_i8259_irqs();			/* Integrated i8259  */
+	init_pciasic();
+
+	/* Actually we've got more interrupts to handle ...  */
+	for (i = PCIMT_IRQ_INT2; i <= PCIMT_IRQ_ETHERNET; i++) {
+		irq_desc[i].status     = IRQ_DISABLED;
+		irq_desc[i].action     = 0;
+		irq_desc[i].depth      = 1;
+		irq_desc[i].handler    = &pciasic_irq_type;
+	}
+
+	change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ2|IE_IRQ3|IE_IRQ4);
+}
diff --git a/arch/mips/sni/pcimt_scache.c b/arch/mips/sni/pcimt_scache.c
new file mode 100644
index 0000000..a59d457
--- /dev/null
+++ b/arch/mips/sni/pcimt_scache.c
@@ -0,0 +1,37 @@
+/*
+ * arch/mips/sni/pcimt_scache.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1997, 1998 by Ralf Baechle
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/bcache.h>
+#include <asm/sni.h>
+
+#define cacheconf (*(volatile unsigned int *)PCIMT_CACHECONF)
+#define invspace (*(volatile unsigned int *)PCIMT_INVSPACE)
+
+void __init sni_pcimt_sc_init(void)
+{
+	unsigned int scsiz, sc_size;
+
+	scsiz = cacheconf & 7;
+	if (scsiz == 0) {
+		printk("Second level cache is deactived.\n");
+		return;
+	}
+	if (scsiz >= 6) {
+		printk("Invalid second level cache size configured, "
+		       "deactivating second level cache.\n");
+		cacheconf = 0;
+		return;
+	}
+
+	sc_size = 128 << scsiz;
+	printk("%dkb second level cache detected, deactivating.\n", sc_size);
+	cacheconf = 0;
+}
diff --git a/arch/mips/sni/reset.c b/arch/mips/sni/reset.c
new file mode 100644
index 0000000..be85bec
--- /dev/null
+++ b/arch/mips/sni/reset.c
@@ -0,0 +1,51 @@
+/*
+ *  linux/arch/mips/sni/process.c
+ *
+ *  Reset a SNI machine.
+ */
+#include <asm/io.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <asm/sni.h>
+
+/*
+ * This routine reboots the machine by asking the keyboard
+ * controller to pulse the reset-line low. We try that for a while,
+ * and if it doesn't work, we do some other stupid things.
+ */
+static inline void
+kb_wait(void)
+{
+	int i;
+
+	for (i=0; i<0x10000; i++)
+		if ((inb_p(0x64) & 0x02) == 0)
+			break;
+}
+
+/* XXX This ends up at the ARC firmware prompt ...  */
+void sni_machine_restart(char *command)
+{
+	int i, j;
+
+	/* This does a normal via the keyboard controller like a PC.
+	   We can do that easier ...  */
+	local_irq_disable();
+	for (;;) {
+		for (i=0; i<100; i++) {
+			kb_wait();
+			for(j = 0; j < 100000 ; j++)
+				/* nothing */;
+			outb_p(0xfe,0x64);	 /* pulse reset low */
+		}
+	}
+}
+
+void sni_machine_halt(void)
+{
+}
+
+void sni_machine_power_off(void)
+{
+	*(volatile unsigned char *)PCIMT_CSWCSM = 0xfd;
+}
diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c
new file mode 100644
index 0000000..8f67cee
--- /dev/null
+++ b/arch/mips/sni/setup.c
@@ -0,0 +1,203 @@
+/*
+ * Setup pointers to hardware-dependent routines.
+ *
+ * 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) 1996, 97, 98, 2000, 03, 04 Ralf Baechle (ralf@linux-mips.org)
+ */
+#include <linux/config.h>
+#include <linux/eisa.h>
+#include <linux/hdreg.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/mc146818rtc.h>
+#include <linux/pci.h>
+#include <linux/console.h>
+#include <linux/fb.h>
+#include <linux/tty.h>
+
+#include <asm/arc/types.h>
+#include <asm/sgialib.h>
+#include <asm/bcache.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mc146818-time.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/reboot.h>
+#include <asm/sni.h>
+#include <asm/time.h>
+#include <asm/traps.h>
+
+extern void sni_machine_restart(char *command);
+extern void sni_machine_halt(void);
+extern void sni_machine_power_off(void);
+
+static void __init sni_rm200_pci_timer_setup(struct irqaction *irq)
+{
+	/* set the clock to 100 Hz */
+	outb_p(0x34,0x43);		/* binary, mode 2, LSB/MSB, ch 0 */
+	outb_p(LATCH & 0xff , 0x40);	/* LSB */
+	outb(LATCH >> 8 , 0x40);	/* MSB */
+	setup_irq(0, irq);
+}
+
+/*
+ * A bit more gossip about the iron we're running on ...
+ */
+static inline void sni_pcimt_detect(void)
+{
+	char boardtype[80];
+	unsigned char csmsr;
+	char *p = boardtype;
+	unsigned int asic;
+
+	csmsr = *(volatile unsigned char *)PCIMT_CSMSR;
+
+	p += sprintf(p, "%s PCI", (csmsr & 0x80) ? "RM200" : "RM300");
+	if ((csmsr & 0x80) == 0)
+		p += sprintf(p, ", board revision %s",
+		             (csmsr & 0x20) ? "D" : "C");
+	asic = csmsr & 0x80;
+	asic = (csmsr & 0x08) ? asic : !asic;
+	p += sprintf(p, ", ASIC PCI Rev %s", asic ? "1.0" : "1.1");
+	printk("%s.\n", boardtype);
+}
+
+static void __init sni_display_setup(void)
+{
+#ifdef CONFIG_VT
+#if defined(CONFIG_VGA_CONSOLE)
+	struct screen_info *si = &screen_info;
+	DISPLAY_STATUS *di;
+
+	di = ArcGetDisplayStatus(1);
+
+	if (di) {
+		si->orig_x		= di->CursorXPosition;
+		si->orig_y		= di->CursorYPosition;
+		si->orig_video_cols	= di->CursorMaxXPosition;
+		si->orig_video_lines	= di->CursorMaxYPosition;
+		si->orig_video_isVGA	= VIDEO_TYPE_VGAC;
+		si->orig_video_points	= 16;
+	}
+#endif
+#endif
+}
+
+static struct resource sni_io_resource = {
+	"PCIMT IO MEM", 0x00001000UL, 0x03bfffffUL, IORESOURCE_IO,
+};
+
+static struct resource pcimt_io_resources[] = {
+	{ "dma1", 0x00, 0x1f, IORESOURCE_BUSY },
+	{ "timer", 0x40, 0x5f, IORESOURCE_BUSY },
+	{ "keyboard", 0x60, 0x6f, IORESOURCE_BUSY },
+	{ "dma page reg", 0x80, 0x8f, IORESOURCE_BUSY },
+	{ "dma2", 0xc0, 0xdf, IORESOURCE_BUSY },
+	{ "PCI config data", 0xcfc, 0xcff, IORESOURCE_BUSY }
+};
+
+static struct resource sni_mem_resource = {
+	"PCIMT PCI MEM", 0x10000000UL, 0xffffffffUL, IORESOURCE_MEM
+};
+
+/*
+ * The RM200/RM300 has a few holes in it's PCI/EISA memory address space used
+ * for other purposes.  Be paranoid and allocate all of the before the PCI
+ * code gets a chance to to map anything else there ...
+ * 
+ * This leaves the following areas available:
+ *
+ * 0x10000000 - 0x1009ffff (640kB) PCI/EISA/ISA Bus Memory
+ * 0x10100000 - 0x13ffffff ( 15MB) PCI/EISA/ISA Bus Memory
+ * 0x18000000 - 0x1fbfffff (124MB) PCI/EISA Bus Memory
+ * 0x1ff08000 - 0x1ffeffff (816kB) PCI/EISA Bus Memory
+ * 0xa0000000 - 0xffffffff (1.5GB) PCI/EISA Bus Memory
+ */
+static struct resource pcimt_mem_resources[] = {
+	{ "Video RAM area", 0x100a0000, 0x100bffff, IORESOURCE_BUSY },
+	{ "ISA Reserved", 0x100c0000, 0x100fffff, IORESOURCE_BUSY },
+	{ "PCI IO", 0x14000000, 0x17bfffff, IORESOURCE_BUSY },
+	{ "Cache Replacement Area", 0x17c00000, 0x17ffffff, IORESOURCE_BUSY},
+	{ "PCI INT Acknowledge", 0x1a000000, 0x1a000003, IORESOURCE_BUSY },
+	{ "Boot PROM", 0x1fc00000, 0x1fc7ffff, IORESOURCE_BUSY},
+	{ "Diag PROM", 0x1fc80000, 0x1fcfffff, IORESOURCE_BUSY},
+	{ "X-Bus", 0x1fd00000, 0x1fdfffff, IORESOURCE_BUSY},
+	{ "BIOS map", 0x1fe00000, 0x1fefffff, IORESOURCE_BUSY},
+	{ "NVRAM / EEPROM", 0x1ff00000, 0x1ff7ffff, IORESOURCE_BUSY},
+	{ "ASIC PCI", 0x1fff0000, 0x1fffefff, IORESOURCE_BUSY},
+	{ "MP Agent", 0x1ffff000, 0x1fffffff, IORESOURCE_BUSY},
+	{ "Main Memory", 0x20000000, 0x9fffffff, IORESOURCE_BUSY}
+};
+
+static void __init sni_resource_init(void)
+{
+	int i;
+
+	/* request I/O space for devices used on all i[345]86 PCs */
+	for (i = 0; i < ARRAY_SIZE(pcimt_io_resources); i++)
+		request_resource(&ioport_resource, pcimt_io_resources + i);
+
+	/* request mem space for pcimt-specific devices */
+	for (i = 0; i < ARRAY_SIZE(pcimt_mem_resources); i++)
+		request_resource(&sni_mem_resource, pcimt_mem_resources + i);
+
+	ioport_resource.end = sni_io_resource.end;
+}
+
+extern struct pci_ops sni_pci_ops;
+
+static struct pci_controller sni_controller = {
+	.pci_ops	= &sni_pci_ops,
+	.mem_resource	= &sni_mem_resource,
+	.mem_offset	= 0x10000000UL,
+	.io_resource	= &sni_io_resource,
+	.io_offset	= 0x00000000UL
+};
+
+static inline void sni_pcimt_time_init(void)
+{
+	rtc_get_time = mc146818_get_cmos_time;
+	rtc_set_time = mc146818_set_rtc_mmss;
+}
+
+static int __init sni_rm200_pci_setup(void)
+{
+	sni_pcimt_detect();
+	sni_pcimt_sc_init();
+	sni_pcimt_time_init();
+
+	set_io_port_base(SNI_PORT_BASE);
+	ioport_resource.end = sni_io_resource.end;
+
+	/*
+	 * Setup (E)ISA I/O memory access stuff
+	 */
+	isa_slot_offset = 0xb0000000;
+#ifdef CONFIG_EISA
+	EISA_bus = 1;
+#endif
+
+	sni_resource_init();
+	board_timer_setup = sni_rm200_pci_timer_setup;
+
+	_machine_restart = sni_machine_restart;
+	_machine_halt = sni_machine_halt;
+	_machine_power_off = sni_machine_power_off;
+
+	sni_display_setup();
+
+#ifdef CONFIG_PCI
+	register_pci_controller(&sni_controller);
+#endif
+
+	return 0;
+}
+
+early_initcall(sni_rm200_pci_setup);
diff --git a/arch/mips/tx4927/common/Makefile b/arch/mips/tx4927/common/Makefile
new file mode 100644
index 0000000..8fa126b
--- /dev/null
+++ b/arch/mips/tx4927/common/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for common code for Toshiba TX4927 based systems
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+obj-y	+= tx4927_prom.o tx4927_setup.o tx4927_irq.o tx4927_irq_handler.o
+
+obj-$(CONFIG_TOSHIBA_FPCIB0)	   += smsc_fdc37m81x.o
+obj-$(CONFIG_KGDB)                 += tx4927_dbgio.o
diff --git a/arch/mips/tx4927/common/tx4927_dbgio.c b/arch/mips/tx4927/common/tx4927_dbgio.c
new file mode 100644
index 0000000..09bdf2b
--- /dev/null
+++ b/arch/mips/tx4927/common/tx4927_dbgio.c
@@ -0,0 +1,47 @@
+/*
+ * linux/arch/mips/tx4927/common/tx4927_dbgio.c
+ *
+ * kgdb interface for gdb
+ *
+ * Author: MontaVista Software, Inc.
+ *         source@mvista.com
+ *
+ * Copyright 2001-2002 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/tx4927/tx4927_mips.h>
+
+u8 getDebugChar(void)
+{
+	extern u8 txx9_sio_kdbg_rd(void);
+	return (txx9_sio_kdbg_rd());
+}
+
+
+int putDebugChar(u8 byte)
+{
+	extern int txx9_sio_kdbg_wr( u8 ch );
+	return (txx9_sio_kdbg_wr(byte));
+}
diff --git a/arch/mips/tx4927/common/tx4927_irq.c b/arch/mips/tx4927/common/tx4927_irq.c
new file mode 100644
index 0000000..5ab2e2b
--- /dev/null
+++ b/arch/mips/tx4927/common/tx4927_irq.c
@@ -0,0 +1,584 @@
+/*
+ * Common tx4927 irq handler
+ *
+ * Author: MontaVista Software, Inc.
+ *         source@mvista.com
+ *
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/irq.h>
+#include <linux/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/tx4927/tx4927.h>
+
+/*
+ * DEBUG
+ */
+
+#undef TX4927_IRQ_DEBUG
+
+#ifdef TX4927_IRQ_DEBUG
+#define TX4927_IRQ_NONE        0x00000000
+
+#define TX4927_IRQ_INFO        ( 1 <<  0 )
+#define TX4927_IRQ_WARN        ( 1 <<  1 )
+#define TX4927_IRQ_EROR        ( 1 <<  2 )
+
+#define TX4927_IRQ_INIT        ( 1 <<  5 )
+#define TX4927_IRQ_NEST1       ( 1 <<  6 )
+#define TX4927_IRQ_NEST2       ( 1 <<  7 )
+#define TX4927_IRQ_NEST3       ( 1 <<  8 )
+#define TX4927_IRQ_NEST4       ( 1 <<  9 )
+
+#define TX4927_IRQ_CP0_INIT     ( 1 << 10 )
+#define TX4927_IRQ_CP0_STARTUP  ( 1 << 11 )
+#define TX4927_IRQ_CP0_SHUTDOWN ( 1 << 12 )
+#define TX4927_IRQ_CP0_ENABLE   ( 1 << 13 )
+#define TX4927_IRQ_CP0_DISABLE  ( 1 << 14 )
+#define TX4927_IRQ_CP0_MASK     ( 1 << 15 )
+#define TX4927_IRQ_CP0_ENDIRQ   ( 1 << 16 )
+
+#define TX4927_IRQ_PIC_INIT     ( 1 << 20 )
+#define TX4927_IRQ_PIC_STARTUP  ( 1 << 21 )
+#define TX4927_IRQ_PIC_SHUTDOWN ( 1 << 22 )
+#define TX4927_IRQ_PIC_ENABLE   ( 1 << 23 )
+#define TX4927_IRQ_PIC_DISABLE  ( 1 << 24 )
+#define TX4927_IRQ_PIC_MASK     ( 1 << 25 )
+#define TX4927_IRQ_PIC_ENDIRQ   ( 1 << 26 )
+
+#define TX4927_IRQ_ALL         0xffffffff
+#endif
+
+#ifdef TX4927_IRQ_DEBUG
+static const u32 tx4927_irq_debug_flag = (TX4927_IRQ_NONE
+					  | TX4927_IRQ_INFO
+					  | TX4927_IRQ_WARN | TX4927_IRQ_EROR
+//                                       | TX4927_IRQ_CP0_INIT
+//                                       | TX4927_IRQ_CP0_STARTUP
+//                                       | TX4927_IRQ_CP0_SHUTDOWN
+//                                       | TX4927_IRQ_CP0_ENABLE
+//                                       | TX4927_IRQ_CP0_DISABLE
+//                                       | TX4927_IRQ_CP0_MASK
+//                                       | TX4927_IRQ_CP0_ENDIRQ
+//                                       | TX4927_IRQ_PIC_INIT
+//                                       | TX4927_IRQ_PIC_STARTUP
+//                                       | TX4927_IRQ_PIC_SHUTDOWN
+//                                       | TX4927_IRQ_PIC_ENABLE
+//                                       | TX4927_IRQ_PIC_DISABLE
+//                                       | TX4927_IRQ_PIC_MASK
+//                                       | TX4927_IRQ_PIC_ENDIRQ
+//                                       | TX4927_IRQ_INIT
+//                                       | TX4927_IRQ_NEST1
+//                                       | TX4927_IRQ_NEST2
+//                                       | TX4927_IRQ_NEST3
+//                                       | TX4927_IRQ_NEST4
+    );
+#endif
+
+#ifdef TX4927_IRQ_DEBUG
+#define TX4927_IRQ_DPRINTK(flag,str...) \
+        if ( (tx4927_irq_debug_flag) & (flag) ) \
+        { \
+           char tmp[100]; \
+           sprintf( tmp, str ); \
+           printk( "%s(%s:%u)::%s", __FUNCTION__, __FILE__, __LINE__, tmp ); \
+        }
+#else
+#define TX4927_IRQ_DPRINTK(flag,str...)
+#endif
+
+/*
+ * Forwad definitions for all pic's
+ */
+
+static unsigned int tx4927_irq_cp0_startup(unsigned int irq);
+static void tx4927_irq_cp0_shutdown(unsigned int irq);
+static void tx4927_irq_cp0_enable(unsigned int irq);
+static void tx4927_irq_cp0_disable(unsigned int irq);
+static void tx4927_irq_cp0_mask_and_ack(unsigned int irq);
+static void tx4927_irq_cp0_end(unsigned int irq);
+
+static unsigned int tx4927_irq_pic_startup(unsigned int irq);
+static void tx4927_irq_pic_shutdown(unsigned int irq);
+static void tx4927_irq_pic_enable(unsigned int irq);
+static void tx4927_irq_pic_disable(unsigned int irq);
+static void tx4927_irq_pic_mask_and_ack(unsigned int irq);
+static void tx4927_irq_pic_end(unsigned int irq);
+
+/*
+ * Kernel structs for all pic's
+ */
+
+static DEFINE_SPINLOCK(tx4927_cp0_lock);
+static DEFINE_SPINLOCK(tx4927_pic_lock);
+
+#define TX4927_CP0_NAME "TX4927-CP0"
+static struct hw_interrupt_type tx4927_irq_cp0_type = {
+	.typename	= TX4927_CP0_NAME,
+	.startup	= tx4927_irq_cp0_startup,
+	.shutdown	= tx4927_irq_cp0_shutdown,
+	.enable		= tx4927_irq_cp0_enable,
+	.disable	= tx4927_irq_cp0_disable,
+	.ack		= tx4927_irq_cp0_mask_and_ack,
+	.end		= tx4927_irq_cp0_end,
+	.set_affinity	= NULL
+};
+
+#define TX4927_PIC_NAME "TX4927-PIC"
+static struct hw_interrupt_type tx4927_irq_pic_type = {
+	.typename	= TX4927_PIC_NAME,
+	.startup	= tx4927_irq_pic_startup,
+	.shutdown	= tx4927_irq_pic_shutdown,
+	.enable		= tx4927_irq_pic_enable,
+	.disable	= tx4927_irq_pic_disable,
+	.ack		= tx4927_irq_pic_mask_and_ack,
+	.end		= tx4927_irq_pic_end,
+	.set_affinity	= NULL
+};
+
+#define TX4927_PIC_ACTION(s) { no_action, 0, CPU_MASK_NONE, s, NULL, NULL }
+static struct irqaction tx4927_irq_pic_action =
+TX4927_PIC_ACTION(TX4927_PIC_NAME);
+
+#define CCP0_STATUS 12
+#define CCP0_CAUSE 13
+
+/*
+ * Functions for cp0
+ */
+
+#define tx4927_irq_cp0_mask(irq) ( 1 << ( irq-TX4927_IRQ_CP0_BEG+8 ) )
+
+static void
+tx4927_irq_cp0_modify(unsigned cp0_reg, unsigned clr_bits, unsigned set_bits)
+{
+	unsigned long val = 0;
+
+	switch (cp0_reg) {
+	case CCP0_STATUS:
+		val = read_c0_status();
+		break;
+
+	case CCP0_CAUSE:
+		val = read_c0_cause();
+		break;
+
+	}
+
+	val &= (~clr_bits);
+	val |= (set_bits);
+
+	switch (cp0_reg) {
+	case CCP0_STATUS:{
+			write_c0_status(val);
+			break;
+		}
+	case CCP0_CAUSE:{
+			write_c0_cause(val);
+			break;
+		}
+	}
+
+	return;
+}
+
+static void __init tx4927_irq_cp0_init(void)
+{
+	int i;
+
+	TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_INIT, "beg=%d end=%d\n",
+			   TX4927_IRQ_CP0_BEG, TX4927_IRQ_CP0_END);
+
+	for (i = TX4927_IRQ_CP0_BEG; i <= TX4927_IRQ_CP0_END; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = 0;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &tx4927_irq_cp0_type;
+	}
+
+	return;
+}
+
+static unsigned int tx4927_irq_cp0_startup(unsigned int irq)
+{
+	TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_STARTUP, "irq=%d \n", irq);
+
+	tx4927_irq_cp0_enable(irq);
+
+	return (0);
+}
+
+static void tx4927_irq_cp0_shutdown(unsigned int irq)
+{
+	TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_SHUTDOWN, "irq=%d \n", irq);
+
+	tx4927_irq_cp0_disable(irq);
+
+	return;
+}
+
+static void tx4927_irq_cp0_enable(unsigned int irq)
+{
+	unsigned long flags;
+
+	TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_ENABLE, "irq=%d \n", irq);
+
+	spin_lock_irqsave(&tx4927_cp0_lock, flags);
+
+	tx4927_irq_cp0_modify(CCP0_STATUS, 0, tx4927_irq_cp0_mask(irq));
+
+	spin_unlock_irqrestore(&tx4927_cp0_lock, flags);
+
+	return;
+}
+
+static void tx4927_irq_cp0_disable(unsigned int irq)
+{
+	unsigned long flags;
+
+	TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_DISABLE, "irq=%d \n", irq);
+
+	spin_lock_irqsave(&tx4927_cp0_lock, flags);
+
+	tx4927_irq_cp0_modify(CCP0_STATUS, tx4927_irq_cp0_mask(irq), 0);
+
+	spin_unlock_irqrestore(&tx4927_cp0_lock, flags);
+
+	return;
+}
+
+static void tx4927_irq_cp0_mask_and_ack(unsigned int irq)
+{
+	TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_MASK, "irq=%d \n", irq);
+
+	tx4927_irq_cp0_disable(irq);
+
+	return;
+}
+
+static void tx4927_irq_cp0_end(unsigned int irq)
+{
+	TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_ENDIRQ, "irq=%d \n", irq);
+
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+		tx4927_irq_cp0_enable(irq);
+	}
+
+	return;
+}
+
+/*
+ * Functions for pic
+ */
+u32 tx4927_irq_pic_addr(int irq)
+{
+	/* MVMCP -- need to formulize this */
+	irq -= TX4927_IRQ_PIC_BEG;
+	switch (irq) {
+	case 17:
+	case 16:
+	case 1:
+	case 0:
+		return (0xff1ff610);
+
+	case 19:
+	case 18:
+	case 3:
+	case 2:
+		return (0xff1ff614);
+
+	case 21:
+	case 20:
+	case 5:
+	case 4:
+		return (0xff1ff618);
+
+	case 23:
+	case 22:
+	case 7:
+	case 6:
+		return (0xff1ff61c);
+
+	case 25:
+	case 24:
+	case 9:
+	case 8:
+		return (0xff1ff620);
+
+	case 27:
+	case 26:
+	case 11:
+	case 10:
+		return (0xff1ff624);
+
+	case 29:
+	case 28:
+	case 13:
+	case 12:
+		return (0xff1ff628);
+
+	case 31:
+	case 30:
+	case 15:
+	case 14:
+		return (0xff1ff62c);
+
+	}
+	return (0);
+}
+
+u32 tx4927_irq_pic_mask(int irq)
+{
+	/* MVMCP -- need to formulize this */
+	irq -= TX4927_IRQ_PIC_BEG;
+	switch (irq) {
+	case 31:
+	case 29:
+	case 27:
+	case 25:
+	case 23:
+	case 21:
+	case 19:
+	case 17:{
+			return (0x07000000);
+		}
+	case 30:
+	case 28:
+	case 26:
+	case 24:
+	case 22:
+	case 20:
+	case 18:
+	case 16:{
+			return (0x00070000);
+		}
+	case 15:
+	case 13:
+	case 11:
+	case 9:
+	case 7:
+	case 5:
+	case 3:
+	case 1:{
+			return (0x00000700);
+		}
+	case 14:
+	case 12:
+	case 10:
+	case 8:
+	case 6:
+	case 4:
+	case 2:
+	case 0:{
+			return (0x00000007);
+		}
+	}
+	return (0x00000000);
+}
+
+static void tx4927_irq_pic_modify(unsigned pic_reg, unsigned clr_bits,
+	unsigned set_bits)
+{
+	unsigned long val = 0;
+
+	val = TX4927_RD(pic_reg);
+	val &= (~clr_bits);
+	val |= (set_bits);
+	TX4927_WR(pic_reg, val);
+
+	return;
+}
+
+static void __init tx4927_irq_pic_init(void)
+{
+	unsigned long flags;
+	int i;
+
+	TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_INIT, "beg=%d end=%d\n",
+			   TX4927_IRQ_PIC_BEG, TX4927_IRQ_PIC_END);
+
+	for (i = TX4927_IRQ_PIC_BEG; i <= TX4927_IRQ_PIC_END; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = 0;
+		irq_desc[i].depth = 2;
+		irq_desc[i].handler = &tx4927_irq_pic_type;
+	}
+
+	setup_irq(TX4927_IRQ_NEST_PIC_ON_CP0, &tx4927_irq_pic_action);
+
+	spin_lock_irqsave(&tx4927_pic_lock, flags);
+
+	TX4927_WR(0xff1ff640, 0x6);	/* irq level mask -- only accept hightest */
+	TX4927_WR(0xff1ff600, TX4927_RD(0xff1ff600) | 0x1);	/* irq enable */
+
+	spin_unlock_irqrestore(&tx4927_pic_lock, flags);
+
+	return;
+}
+
+static unsigned int tx4927_irq_pic_startup(unsigned int irq)
+{
+	TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_STARTUP, "irq=%d\n", irq);
+
+	tx4927_irq_pic_enable(irq);
+
+	return (0);
+}
+
+static void tx4927_irq_pic_shutdown(unsigned int irq)
+{
+	TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_SHUTDOWN, "irq=%d\n", irq);
+
+	tx4927_irq_pic_disable(irq);
+
+	return;
+}
+
+static void tx4927_irq_pic_enable(unsigned int irq)
+{
+	unsigned long flags;
+
+	TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_ENABLE, "irq=%d\n", irq);
+
+	spin_lock_irqsave(&tx4927_pic_lock, flags);
+
+	tx4927_irq_pic_modify(tx4927_irq_pic_addr(irq), 0,
+			      tx4927_irq_pic_mask(irq));
+
+	spin_unlock_irqrestore(&tx4927_pic_lock, flags);
+
+	return;
+}
+
+static void tx4927_irq_pic_disable(unsigned int irq)
+{
+	unsigned long flags;
+
+	TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_DISABLE, "irq=%d\n", irq);
+
+	spin_lock_irqsave(&tx4927_pic_lock, flags);
+
+	tx4927_irq_pic_modify(tx4927_irq_pic_addr(irq),
+			      tx4927_irq_pic_mask(irq), 0);
+
+	spin_unlock_irqrestore(&tx4927_pic_lock, flags);
+
+	return;
+}
+
+static void tx4927_irq_pic_mask_and_ack(unsigned int irq)
+{
+	TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_MASK, "irq=%d\n", irq);
+
+	tx4927_irq_pic_disable(irq);
+
+	return;
+}
+
+static void tx4927_irq_pic_end(unsigned int irq)
+{
+	TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_ENDIRQ, "irq=%d\n", irq);
+
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+		tx4927_irq_pic_enable(irq);
+	}
+
+	return;
+}
+
+/*
+ * Main init functions
+ */
+void __init tx4927_irq_init(void)
+{
+	extern asmlinkage void tx4927_irq_handler(void);
+
+	TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "-\n");
+
+	TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_cp0_init()\n");
+	tx4927_irq_cp0_init();
+
+	TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_pic_init()\n");
+	tx4927_irq_pic_init();
+
+	TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT,
+			   "=Calling set_except_vector(tx4927_irq_handler)\n");
+	set_except_vector(0, tx4927_irq_handler);
+
+	TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "+\n");
+
+	return;
+}
+
+int tx4927_irq_nested(void)
+{
+	int sw_irq = 0;
+	u32 level2;
+
+	TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST1, "-\n");
+
+	level2 = TX4927_RD(0xff1ff6a0);
+	TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST2, "=level2a=0x%x\n", level2);
+
+	if ((level2 & 0x10000) == 0) {
+		level2 &= 0x1f;
+		TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST3, "=level2b=0x%x\n", level2);
+
+		sw_irq = TX4927_IRQ_PIC_BEG + level2;
+		TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST3, "=sw_irq=%d\n", sw_irq);
+
+		if (sw_irq == 27) {
+			TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST4, "=irq-%d\n",
+					   sw_irq);
+
+#ifdef CONFIG_TOSHIBA_RBTX4927
+			{
+				sw_irq = toshiba_rbtx4927_irq_nested(sw_irq);
+			}
+#endif
+
+			TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST4, "=irq+%d\n",
+					   sw_irq);
+		}
+	}
+
+	TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST2, "=sw_irq=%d\n", sw_irq);
+
+	TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST1, "+\n");
+
+	return (sw_irq);
+}
diff --git a/arch/mips/tx4927/common/tx4927_irq_handler.S b/arch/mips/tx4927/common/tx4927_irq_handler.S
new file mode 100644
index 0000000..ca123e2
--- /dev/null
+++ b/arch/mips/tx4927/common/tx4927_irq_handler.S
@@ -0,0 +1,103 @@
+/*
+ * linux/arch/mips/tx4927/common/tx4927_irq_handler.S
+ *
+ * Primary interrupt handler for tx4927 based systems
+ *
+ * Author: MontaVista Software, Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *         source@mvista.com
+ *
+ * Copyright 2001-2002 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/tx4927/tx4927.h>
+
+		.align	5
+		NESTED(tx4927_irq_handler, PT_SIZE, sp)
+		SAVE_ALL
+		CLI
+		.set	at
+
+		mfc0	t0, CP0_CAUSE  
+		mfc0	t1, CP0_STATUS
+		and	t0, t1
+        
+		andi	t1, t0, STATUSF_IP7	/* cpu timer */
+		bnez	t1, ll_ip7
+		
+		/* IP6..IP3 multiplexed -- do not use */
+
+		andi	t1, t0, STATUSF_IP2	/* tx4927 pic */
+		bnez	t1, ll_ip2
+
+		andi	t1, t0, STATUSF_IP0	/* user line 0 */
+		bnez	t1, ll_ip0
+
+		andi	t1, t0, STATUSF_IP1	/* user line 1 */
+		bnez	t1, ll_ip1
+
+		.set	reorder
+
+		/* wrong alarm or masked ... */
+		j	spurious_interrupt
+		nop
+		END(tx4927_irq_handler)
+
+		.align	5
+
+
+ll_ip7:
+		li	a0, TX4927_IRQ_CPU_TIMER
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_ip2:
+		jal	tx4927_irq_nested
+		nop
+		beqz 	v0, goto_spurious_interrupt
+		nop
+		move	a0, v0
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+goto_spurious_interrupt:
+	j spurious_interrupt
+	nop
+
+ll_ip1:
+		li	a0, TX4927_IRQ_USER1
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_ip0:
+		li	a0, TX4927_IRQ_USER0
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
diff --git a/arch/mips/tx4927/common/tx4927_prom.c b/arch/mips/tx4927/common/tx4927_prom.c
new file mode 100644
index 0000000..7d4cbf5
--- /dev/null
+++ b/arch/mips/tx4927/common/tx4927_prom.c
@@ -0,0 +1,146 @@
+/*
+ * linux/arch/mips/tx4927/common/tx4927_prom.c
+ *
+ * common tx4927 memory interface
+ *
+ * Author: MontaVista Software, Inc.
+ *         source@mvista.com
+ *
+ * Copyright 2001-2002 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/tx4927/tx4927.h>
+
+static unsigned int __init tx4927_process_sdccr(u64 * addr)
+{
+	u64 val;
+	unsigned int sdccr_ce;
+	unsigned int sdccr_bs;
+	unsigned int sdccr_rs;
+	unsigned int sdccr_cs;
+	unsigned int sdccr_mw;
+	unsigned int bs = 0;
+	unsigned int rs = 0;
+	unsigned int cs = 0;
+	unsigned int mw = 0;
+	unsigned int msize = 0;
+
+	val = (*((vu64 *) (addr)));
+
+	/* MVMCP -- need #defs for these bits masks */
+	sdccr_ce = ((val & (1 << 10)) >> 10);
+	sdccr_bs = ((val & (1 << 8)) >> 8);
+	sdccr_rs = ((val & (3 << 5)) >> 5);
+	sdccr_cs = ((val & (3 << 2)) >> 2);
+	sdccr_mw = ((val & (1 << 0)) >> 0);
+
+	if (sdccr_ce) {
+		switch (sdccr_bs) {
+		case 0:{
+				bs = 2;
+				break;
+			}
+		case 1:{
+				bs = 4;
+				break;
+			}
+		}
+		switch (sdccr_rs) {
+		case 0:{
+				rs = 2048;
+				break;
+			}
+		case 1:{
+				rs = 4096;
+				break;
+			}
+		case 2:{
+				rs = 8192;
+				break;
+			}
+		case 3:{
+				rs = 0;
+				break;
+			}
+		}
+		switch (sdccr_cs) {
+		case 0:{
+				cs = 256;
+				break;
+			}
+		case 1:{
+				cs = 512;
+				break;
+			}
+		case 2:{
+				cs = 1024;
+				break;
+			}
+		case 3:{
+				cs = 2048;
+				break;
+			}
+		}
+		switch (sdccr_mw) {
+		case 0:{
+				mw = 8;
+				break;
+			}	/* 8 bytes = 64 bits */
+		case 1:{
+				mw = 4;
+				break;
+			}	/* 4 bytes = 32 bits */
+		}
+	}
+
+	/*            bytes per chip     MB per chip      num chips */
+	msize = (((rs * cs * mw) / (1024 * 1024)) * bs);
+
+	return (msize);
+}
+
+
+unsigned int __init tx4927_get_mem_size(void)
+{
+	unsigned int c0;
+	unsigned int c1;
+	unsigned int c2;
+	unsigned int c3;
+	unsigned int total;
+
+	/* MVMCP -- need #defs for these registers */
+	c0 = tx4927_process_sdccr((u64 *) 0xff1f8000);
+	c1 = tx4927_process_sdccr((u64 *) 0xff1f8008);
+	c2 = tx4927_process_sdccr((u64 *) 0xff1f8010);
+	c3 = tx4927_process_sdccr((u64 *) 0xff1f8018);
+	total = c0 + c1 + c2 + c3;
+
+	return (total);
+}
diff --git a/arch/mips/tx4927/common/tx4927_setup.c b/arch/mips/tx4927/common/tx4927_setup.c
new file mode 100644
index 0000000..16bcbdc
--- /dev/null
+++ b/arch/mips/tx4927/common/tx4927_setup.c
@@ -0,0 +1,237 @@
+/*
+ * Author: MontaVista Software, Inc.
+ *         source@mvista.com
+ *
+ * Copyright 2001-2002 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/irq.h>
+#include <linux/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/tx4927/tx4927.h>
+
+
+#undef DEBUG
+
+void __init tx4927_time_init(void);
+void __init tx4927_timer_setup(struct irqaction *irq);
+void dump_cp0(char *key);
+
+
+void (*__wbflush) (void);
+
+static void tx4927_write_buffer_flush(void)
+{
+	__asm__ __volatile__
+	    ("sync\n\t" "nop\n\t" "loop: bc0f loop\n\t" "nop\n\t");
+}
+
+
+static void __init tx4927_setup(void)
+{
+	board_time_init = tx4927_time_init;
+	board_timer_setup = tx4927_timer_setup;
+	__wbflush = tx4927_write_buffer_flush;
+
+#ifdef CONFIG_TOSHIBA_RBTX4927
+	{
+		extern void toshiba_rbtx4927_setup(void);
+		toshiba_rbtx4927_setup();
+	}
+#endif
+
+	return;
+}
+
+early_initcall(tx4927_setup);
+
+void __init tx4927_time_init(void)
+{
+
+#ifdef CONFIG_TOSHIBA_RBTX4927
+	{
+		extern void toshiba_rbtx4927_time_init(void);
+		toshiba_rbtx4927_time_init();
+	}
+#endif
+
+	return;
+}
+
+
+void __init tx4927_timer_setup(struct irqaction *irq)
+{
+	u32 count;
+	u32 c1;
+	u32 c2;
+
+	setup_irq(TX4927_IRQ_CPU_TIMER, irq);
+
+	/* to generate the first timer interrupt */
+	c1 = read_c0_count();
+	count = c1 + (mips_hpt_frequency / HZ);
+	write_c0_compare(count);
+	c2 = read_c0_count();
+
+#ifdef CONFIG_TOSHIBA_RBTX4927
+	{
+		extern void toshiba_rbtx4927_timer_setup(struct irqaction
+							 *irq);
+		toshiba_rbtx4927_timer_setup(irq);
+	}
+#endif
+
+	return;
+}
+
+
+#ifdef DEBUG
+void print_cp0(char *key, int num, char *name, u32 val)
+{
+	printk("%s cp0:%02d:%s=0x%08x\n", key, num, name, val);
+	return;
+}
+
+indent: Standard input:25: Error:Unexpected end of file
+
+void
+dump_cp0(char *key)
+{
+	if (key == NULL)
+		key = "";
+
+	print_cp0(key, 0, "INDEX   ", read_c0_index());
+	print_cp0(key, 2, "ENTRYLO1", read_c0_entrylo0());
+	print_cp0(key, 3, "ENTRYLO2", read_c0_entrylo1());
+	print_cp0(key, 4, "CONTEXT ", read_c0_context());
+	print_cp0(key, 5, "PAGEMASK", read_c0_pagemask());
+	print_cp0(key, 6, "WIRED   ", read_c0_wired());
+	//print_cp0(key, 8, "BADVADDR",  read_c0_badvaddr());
+	print_cp0(key, 9, "COUNT   ", read_c0_count());
+	print_cp0(key, 10, "ENTRYHI ", read_c0_entryhi());
+	print_cp0(key, 11, "COMPARE ", read_c0_compare());
+	print_cp0(key, 12, "STATUS  ", read_c0_status());
+	print_cp0(key, 13, "CAUSE   ", read_c0_cause() & 0xffff87ff);
+	print_cp0(key, 16, "CONFIG  ", read_c0_config());
+	return;
+}
+	
+void print_pic(char *key, u32 reg, char *name)
+{
+	printk("%s pic:0x%08x:%s=0x%08x\n", key, reg, name,
+	       TX4927_RD(reg));
+	return;
+}
+
+
+void dump_pic(char *key)
+{
+	if (key == NULL)
+		key = "";
+
+	print_pic(key, 0xff1ff600, "IRDEN    ");
+	print_pic(key, 0xff1ff604, "IRDM0    ");
+	print_pic(key, 0xff1ff608, "IRDM1    ");
+
+	print_pic(key, 0xff1ff610, "IRLVL0   ");
+	print_pic(key, 0xff1ff614, "IRLVL1   ");
+	print_pic(key, 0xff1ff618, "IRLVL2   ");
+	print_pic(key, 0xff1ff61c, "IRLVL3   ");
+	print_pic(key, 0xff1ff620, "IRLVL4   ");
+	print_pic(key, 0xff1ff624, "IRLVL5   ");
+	print_pic(key, 0xff1ff628, "IRLVL6   ");
+	print_pic(key, 0xff1ff62c, "IRLVL7   ");
+
+	print_pic(key, 0xff1ff640, "IRMSK    ");
+	print_pic(key, 0xff1ff660, "IREDC    ");
+	print_pic(key, 0xff1ff680, "IRPND    ");
+	print_pic(key, 0xff1ff6a0, "IRCS     ");
+
+	print_pic(key, 0xff1ff514, "IRFLAG1  ");	/* don't read IRLAG0 -- it hangs system */
+
+	print_pic(key, 0xff1ff518, "IRPOL    ");
+	print_pic(key, 0xff1ff51c, "IRRCNT   ");
+	print_pic(key, 0xff1ff520, "IRMASKINT");
+	print_pic(key, 0xff1ff524, "IRMASKEXT");
+
+	return;
+}
+
+
+void print_addr(char *hdr, char *key, u32 addr)
+{
+	printk("%s %s:0x%08x=0x%08x\n", hdr, key, addr, TX4927_RD(addr));
+	return;
+}
+
+
+void dump_180(char *key)
+{
+	u32 i;
+
+	for (i = 0x80000180; i < 0x80000180 + 0x80; i += 4) {
+		print_addr("180", key, i);
+	}
+	return;
+}
+
+
+void dump_eh0(char *key)
+{
+	int i;
+	extern unsigned long exception_handlers[];
+
+	for (i = (int) exception_handlers;
+	     i < (int) (exception_handlers + 20); i += 4) {
+		print_addr("eh0", key, i);
+	}
+
+	return;
+}
+
+void pk0(void)
+{
+	volatile u32 val;
+
+	__asm__ __volatile__("ori %0, $26, 0":"=r"(val)
+	    );
+	printk("k0=[0x%08x]\n", val);
+}
+#endif
diff --git a/arch/mips/tx4927/toshiba_rbtx4927/Makefile b/arch/mips/tx4927/toshiba_rbtx4927/Makefile
new file mode 100644
index 0000000..86ca4cf
--- /dev/null
+++ b/arch/mips/tx4927/toshiba_rbtx4927/Makefile
@@ -0,0 +1,5 @@
+obj-y	+= toshiba_rbtx4927_prom.o 
+obj-y	+= toshiba_rbtx4927_setup.o 
+obj-y	+= toshiba_rbtx4927_irq.o 
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c
new file mode 100644
index 0000000..fd5b433
--- /dev/null
+++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c
@@ -0,0 +1,786 @@
+/*
+ * linux/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c
+ *
+ * Toshiba RBTX4927 specific interrupt handlers
+ *
+ * Author: MontaVista Software, Inc.
+ *         source@mvista.com
+ *
+ * Copyright 2001-2002 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+IRQ  Device  
+00   RBTX4927-ISA/00
+01   RBTX4927-ISA/01 PS2/Keyboard
+02   RBTX4927-ISA/02 Cascade RBTX4927-ISA (irqs 8-15)
+03   RBTX4927-ISA/03
+04   RBTX4927-ISA/04
+05   RBTX4927-ISA/05
+06   RBTX4927-ISA/06
+07   RBTX4927-ISA/07
+08   RBTX4927-ISA/08
+09   RBTX4927-ISA/09
+10   RBTX4927-ISA/10
+11   RBTX4927-ISA/11
+12   RBTX4927-ISA/12 PS2/Mouse (not supported at this time)
+13   RBTX4927-ISA/13
+14   RBTX4927-ISA/14 IDE
+15   RBTX4927-ISA/15
+
+16   TX4927-CP0/00 Software 0
+17   TX4927-CP0/01 Software 1
+18   TX4927-CP0/02 Cascade TX4927-CP0
+19   TX4927-CP0/03 Multiplexed -- do not use 
+20   TX4927-CP0/04 Multiplexed -- do not use 
+21   TX4927-CP0/05 Multiplexed -- do not use 
+22   TX4927-CP0/06 Multiplexed -- do not use 
+23   TX4927-CP0/07 CPU TIMER
+
+24   TX4927-PIC/00
+25   TX4927-PIC/01
+26   TX4927-PIC/02  
+27   TX4927-PIC/03 Cascade RBTX4927-IOC
+28   TX4927-PIC/04
+29   TX4927-PIC/05 RBTX4927 RTL-8019AS ethernet
+30   TX4927-PIC/06
+31   TX4927-PIC/07
+32   TX4927-PIC/08 TX4927 SerialIO Channel 0
+33   TX4927-PIC/09 TX4927 SerialIO Channel 1
+34   TX4927-PIC/10
+35   TX4927-PIC/11
+36   TX4927-PIC/12
+37   TX4927-PIC/13
+38   TX4927-PIC/14
+39   TX4927-PIC/15
+40   TX4927-PIC/16 TX4927 PCI PCI-C
+41   TX4927-PIC/17
+42   TX4927-PIC/18
+43   TX4927-PIC/19
+44   TX4927-PIC/20
+45   TX4927-PIC/21
+46   TX4927-PIC/22 TX4927 PCI PCI-ERR 
+47   TX4927-PIC/23 TX4927 PCI PCI-PMA (not used)
+48   TX4927-PIC/24
+49   TX4927-PIC/25
+50   TX4927-PIC/26
+51   TX4927-PIC/27
+52   TX4927-PIC/28
+53   TX4927-PIC/29
+54   TX4927-PIC/30
+55   TX4927-PIC/31
+
+56 RBTX4927-IOC/00 FPCIB0 PCI-D PJ4/A PJ5/B SB/C PJ6/D PJ7/A (SouthBridge/NotUsed)        [RTL-8139=PJ4]
+57 RBTX4927-IOC/01 FPCIB0 PCI-C PJ4/D PJ5/A SB/B PJ6/C PJ7/D (SouthBridge/NotUsed)        [RTL-8139=PJ5]
+58 RBTX4927-IOC/02 FPCIB0 PCI-B PJ4/C PJ5/D SB/A PJ6/B PJ7/C (SouthBridge/IDE/pin=1,INTR) [RTL-8139=NotSupported]
+59 RBTX4927-IOC/03 FPCIB0 PCI-A PJ4/B PJ5/C SB/D PJ6/A PJ7/B (SouthBridge/USB/pin=4)      [RTL-8139=PJ6]
+60 RBTX4927-IOC/04
+61 RBTX4927-IOC/05
+62 RBTX4927-IOC/06
+63 RBTX4927-IOC/07
+
+NOTES: 
+SouthBridge/INTR is mapped to SouthBridge/A=PCI-B/#58
+SouthBridge/ISA/pin=0 no pci irq used by this device
+SouthBridge/IDE/pin=1 no pci irq used by this device, using INTR via ISA IRQ14
+SouthBridge/USB/pin=4 using pci irq SouthBridge/D=PCI-A=#59
+SouthBridge/PMC/pin=0 no pci irq used by this device
+SuperIO/PS2/Keyboard, using INTR via ISA IRQ1
+SuperIO/PS2/Mouse, using INTR via ISA IRQ12 (mouse not currently supported)
+JP7 is not bus master -- do NOT use -- only 4 pci bus master's allowed -- SouthBridge, JP4, JP5, JP6
+*/
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/timex.h>
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pci.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/reboot.h>
+#include <asm/time.h>
+#include <linux/bootmem.h>
+#include <linux/blkdev.h>
+#ifdef CONFIG_RTC_DS1742
+#include <linux/ds1742rtc.h>
+#endif
+#ifdef CONFIG_TOSHIBA_FPCIB0
+#include <asm/tx4927/smsc_fdc37m81x.h>
+#endif
+#include <asm/tx4927/toshiba_rbtx4927.h>
+
+
+#undef TOSHIBA_RBTX4927_IRQ_DEBUG
+
+#ifdef TOSHIBA_RBTX4927_IRQ_DEBUG
+#define TOSHIBA_RBTX4927_IRQ_NONE        0x00000000
+
+#define TOSHIBA_RBTX4927_IRQ_INFO          ( 1 <<  0 )
+#define TOSHIBA_RBTX4927_IRQ_WARN          ( 1 <<  1 )
+#define TOSHIBA_RBTX4927_IRQ_EROR          ( 1 <<  2 )
+
+#define TOSHIBA_RBTX4927_IRQ_IOC_INIT      ( 1 << 10 )
+#define TOSHIBA_RBTX4927_IRQ_IOC_STARTUP   ( 1 << 11 )
+#define TOSHIBA_RBTX4927_IRQ_IOC_SHUTDOWN  ( 1 << 12 )
+#define TOSHIBA_RBTX4927_IRQ_IOC_ENABLE    ( 1 << 13 )
+#define TOSHIBA_RBTX4927_IRQ_IOC_DISABLE   ( 1 << 14 )
+#define TOSHIBA_RBTX4927_IRQ_IOC_MASK      ( 1 << 15 )
+#define TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ    ( 1 << 16 )
+
+#define TOSHIBA_RBTX4927_IRQ_ISA_INIT      ( 1 << 20 )
+#define TOSHIBA_RBTX4927_IRQ_ISA_STARTUP   ( 1 << 21 )
+#define TOSHIBA_RBTX4927_IRQ_ISA_SHUTDOWN  ( 1 << 22 )
+#define TOSHIBA_RBTX4927_IRQ_ISA_ENABLE    ( 1 << 23 )
+#define TOSHIBA_RBTX4927_IRQ_ISA_DISABLE   ( 1 << 24 )
+#define TOSHIBA_RBTX4927_IRQ_ISA_MASK      ( 1 << 25 )
+#define TOSHIBA_RBTX4927_IRQ_ISA_ENDIRQ    ( 1 << 26 )
+
+#define TOSHIBA_RBTX4927_SETUP_ALL         0xffffffff
+#endif
+
+
+#ifdef TOSHIBA_RBTX4927_IRQ_DEBUG
+static const u32 toshiba_rbtx4927_irq_debug_flag =
+    (TOSHIBA_RBTX4927_IRQ_NONE | TOSHIBA_RBTX4927_IRQ_INFO |
+     TOSHIBA_RBTX4927_IRQ_WARN | TOSHIBA_RBTX4927_IRQ_EROR
+//                                                 | TOSHIBA_RBTX4927_IRQ_IOC_INIT  
+//                                                 | TOSHIBA_RBTX4927_IRQ_IOC_STARTUP  
+//                                                 | TOSHIBA_RBTX4927_IRQ_IOC_SHUTDOWN  
+//                                                 | TOSHIBA_RBTX4927_IRQ_IOC_ENABLE  
+//                                                 | TOSHIBA_RBTX4927_IRQ_IOC_DISABLE  
+//                                                 | TOSHIBA_RBTX4927_IRQ_IOC_MASK  
+//                                                 | TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ  
+//                                                 | TOSHIBA_RBTX4927_IRQ_ISA_INIT  
+//                                                 | TOSHIBA_RBTX4927_IRQ_ISA_STARTUP  
+//                                                 | TOSHIBA_RBTX4927_IRQ_ISA_SHUTDOWN  
+//                                                 | TOSHIBA_RBTX4927_IRQ_ISA_ENABLE  
+//                                                 | TOSHIBA_RBTX4927_IRQ_ISA_DISABLE  
+//                                                 | TOSHIBA_RBTX4927_IRQ_ISA_MASK  
+//                                                 | TOSHIBA_RBTX4927_IRQ_ISA_ENDIRQ
+    );
+#endif
+
+
+#ifdef TOSHIBA_RBTX4927_IRQ_DEBUG
+#define TOSHIBA_RBTX4927_IRQ_DPRINTK(flag,str...) \
+        if ( (toshiba_rbtx4927_irq_debug_flag) & (flag) ) \
+        { \
+           char tmp[100]; \
+           sprintf( tmp, str ); \
+           printk( "%s(%s:%u)::%s", __FUNCTION__, __FILE__, __LINE__, tmp ); \
+        }
+#else
+#define TOSHIBA_RBTX4927_IRQ_DPRINTK(flag,str...)
+#endif
+
+
+
+
+#define TOSHIBA_RBTX4927_IRQ_IOC_RAW_BEG   0
+#define TOSHIBA_RBTX4927_IRQ_IOC_RAW_END   7
+
+#define TOSHIBA_RBTX4927_IRQ_IOC_BEG  ((TX4927_IRQ_PIC_END+1)+TOSHIBA_RBTX4927_IRQ_IOC_RAW_BEG)	/* 56 */
+#define TOSHIBA_RBTX4927_IRQ_IOC_END  ((TX4927_IRQ_PIC_END+1)+TOSHIBA_RBTX4927_IRQ_IOC_RAW_END)	/* 63 */
+
+
+#define TOSHIBA_RBTX4927_IRQ_ISA_BEG MI8259_IRQ_ISA_BEG
+#define TOSHIBA_RBTX4927_IRQ_ISA_END MI8259_IRQ_ISA_END
+#define TOSHIBA_RBTX4927_IRQ_ISA_MID ((TOSHIBA_RBTX4927_IRQ_ISA_BEG+TOSHIBA_RBTX4927_IRQ_ISA_END+1)/2)
+
+
+#define TOSHIBA_RBTX4927_IRQ_NEST_IOC_ON_PIC TX4927_IRQ_NEST_EXT_ON_PIC
+#define TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC (TOSHIBA_RBTX4927_IRQ_IOC_BEG+2)
+#define TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_ISA (TOSHIBA_RBTX4927_IRQ_ISA_BEG+2)
+
+extern int tx4927_using_backplane;
+
+#ifdef CONFIG_TOSHIBA_FPCIB0
+extern void enable_8259A_irq(unsigned int irq);
+extern void disable_8259A_irq(unsigned int irq);
+extern void mask_and_ack_8259A(unsigned int irq);
+#endif
+
+static unsigned int toshiba_rbtx4927_irq_ioc_startup(unsigned int irq);
+static void toshiba_rbtx4927_irq_ioc_shutdown(unsigned int irq);
+static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq);
+static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq);
+static void toshiba_rbtx4927_irq_ioc_mask_and_ack(unsigned int irq);
+static void toshiba_rbtx4927_irq_ioc_end(unsigned int irq);
+
+#ifdef CONFIG_TOSHIBA_FPCIB0
+static unsigned int toshiba_rbtx4927_irq_isa_startup(unsigned int irq);
+static void toshiba_rbtx4927_irq_isa_shutdown(unsigned int irq);
+static void toshiba_rbtx4927_irq_isa_enable(unsigned int irq);
+static void toshiba_rbtx4927_irq_isa_disable(unsigned int irq);
+static void toshiba_rbtx4927_irq_isa_mask_and_ack(unsigned int irq);
+static void toshiba_rbtx4927_irq_isa_end(unsigned int irq);
+#endif
+
+static DEFINE_SPINLOCK(toshiba_rbtx4927_ioc_lock);
+
+
+#define TOSHIBA_RBTX4927_IOC_NAME "RBTX4927-IOC"
+static struct hw_interrupt_type toshiba_rbtx4927_irq_ioc_type = {
+	.typename = TOSHIBA_RBTX4927_IOC_NAME,
+	.startup = toshiba_rbtx4927_irq_ioc_startup,
+	.shutdown = toshiba_rbtx4927_irq_ioc_shutdown,
+	.enable = toshiba_rbtx4927_irq_ioc_enable,
+	.disable = toshiba_rbtx4927_irq_ioc_disable,
+	.ack = toshiba_rbtx4927_irq_ioc_mask_and_ack,
+	.end = toshiba_rbtx4927_irq_ioc_end,
+	.set_affinity = NULL
+};
+#define TOSHIBA_RBTX4927_IOC_INTR_ENAB 0xbc002000
+#define TOSHIBA_RBTX4927_IOC_INTR_STAT 0xbc002006
+
+
+#ifdef CONFIG_TOSHIBA_FPCIB0
+#define TOSHIBA_RBTX4927_ISA_NAME "RBTX4927-ISA"
+static struct hw_interrupt_type toshiba_rbtx4927_irq_isa_type = {
+	.typename = TOSHIBA_RBTX4927_ISA_NAME,
+	.startup = toshiba_rbtx4927_irq_isa_startup,
+	.shutdown = toshiba_rbtx4927_irq_isa_shutdown,
+	.enable = toshiba_rbtx4927_irq_isa_enable,
+	.disable = toshiba_rbtx4927_irq_isa_disable,
+	.ack = toshiba_rbtx4927_irq_isa_mask_and_ack,
+	.end = toshiba_rbtx4927_irq_isa_end,
+	.set_affinity = NULL
+};
+#endif
+
+
+u32 bit2num(u32 num)
+{
+	u32 i;
+
+	for (i = 0; i < (sizeof(num) * 8); i++) {
+		if (num & (1 << i)) {
+			return (i);
+		}
+	}
+	return (0);
+}
+
+int toshiba_rbtx4927_irq_nested(int sw_irq)
+{
+	u32 level3;
+	u32 level4;
+	u32 level5;
+
+	level3 = reg_rd08(TOSHIBA_RBTX4927_IOC_INTR_STAT) & 0x1f;
+	if (level3) {
+		sw_irq = TOSHIBA_RBTX4927_IRQ_IOC_BEG + bit2num(level3);
+		if (sw_irq != TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC) {
+			goto RETURN;
+		}
+	}
+#ifdef CONFIG_TOSHIBA_FPCIB0
+	{
+		if (tx4927_using_backplane) {
+			outb(0x0A, 0x20);
+			level4 = inb(0x20) & 0xff;
+			if (level4) {
+				sw_irq =
+				    TOSHIBA_RBTX4927_IRQ_ISA_BEG +
+				    bit2num(level4);
+				if (sw_irq !=
+				    TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_ISA) {
+					goto RETURN;
+				}
+			}
+
+			outb(0x0A, 0xA0);
+			level5 = inb(0xA0) & 0xff;
+			if (level5) {
+				sw_irq =
+				    TOSHIBA_RBTX4927_IRQ_ISA_MID +
+				    bit2num(level5);
+				goto RETURN;
+			}
+		}
+	}
+#endif
+
+      RETURN:
+	return (sw_irq);
+}
+
+//#define TOSHIBA_RBTX4927_PIC_ACTION(s) { no_action, 0, CPU_MASK_NONE, s, NULL, NULL }
+#define TOSHIBA_RBTX4927_PIC_ACTION(s) { no_action, SA_SHIRQ, CPU_MASK_NONE, s, NULL, NULL }
+static struct irqaction toshiba_rbtx4927_irq_ioc_action =
+TOSHIBA_RBTX4927_PIC_ACTION(TOSHIBA_RBTX4927_IOC_NAME);
+#ifdef CONFIG_TOSHIBA_FPCIB0
+static struct irqaction toshiba_rbtx4927_irq_isa_master =
+TOSHIBA_RBTX4927_PIC_ACTION(TOSHIBA_RBTX4927_ISA_NAME "/M");
+static struct irqaction toshiba_rbtx4927_irq_isa_slave =
+TOSHIBA_RBTX4927_PIC_ACTION(TOSHIBA_RBTX4927_ISA_NAME "/S");
+#endif
+
+
+/**********************************************************************************/
+/* Functions for ioc                                                              */
+/**********************************************************************************/
+
+
+static void __init toshiba_rbtx4927_irq_ioc_init(void)
+{
+	int i;
+
+	TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_INIT,
+				     "beg=%d end=%d\n",
+				     TOSHIBA_RBTX4927_IRQ_IOC_BEG,
+				     TOSHIBA_RBTX4927_IRQ_IOC_END);
+
+	for (i = TOSHIBA_RBTX4927_IRQ_IOC_BEG;
+	     i <= TOSHIBA_RBTX4927_IRQ_IOC_END; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = 0;
+		irq_desc[i].depth = 3;
+		irq_desc[i].handler = &toshiba_rbtx4927_irq_ioc_type;
+	}
+
+	setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_IOC_ON_PIC,
+		  &toshiba_rbtx4927_irq_ioc_action);
+
+	return;
+}
+
+static unsigned int toshiba_rbtx4927_irq_ioc_startup(unsigned int irq)
+{
+	TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_STARTUP,
+				     "irq=%d\n", irq);
+
+	if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG
+	    || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) {
+		TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR,
+					     "bad irq=%d\n", irq);
+		panic("\n");
+	}
+
+	toshiba_rbtx4927_irq_ioc_enable(irq);
+
+	return (0);
+}
+
+
+static void toshiba_rbtx4927_irq_ioc_shutdown(unsigned int irq)
+{
+	TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_SHUTDOWN,
+				     "irq=%d\n", irq);
+
+	if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG
+	    || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) {
+		TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR,
+					     "bad irq=%d\n", irq);
+		panic("\n");
+	}
+
+	toshiba_rbtx4927_irq_ioc_disable(irq);
+
+	return;
+}
+
+
+static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq)
+{
+	unsigned long flags;
+	volatile unsigned char v;
+
+	TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_ENABLE,
+				     "irq=%d\n", irq);
+
+	if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG
+	    || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) {
+		TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR,
+					     "bad irq=%d\n", irq);
+		panic("\n");
+	}
+
+	spin_lock_irqsave(&toshiba_rbtx4927_ioc_lock, flags);
+
+	v = TX4927_RD08(TOSHIBA_RBTX4927_IOC_INTR_ENAB);
+	v |= (1 << (irq - TOSHIBA_RBTX4927_IRQ_IOC_BEG));
+	TOSHIBA_RBTX4927_WR08(TOSHIBA_RBTX4927_IOC_INTR_ENAB, v);
+
+	spin_unlock_irqrestore(&toshiba_rbtx4927_ioc_lock, flags);
+
+	return;
+}
+
+
+static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq)
+{
+	unsigned long flags;
+	volatile unsigned char v;
+
+	TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_DISABLE,
+				     "irq=%d\n", irq);
+
+	if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG
+	    || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) {
+		TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR,
+					     "bad irq=%d\n", irq);
+		panic("\n");
+	}
+
+	spin_lock_irqsave(&toshiba_rbtx4927_ioc_lock, flags);
+
+	v = TX4927_RD08(TOSHIBA_RBTX4927_IOC_INTR_ENAB);
+	v &= ~(1 << (irq - TOSHIBA_RBTX4927_IRQ_IOC_BEG));
+	TOSHIBA_RBTX4927_WR08(TOSHIBA_RBTX4927_IOC_INTR_ENAB, v);
+
+	spin_unlock_irqrestore(&toshiba_rbtx4927_ioc_lock, flags);
+
+	return;
+}
+
+
+static void toshiba_rbtx4927_irq_ioc_mask_and_ack(unsigned int irq)
+{
+	TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_MASK,
+				     "irq=%d\n", irq);
+
+	if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG
+	    || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) {
+		TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR,
+					     "bad irq=%d\n", irq);
+		panic("\n");
+	}
+
+	toshiba_rbtx4927_irq_ioc_disable(irq);
+
+	return;
+}
+
+
+static void toshiba_rbtx4927_irq_ioc_end(unsigned int irq)
+{
+	TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ,
+				     "irq=%d\n", irq);
+
+	if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG
+	    || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) {
+		TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR,
+					     "bad irq=%d\n", irq);
+		panic("\n");
+	}
+
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+		toshiba_rbtx4927_irq_ioc_enable(irq);
+	}
+
+	return;
+}
+
+
+/**********************************************************************************/
+/* Functions for isa                                                              */
+/**********************************************************************************/
+
+
+#ifdef CONFIG_TOSHIBA_FPCIB0
+static void __init toshiba_rbtx4927_irq_isa_init(void)
+{
+	int i;
+
+	TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_INIT,
+				     "beg=%d end=%d\n",
+				     TOSHIBA_RBTX4927_IRQ_ISA_BEG,
+				     TOSHIBA_RBTX4927_IRQ_ISA_END);
+
+	for (i = TOSHIBA_RBTX4927_IRQ_ISA_BEG;
+	     i <= TOSHIBA_RBTX4927_IRQ_ISA_END; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = 0;
+		irq_desc[i].depth =
+		    ((i < TOSHIBA_RBTX4927_IRQ_ISA_MID) ? (4) : (5));
+		irq_desc[i].handler = &toshiba_rbtx4927_irq_isa_type;
+	}
+
+	setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC,
+		  &toshiba_rbtx4927_irq_isa_master);
+	setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_ISA,
+		  &toshiba_rbtx4927_irq_isa_slave);
+
+	/* make sure we are looking at IRR (not ISR) */
+	outb(0x0A, 0x20);
+	outb(0x0A, 0xA0);
+
+	return;
+}
+#endif
+
+
+#ifdef CONFIG_TOSHIBA_FPCIB0
+static unsigned int toshiba_rbtx4927_irq_isa_startup(unsigned int irq)
+{
+	TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_STARTUP,
+				     "irq=%d\n", irq);
+
+	if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG
+	    || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) {
+		TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR,
+					     "bad irq=%d\n", irq);
+		panic("\n");
+	}
+
+	toshiba_rbtx4927_irq_isa_enable(irq);
+
+	return (0);
+}
+#endif
+
+
+#ifdef CONFIG_TOSHIBA_FPCIB0
+static void toshiba_rbtx4927_irq_isa_shutdown(unsigned int irq)
+{
+	TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_SHUTDOWN,
+				     "irq=%d\n", irq);
+
+	if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG
+	    || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) {
+		TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR,
+					     "bad irq=%d\n", irq);
+		panic("\n");
+	}
+
+	toshiba_rbtx4927_irq_isa_disable(irq);
+
+	return;
+}
+#endif
+
+
+#ifdef CONFIG_TOSHIBA_FPCIB0
+static void toshiba_rbtx4927_irq_isa_enable(unsigned int irq)
+{
+	TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_ENABLE,
+				     "irq=%d\n", irq);
+
+	if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG
+	    || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) {
+		TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR,
+					     "bad irq=%d\n", irq);
+		panic("\n");
+	}
+
+	enable_8259A_irq(irq);
+
+	return;
+}
+#endif
+
+
+#ifdef CONFIG_TOSHIBA_FPCIB0
+static void toshiba_rbtx4927_irq_isa_disable(unsigned int irq)
+{
+	TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_DISABLE,
+				     "irq=%d\n", irq);
+
+	if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG
+	    || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) {
+		TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR,
+					     "bad irq=%d\n", irq);
+		panic("\n");
+	}
+
+	disable_8259A_irq(irq);
+
+	return;
+}
+#endif
+
+
+#ifdef CONFIG_TOSHIBA_FPCIB0
+static void toshiba_rbtx4927_irq_isa_mask_and_ack(unsigned int irq)
+{
+	TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_MASK,
+				     "irq=%d\n", irq);
+
+	if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG
+	    || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) {
+		TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR,
+					     "bad irq=%d\n", irq);
+		panic("\n");
+	}
+
+	mask_and_ack_8259A(irq);
+
+	return;
+}
+#endif
+
+
+#ifdef CONFIG_TOSHIBA_FPCIB0
+static void toshiba_rbtx4927_irq_isa_end(unsigned int irq)
+{
+	TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_ENDIRQ,
+				     "irq=%d\n", irq);
+
+	if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG
+	    || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) {
+		TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR,
+					     "bad irq=%d\n", irq);
+		panic("\n");
+	}
+
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+		toshiba_rbtx4927_irq_isa_enable(irq);
+	}
+
+	return;
+}
+#endif
+
+
+void __init arch_init_irq(void)
+{
+	extern void tx4927_irq_init(void);
+
+	local_irq_disable();
+
+	tx4927_irq_init();
+	toshiba_rbtx4927_irq_ioc_init();
+#ifdef CONFIG_TOSHIBA_FPCIB0
+	{
+		if (tx4927_using_backplane) {
+			toshiba_rbtx4927_irq_isa_init();
+		}
+	}
+#endif
+
+	wbflush();
+
+	return;
+}
+
+void toshiba_rbtx4927_irq_dump(char *key)
+{
+#ifdef TOSHIBA_RBTX4927_IRQ_DEBUG
+	{
+		u32 i, j = 0;
+		for (i = 0; i < NR_IRQS; i++) {
+			if (strcmp(irq_desc[i].handler->typename, "none")
+			    == 0)
+				continue;
+
+			if ((i >= 1)
+			    && (irq_desc[i - 1].handler->typename ==
+				irq_desc[i].handler->typename)) {
+				j++;
+			} else {
+				j = 0;
+			}
+			TOSHIBA_RBTX4927_IRQ_DPRINTK
+			    (TOSHIBA_RBTX4927_IRQ_INFO,
+			     "%s irq=0x%02x/%3d s=0x%08x h=0x%08x a=0x%08x ah=0x%08x d=%1d n=%s/%02d\n",
+			     key, i, i, irq_desc[i].status,
+			     (u32) irq_desc[i].handler,
+			     (u32) irq_desc[i].action,
+			     (u32) (irq_desc[i].action ? irq_desc[i].
+				    action->handler : 0),
+			     irq_desc[i].depth,
+			     irq_desc[i].handler->typename, j);
+		}
+	}
+#endif
+	return;
+}
+
+void toshiba_rbtx4927_irq_dump_pics(char *s)
+{
+	u32 level0_m;
+	u32 level0_s;
+	u32 level1_m;
+	u32 level1_s;
+	u32 level2;
+	u32 level2_p;
+	u32 level2_s;
+	u32 level3_m;
+	u32 level3_s;
+	u32 level4_m;
+	u32 level4_s;
+	u32 level5_m;
+	u32 level5_s;
+
+	if (s == NULL)
+		s = "null";
+
+	level0_m = (read_c0_status() & 0x0000ff00) >> 8;
+	level0_s = (read_c0_cause() & 0x0000ff00) >> 8;
+
+	level1_m = level0_m;
+	level1_s = level0_s & 0x87;
+
+	level2 = TX4927_RD(0xff1ff6a0);
+	level2_p = (((level2 & 0x10000)) ? 0 : 1);
+	level2_s = (((level2 & 0x1f) == 0x1f) ? 0 : (level2 & 0x1f));
+
+	level3_m = reg_rd08(TOSHIBA_RBTX4927_IOC_INTR_ENAB) & 0x1f;
+	level3_s = reg_rd08(TOSHIBA_RBTX4927_IOC_INTR_STAT) & 0x1f;
+
+	level4_m = inb(0x21);
+	outb(0x0A, 0x20);
+	level4_s = inb(0x20);
+
+	level5_m = inb(0xa1);
+	outb(0x0A, 0xa0);
+	level5_s = inb(0xa0);
+
+	TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO,
+				     "dump_raw_pic() ");
+	TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO,
+				     "cp0:m=0x%02x/s=0x%02x ", level0_m,
+				     level0_s);
+	TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO,
+				     "cp0:m=0x%02x/s=0x%02x ", level1_m,
+				     level1_s);
+	TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO,
+				     "pic:e=0x%02x/s=0x%02x ", level2_p,
+				     level2_s);
+	TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO,
+				     "ioc:m=0x%02x/s=0x%02x ", level3_m,
+				     level3_s);
+	TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO,
+				     "sbm:m=0x%02x/s=0x%02x ", level4_m,
+				     level4_s);
+	TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO,
+				     "sbs:m=0x%02x/s=0x%02x ", level5_m,
+				     level5_s);
+	TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, "[%s]\n",
+				     s);
+
+	return;
+}
diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c
new file mode 100644
index 0000000..e4d095d
--- /dev/null
+++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c
@@ -0,0 +1,97 @@
+/*
+ * rbtx4927 specific prom routines
+ *
+ * Author: MontaVista Software, Inc.
+ *         source@mvista.com
+ *
+ * Copyright 2001-2002 MontaVista Software Inc.
+ *
+ * Copyright (C) 2004 MontaVista Software Inc.
+ * Author: Manish Lachwani, mlachwani@mvista.com
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/tx4927/tx4927.h>
+
+void __init prom_init_cmdline(void)
+{
+	int argc = (int) fw_arg0;
+	char **argv = (char **) fw_arg1;
+	int i;			/* Always ignore the "-c" at argv[0] */
+
+	/* ignore all built-in args if any f/w args given */
+	if (argc > 1) {
+		*arcs_cmdline = '\0';
+	}
+
+	for (i = 1; i < argc; i++) {
+		if (i != 1) {
+			strcat(arcs_cmdline, " ");
+		}
+		strcat(arcs_cmdline, argv[i]);
+	}
+}
+
+void __init prom_init(void)
+{
+	const char* toshiba_name_list[] = GROUP_TOSHIBA_NAMES;
+	extern int tx4927_get_mem_size(void);
+	extern char* toshiba_name;
+	int msize;
+
+	prom_init_cmdline();
+
+	mips_machgroup = MACH_GROUP_TOSHIBA;
+
+	if ((read_c0_prid() & 0xff) == PRID_REV_TX4927)
+		mips_machtype = MACH_TOSHIBA_RBTX4927;
+	else
+		mips_machtype = MACH_TOSHIBA_RBTX4937;
+
+        toshiba_name = toshiba_name_list[mips_machtype];
+
+	msize = tx4927_get_mem_size();
+	add_memory_region(0, msize << 20, BOOT_MEM_RAM);
+}
+
+unsigned long __init prom_free_prom_memory(void)
+{
+	return 0;
+}
+
+const char *get_system_type(void)
+{
+	return "Toshiba RBTX4927/RBTX4937";
+}
+
+char * __init prom_getcmdline(void)
+{
+        return &(arcs_cmdline[0]);
+}
+
diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
new file mode 100644
index 0000000..8724ea3
--- /dev/null
+++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
@@ -0,0 +1,1024 @@
+/*
+ * Toshiba rbtx4927 specific setup
+ *
+ * Author: MontaVista Software, Inc.
+ *         source@mvista.com
+ *
+ * Copyright 2001-2002 MontaVista Software Inc.
+ *
+ * Copyright (C) 1996, 97, 2001, 04  Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: RidgeRun, Inc.
+ *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ * Author: Michael Pruznick, michael_pruznick@mvista.com
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * Copyright (C) 2004 MontaVista Software Inc.
+ * Author: Manish Lachwani, mlachwani@mvista.com
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/timex.h>
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/reboot.h>
+#include <asm/time.h>
+#include <linux/bootmem.h>
+#include <linux/blkdev.h>
+#ifdef CONFIG_RTC_DS1742
+#include <linux/ds1742rtc.h>
+#endif
+#ifdef CONFIG_TOSHIBA_FPCIB0
+#include <asm/tx4927/smsc_fdc37m81x.h>
+#endif
+#include <asm/tx4927/toshiba_rbtx4927.h>
+#ifdef CONFIG_PCI
+#include <asm/tx4927/tx4927_pci.h>
+#endif
+#ifdef CONFIG_BLK_DEV_IDEPCI
+#include <linux/hdreg.h>
+#include <linux/ide.h>
+#endif
+
+#undef TOSHIBA_RBTX4927_SETUP_DEBUG
+
+#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG
+#define TOSHIBA_RBTX4927_SETUP_NONE        0x00000000
+
+#define TOSHIBA_RBTX4927_SETUP_INFO        ( 1 <<  0 )
+#define TOSHIBA_RBTX4927_SETUP_WARN        ( 1 <<  1 )
+#define TOSHIBA_RBTX4927_SETUP_EROR        ( 1 <<  2 )
+
+#define TOSHIBA_RBTX4927_SETUP_EFWFU       ( 1 <<  3 )
+#define TOSHIBA_RBTX4927_SETUP_SETUP       ( 1 <<  4 )
+#define TOSHIBA_RBTX4927_SETUP_TIME_INIT   ( 1 <<  5 )
+#define TOSHIBA_RBTX4927_SETUP_TIMER_SETUP ( 1 <<  6 )
+#define TOSHIBA_RBTX4927_SETUP_PCIBIOS     ( 1 <<  7 )
+#define TOSHIBA_RBTX4927_SETUP_PCI1        ( 1 <<  8 )
+#define TOSHIBA_RBTX4927_SETUP_PCI2        ( 1 <<  9 )
+#define TOSHIBA_RBTX4927_SETUP_PCI66       ( 1 << 10 )
+
+#define TOSHIBA_RBTX4927_SETUP_ALL         0xffffffff
+#endif
+
+#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG
+static const u32 toshiba_rbtx4927_setup_debug_flag =
+    (TOSHIBA_RBTX4927_SETUP_NONE | TOSHIBA_RBTX4927_SETUP_INFO |
+     TOSHIBA_RBTX4927_SETUP_WARN | TOSHIBA_RBTX4927_SETUP_EROR |
+     TOSHIBA_RBTX4927_SETUP_EFWFU | TOSHIBA_RBTX4927_SETUP_SETUP |
+     TOSHIBA_RBTX4927_SETUP_TIME_INIT | TOSHIBA_RBTX4927_SETUP_TIMER_SETUP
+     | TOSHIBA_RBTX4927_SETUP_PCIBIOS | TOSHIBA_RBTX4927_SETUP_PCI1 |
+     TOSHIBA_RBTX4927_SETUP_PCI2 | TOSHIBA_RBTX4927_SETUP_PCI66);
+#endif
+
+#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG
+#define TOSHIBA_RBTX4927_SETUP_DPRINTK(flag,str...) \
+        if ( (toshiba_rbtx4927_setup_debug_flag) & (flag) ) \
+        { \
+           char tmp[100]; \
+           sprintf( tmp, str ); \
+           printk( "%s(%s:%u)::%s", __FUNCTION__, __FILE__, __LINE__, tmp ); \
+        }
+#else
+#define TOSHIBA_RBTX4927_SETUP_DPRINTK(flag,str...)
+#endif
+
+/* These functions are used for rebooting or halting the machine*/
+extern void toshiba_rbtx4927_restart(char *command);
+extern void toshiba_rbtx4927_halt(void);
+extern void toshiba_rbtx4927_power_off(void);
+
+int tx4927_using_backplane = 0;
+
+extern void gt64120_time_init(void);
+extern void toshiba_rbtx4927_irq_setup(void);
+
+#ifdef CONFIG_PCI
+#define CONFIG_TX4927BUG_WORKAROUND
+#undef TX4927_SUPPORT_COMMAND_IO
+#undef  TX4927_SUPPORT_PCI_66
+int tx4927_cpu_clock = 100000000;	/* 100MHz */
+unsigned long mips_pci_io_base;
+unsigned long mips_pci_io_size;
+unsigned long mips_pci_mem_base;
+unsigned long mips_pci_mem_size;
+/* for legacy I/O, PCI I/O PCI Bus address must be 0 */
+unsigned long mips_pci_io_pciaddr = 0;
+unsigned long mips_memory_upper;
+static int tx4927_ccfg_toeon = 1;
+static int tx4927_pcic_trdyto = 0;	/* default: disabled */
+unsigned long tx4927_ce_base[8];
+void tx4927_pci_setup(void);
+void tx4927_reset_pci_pcic(void);
+int tx4927_pci66 = 0;		/* 0:auto */
+#endif
+
+char *toshiba_name = "";
+
+#ifdef CONFIG_PCI
+static void tx4927_pcierr_interrupt(int irq, void *dev_id,
+				    struct pt_regs *regs)
+{
+#ifdef CONFIG_BLK_DEV_IDEPCI
+	/* ignore MasterAbort for ide probing... */
+	if (irq == TX4927_IRQ_IRC_PCIERR &&
+	    ((tx4927_pcicptr->pcistatus >> 16) & 0xf900) ==
+	    PCI_STATUS_REC_MASTER_ABORT) {
+		tx4927_pcicptr->pcistatus =
+		    (tx4927_pcicptr->
+		     pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT
+						<< 16);
+
+		return;
+	}
+#endif
+	printk("PCI error interrupt (irq 0x%x).\n", irq);
+
+	printk("pcistat:%04x, g2pstatus:%08lx, pcicstatus:%08lx\n",
+	       (unsigned short) (tx4927_pcicptr->pcistatus >> 16),
+	       tx4927_pcicptr->g2pstatus, tx4927_pcicptr->pcicstatus);
+	printk("ccfg:%08lx, tear:%02lx_%08lx\n",
+	       (unsigned long) tx4927_ccfgptr->ccfg,
+	       (unsigned long) (tx4927_ccfgptr->tear >> 32),
+	       (unsigned long) tx4927_ccfgptr->tear);
+	show_regs(regs);
+}
+
+void __init toshiba_rbtx4927_pci_irq_init(void)
+{
+	return;
+}
+
+void tx4927_reset_pci_pcic(void)
+{
+	/* Reset PCI Bus */
+	*tx4927_pcireset_ptr = 1;
+	/* Reset PCIC */
+	tx4927_ccfgptr->clkctr |= TX4927_CLKCTR_PCIRST;
+	udelay(10000);
+	/* clear PCIC reset */
+	tx4927_ccfgptr->clkctr &= ~TX4927_CLKCTR_PCIRST;
+	*tx4927_pcireset_ptr = 0;
+}
+#endif /* CONFIG_PCI */
+
+#ifdef CONFIG_PCI
+void print_pci_status(void)
+{
+	printk("PCI STATUS %lx\n", tx4927_pcicptr->pcistatus);
+	printk("PCIC STATUS %lx\n", tx4927_pcicptr->pcicstatus);
+}
+
+extern struct pci_controller tx4927_controller;
+
+static struct pci_dev *fake_pci_dev(struct pci_controller *hose,
+				    int top_bus, int busnr, int devfn)
+{
+	static struct pci_dev dev;
+	static struct pci_bus bus;
+
+	dev.sysdata = (void *)hose;
+	dev.devfn = devfn;
+	bus.number = busnr;
+	bus.ops = hose->pci_ops;
+	bus.parent = NULL;
+	dev.bus = &bus;
+
+	return &dev;
+}
+
+#define EARLY_PCI_OP(rw, size, type)                                    \
+static int early_##rw##_config_##size(struct pci_controller *hose,      \
+        int top_bus, int bus, int devfn, int offset, type value)        \
+{                                                                       \
+        return pci_##rw##_config_##size(                                \
+                fake_pci_dev(hose, top_bus, bus, devfn),                \
+                offset, value);                                         \
+}
+
+EARLY_PCI_OP(read, byte, u8 *)
+EARLY_PCI_OP(read, word, u16 *)
+EARLY_PCI_OP(read, dword, u32 *)
+EARLY_PCI_OP(write, byte, u8)
+EARLY_PCI_OP(write, word, u16)
+EARLY_PCI_OP(write, dword, u32)
+
+static int __init tx4927_pcibios_init(void)
+{
+	unsigned int id;
+	u32 pci_devfn;
+	int devfn_start = 0;
+	int devfn_stop = 0xff;
+	int busno = 0; /* One bus on the Toshiba */
+	struct pci_controller *hose = &tx4927_controller;
+
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCIBIOS,
+				       "-\n");
+
+	for (pci_devfn = devfn_start; pci_devfn < devfn_stop; pci_devfn++) {
+		early_read_config_dword(hose, busno, busno, pci_devfn,
+					PCI_VENDOR_ID, &id);
+
+		if (id == 0xffffffff) {
+			continue;
+		}
+
+		if (id == 0x94601055) {
+			u8 v08_64;
+			u32 v32_b0;
+			u8 v08_e1;
+			char *s = " sb/isa --";
+
+			TOSHIBA_RBTX4927_SETUP_DPRINTK
+			    (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s beg\n",
+			     s);
+
+			early_read_config_byte(hose, busno, busno,
+					       pci_devfn, 0x64, &v08_64);
+			early_read_config_dword(hose, busno, busno,
+						pci_devfn, 0xb0, &v32_b0);
+			early_read_config_byte(hose, busno, busno,
+					       pci_devfn, 0xe1, &v08_e1);
+
+			TOSHIBA_RBTX4927_SETUP_DPRINTK
+			    (TOSHIBA_RBTX4927_SETUP_PCIBIOS,
+			     ":%s beg 0x64 = 0x%02x\n", s, v08_64);
+			TOSHIBA_RBTX4927_SETUP_DPRINTK
+			    (TOSHIBA_RBTX4927_SETUP_PCIBIOS,
+			     ":%s beg 0xb0 = 0x%02x\n", s, v32_b0);
+			TOSHIBA_RBTX4927_SETUP_DPRINTK
+			    (TOSHIBA_RBTX4927_SETUP_PCIBIOS,
+			     ":%s beg 0xe1 = 0x%02x\n", s, v08_e1);
+
+			/* serial irq control */
+			v08_64 = 0xd0;
+
+			/* serial irq pin */
+			v32_b0 |= 0x00010000;
+
+			/* ide irq on isa14 */
+			v08_e1 &= 0xf0;
+			v08_e1 |= 0x0d;
+
+			TOSHIBA_RBTX4927_SETUP_DPRINTK
+			    (TOSHIBA_RBTX4927_SETUP_PCIBIOS,
+			     ":%s mid 0x64 = 0x%02x\n", s, v08_64);
+			TOSHIBA_RBTX4927_SETUP_DPRINTK
+			    (TOSHIBA_RBTX4927_SETUP_PCIBIOS,
+			     ":%s mid 0xb0 = 0x%02x\n", s, v32_b0);
+			TOSHIBA_RBTX4927_SETUP_DPRINTK
+			    (TOSHIBA_RBTX4927_SETUP_PCIBIOS,
+			     ":%s mid 0xe1 = 0x%02x\n", s, v08_e1);
+
+			early_write_config_byte(hose, busno, busno,
+						pci_devfn, 0x64, v08_64);
+			early_write_config_dword(hose, busno, busno,
+						 pci_devfn, 0xb0, v32_b0);
+			early_write_config_byte(hose, busno, busno,
+						pci_devfn, 0xe1, v08_e1);
+
+#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG
+			{
+				early_read_config_byte(hose, busno, busno,
+						       pci_devfn, 0x64,
+						       &v08_64);
+				early_read_config_dword(hose, busno, busno,
+							pci_devfn, 0xb0,
+							&v32_b0);
+				early_read_config_byte(hose, busno, busno,
+						       pci_devfn, 0xe1,
+						       &v08_e1);
+
+				TOSHIBA_RBTX4927_SETUP_DPRINTK
+				    (TOSHIBA_RBTX4927_SETUP_PCIBIOS,
+				     ":%s end 0x64 = 0x%02x\n", s, v08_64);
+				TOSHIBA_RBTX4927_SETUP_DPRINTK
+				    (TOSHIBA_RBTX4927_SETUP_PCIBIOS,
+				     ":%s end 0xb0 = 0x%02x\n", s, v32_b0);
+				TOSHIBA_RBTX4927_SETUP_DPRINTK
+				    (TOSHIBA_RBTX4927_SETUP_PCIBIOS,
+				     ":%s end 0xe1 = 0x%02x\n", s, v08_e1);
+			}
+#endif
+
+			TOSHIBA_RBTX4927_SETUP_DPRINTK
+			    (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s end\n",
+			     s);
+		}
+
+		if (id == 0x91301055) {
+			u8 v08_04;
+			u8 v08_09;
+			u8 v08_41;
+			u8 v08_43;
+			u8 v08_5c;
+			char *s = " sb/ide --";
+
+			TOSHIBA_RBTX4927_SETUP_DPRINTK
+			    (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s beg\n",
+			     s);
+
+			early_read_config_byte(hose, busno, busno,
+					       pci_devfn, 0x04, &v08_04);
+			early_read_config_byte(hose, busno, busno,
+					       pci_devfn, 0x09, &v08_09);
+			early_read_config_byte(hose, busno, busno,
+					       pci_devfn, 0x41, &v08_41);
+			early_read_config_byte(hose, busno, busno,
+					       pci_devfn, 0x43, &v08_43);
+			early_read_config_byte(hose, busno, busno,
+					       pci_devfn, 0x5c, &v08_5c);
+
+			TOSHIBA_RBTX4927_SETUP_DPRINTK
+			    (TOSHIBA_RBTX4927_SETUP_PCIBIOS,
+			     ":%s beg 0x04 = 0x%02x\n", s, v08_04);
+			TOSHIBA_RBTX4927_SETUP_DPRINTK
+			    (TOSHIBA_RBTX4927_SETUP_PCIBIOS,
+			     ":%s beg 0x09 = 0x%02x\n", s, v08_09);
+			TOSHIBA_RBTX4927_SETUP_DPRINTK
+			    (TOSHIBA_RBTX4927_SETUP_PCIBIOS,
+			     ":%s beg 0x41 = 0x%02x\n", s, v08_41);
+			TOSHIBA_RBTX4927_SETUP_DPRINTK
+			    (TOSHIBA_RBTX4927_SETUP_PCIBIOS,
+			     ":%s beg 0x43 = 0x%02x\n", s, v08_43);
+			TOSHIBA_RBTX4927_SETUP_DPRINTK
+			    (TOSHIBA_RBTX4927_SETUP_PCIBIOS,
+			     ":%s beg 0x5c = 0x%02x\n", s, v08_5c);
+
+			/* enable ide master/io */
+			v08_04 |= (PCI_COMMAND_MASTER | PCI_COMMAND_IO);
+
+			/* enable ide native mode */
+			v08_09 |= 0x05;
+
+			/* enable primary ide */
+			v08_41 |= 0x80;
+
+			/* enable secondary ide */
+			v08_43 |= 0x80;
+
+			/* 
+			 * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!!
+			 *
+			 * This line of code is intended to provide the user with a work
+			 * around solution to the anomalies cited in SMSC's anomaly sheet
+			 * entitled, "SLC90E66 Functional Rev.J_0.1 Anomalies"".
+			 *
+			 * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!!
+			 */
+			v08_5c |= 0x01;
+
+			TOSHIBA_RBTX4927_SETUP_DPRINTK
+			    (TOSHIBA_RBTX4927_SETUP_PCIBIOS,
+			     ":%s mid 0x04 = 0x%02x\n", s, v08_04);
+			TOSHIBA_RBTX4927_SETUP_DPRINTK
+			    (TOSHIBA_RBTX4927_SETUP_PCIBIOS,
+			     ":%s mid 0x09 = 0x%02x\n", s, v08_09);
+			TOSHIBA_RBTX4927_SETUP_DPRINTK
+			    (TOSHIBA_RBTX4927_SETUP_PCIBIOS,
+			     ":%s mid 0x41 = 0x%02x\n", s, v08_41);
+			TOSHIBA_RBTX4927_SETUP_DPRINTK
+			    (TOSHIBA_RBTX4927_SETUP_PCIBIOS,
+			     ":%s mid 0x43 = 0x%02x\n", s, v08_43);
+			TOSHIBA_RBTX4927_SETUP_DPRINTK
+			    (TOSHIBA_RBTX4927_SETUP_PCIBIOS,
+			     ":%s mid 0x5c = 0x%02x\n", s, v08_5c);
+
+			early_write_config_byte(hose, busno, busno,
+						pci_devfn, 0x5c, v08_5c);
+			early_write_config_byte(hose, busno, busno,
+						pci_devfn, 0x04, v08_04);
+			early_write_config_byte(hose, busno, busno,
+						pci_devfn, 0x09, v08_09);
+			early_write_config_byte(hose, busno, busno,
+						pci_devfn, 0x41, v08_41);
+			early_write_config_byte(hose, busno, busno,
+						pci_devfn, 0x43, v08_43);
+
+#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG
+			{
+				early_read_config_byte(hose, busno, busno,
+						       pci_devfn, 0x04,
+						       &v08_04);
+				early_read_config_byte(hose, busno, busno,
+						       pci_devfn, 0x09,
+						       &v08_09);
+				early_read_config_byte(hose, busno, busno,
+						       pci_devfn, 0x41,
+						       &v08_41);
+				early_read_config_byte(hose, busno, busno,
+						       pci_devfn, 0x43,
+						       &v08_43);
+				early_read_config_byte(hose, busno, busno,
+						       pci_devfn, 0x5c,
+						       &v08_5c);
+
+				TOSHIBA_RBTX4927_SETUP_DPRINTK
+				    (TOSHIBA_RBTX4927_SETUP_PCIBIOS,
+				     ":%s end 0x04 = 0x%02x\n", s, v08_04);
+				TOSHIBA_RBTX4927_SETUP_DPRINTK
+				    (TOSHIBA_RBTX4927_SETUP_PCIBIOS,
+				     ":%s end 0x09 = 0x%02x\n", s, v08_09);
+				TOSHIBA_RBTX4927_SETUP_DPRINTK
+				    (TOSHIBA_RBTX4927_SETUP_PCIBIOS,
+				     ":%s end 0x41 = 0x%02x\n", s, v08_41);
+				TOSHIBA_RBTX4927_SETUP_DPRINTK
+				    (TOSHIBA_RBTX4927_SETUP_PCIBIOS,
+				     ":%s end 0x43 = 0x%02x\n", s, v08_43);
+				TOSHIBA_RBTX4927_SETUP_DPRINTK
+				    (TOSHIBA_RBTX4927_SETUP_PCIBIOS,
+				     ":%s end 0x5c = 0x%02x\n", s, v08_5c);
+			}
+#endif
+
+			TOSHIBA_RBTX4927_SETUP_DPRINTK
+			    (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s end\n",
+			     s);
+		}
+
+	}
+
+	register_pci_controller(&tx4927_controller);
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCIBIOS,
+				       "+\n");
+
+	return 0;
+}
+
+arch_initcall(tx4927_pcibios_init);
+
+extern struct resource pci_io_resource;
+extern struct resource pci_mem_resource;
+
+void tx4927_pci_setup(void)
+{
+	static int called = 0;
+	extern unsigned int tx4927_get_mem_size(void);
+
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, "-\n");
+
+	mips_memory_upper = tx4927_get_mem_size() << 20;
+	mips_memory_upper += KSEG0;
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2,
+				       "0x%08lx=mips_memory_upper\n",
+				       mips_memory_upper);
+	mips_pci_io_base = TX4927_PCIIO;
+	mips_pci_io_size = TX4927_PCIIO_SIZE;
+	mips_pci_mem_base = TX4927_PCIMEM;
+	mips_pci_mem_size = TX4927_PCIMEM_SIZE;
+
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2,
+				       "0x%08lx=mips_pci_io_base\n",
+				       mips_pci_io_base);
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2,
+				       "0x%08lx=mips_pci_io_size\n",
+				       mips_pci_io_size);
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2,
+				       "0x%08lx=mips_pci_mem_base\n",
+				       mips_pci_mem_base);
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2,
+				       "0x%08lx=mips_pci_mem_size\n",
+				       mips_pci_mem_size);
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2,
+				       "0x%08lx=pci_io_resource.start\n",
+				       pci_io_resource.start);
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2,
+				       "0x%08lx=pci_io_resource.end\n",
+				       pci_io_resource.end);
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2,
+				       "0x%08lx=pci_mem_resource.start\n",
+				       pci_mem_resource.start);
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2,
+				       "0x%08lx=pci_mem_resource.end\n",
+				       pci_mem_resource.end);
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2,
+				       "0x%08lx=mips_io_port_base",
+				       mips_io_port_base);
+
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2,
+				       "setup pci_io_resource  to 0x%08lx 0x%08lx\n",
+				       pci_io_resource.start,
+				       pci_io_resource.end);
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2,
+				       "setup pci_mem_resource to 0x%08lx 0x%08lx\n",
+				       pci_mem_resource.start,
+				       pci_mem_resource.end);
+
+	if (!called) {
+		printk
+		    ("TX4927 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n",
+		     (unsigned short) (tx4927_pcicptr->pciid >> 16),
+		     (unsigned short) (tx4927_pcicptr->pciid & 0xffff),
+		     (unsigned short) (tx4927_pcicptr->pciccrev & 0xff),
+		     (!(tx4927_ccfgptr->
+			ccfg & TX4927_CCFG_PCIXARB)) ? "External" :
+		     "Internal");
+		called = 1;
+	}
+	printk("%s PCIC --%s PCICLK:",toshiba_name,
+	       (tx4927_ccfgptr->ccfg & TX4927_CCFG_PCI66) ? " PCI66" : "");
+	if (tx4927_ccfgptr->pcfg & TX4927_PCFG_PCICLKEN_ALL) {
+		int pciclk = 0;
+		switch ((unsigned long) tx4927_ccfgptr->
+			ccfg & TX4927_CCFG_PCIDIVMODE_MASK) {
+		case TX4927_CCFG_PCIDIVMODE_2_5:
+			pciclk = tx4927_cpu_clock * 2 / 5;
+			break;
+		case TX4927_CCFG_PCIDIVMODE_3:
+			pciclk = tx4927_cpu_clock / 3;
+			break;
+		case TX4927_CCFG_PCIDIVMODE_5:
+			pciclk = tx4927_cpu_clock / 5;
+			break;
+		case TX4927_CCFG_PCIDIVMODE_6:
+			pciclk = tx4927_cpu_clock / 6;
+			break;
+		}
+		printk("Internal(%dMHz)", pciclk / 1000000);
+	} else {
+		int pciclk = 0;
+		int pciclk_setting = *tx4927_pci_clk_ptr;
+		switch (pciclk_setting & TX4927_PCI_CLK_MASK) {
+		case TX4927_PCI_CLK_33:
+			pciclk = 33333333;
+			break;
+		case TX4927_PCI_CLK_25:
+			pciclk = 25000000;
+			break;
+		case TX4927_PCI_CLK_66:
+			pciclk = 66666666;
+			break;
+		case TX4927_PCI_CLK_50:
+			pciclk = 50000000;
+			break;
+		}
+		printk("External(%dMHz)", pciclk / 1000000);
+	}
+	printk("\n");
+
+
+
+	/* GB->PCI mappings */
+	tx4927_pcicptr->g2piomask = (mips_pci_io_size - 1) >> 4;
+	tx4927_pcicptr->g2piogbase = mips_pci_io_base |
+#ifdef __BIG_ENDIAN
+	    TX4927_PCIC_G2PIOGBASE_ECHG
+#else
+	    TX4927_PCIC_G2PIOGBASE_BSDIS
+#endif
+	    ;
+
+	tx4927_pcicptr->g2piopbase = 0;
+
+	tx4927_pcicptr->g2pmmask[0] = (mips_pci_mem_size - 1) >> 4;
+	tx4927_pcicptr->g2pmgbase[0] = mips_pci_mem_base |
+#ifdef __BIG_ENDIAN
+	    TX4927_PCIC_G2PMnGBASE_ECHG
+#else
+	    TX4927_PCIC_G2PMnGBASE_BSDIS
+#endif
+	    ;
+	tx4927_pcicptr->g2pmpbase[0] = mips_pci_mem_base;
+
+	tx4927_pcicptr->g2pmmask[1] = 0;
+	tx4927_pcicptr->g2pmgbase[1] = 0;
+	tx4927_pcicptr->g2pmpbase[1] = 0;
+	tx4927_pcicptr->g2pmmask[2] = 0;
+	tx4927_pcicptr->g2pmgbase[2] = 0;
+	tx4927_pcicptr->g2pmpbase[2] = 0;
+
+
+	/* PCI->GB mappings (I/O 256B) */
+	tx4927_pcicptr->p2giopbase = 0;	/* 256B */
+
+	/* PCI->GB mappings (MEM 512MB) M0 gets all of memory */
+	tx4927_pcicptr->p2gm0plbase = 0;
+	tx4927_pcicptr->p2gm0pubase = 0;
+	tx4927_pcicptr->p2gmgbase[0] = 0 | TX4927_PCIC_P2GMnGBASE_TMEMEN |
+#ifdef __BIG_ENDIAN
+	    TX4927_PCIC_P2GMnGBASE_TECHG
+#else
+	    TX4927_PCIC_P2GMnGBASE_TBSDIS
+#endif
+	    ;
+
+	/* PCI->GB mappings (MEM 16MB) -not used */
+	tx4927_pcicptr->p2gm1plbase = 0xffffffff;
+#ifdef CONFIG_TX4927BUG_WORKAROUND
+	/*
+	 * TX4927-PCIC-BUG: P2GM1PUBASE must be 0
+	 * if P2GM0PUBASE was 0.
+	 */
+	tx4927_pcicptr->p2gm1pubase = 0;
+#else
+	tx4927_pcicptr->p2gm1pubase = 0xffffffff;
+#endif
+	tx4927_pcicptr->p2gmgbase[1] = 0;
+
+	/* PCI->GB mappings (MEM 1MB) -not used */
+	tx4927_pcicptr->p2gm2pbase = 0xffffffff;
+	tx4927_pcicptr->p2gmgbase[2] = 0;
+
+
+	/* Enable Initiator Memory 0 Space, I/O Space, Config */
+	tx4927_pcicptr->pciccfg &= TX4927_PCIC_PCICCFG_LBWC_MASK;
+	tx4927_pcicptr->pciccfg |=
+	    TX4927_PCIC_PCICCFG_IMSE0 | TX4927_PCIC_PCICCFG_IISE |
+	    TX4927_PCIC_PCICCFG_ICAE | TX4927_PCIC_PCICCFG_ATR;
+
+
+	/* Do not use MEMMUL, MEMINF: YMFPCI card causes M_ABORT. */
+	tx4927_pcicptr->pcicfg1 = 0;
+
+	if (tx4927_pcic_trdyto >= 0) {
+		tx4927_pcicptr->g2ptocnt &= ~0xff;
+		tx4927_pcicptr->g2ptocnt |= (tx4927_pcic_trdyto & 0xff);
+	}
+
+	/* Clear All Local Bus Status */
+	tx4927_pcicptr->pcicstatus = TX4927_PCIC_PCICSTATUS_ALL;
+	/* Enable All Local Bus Interrupts */
+	tx4927_pcicptr->pcicmask = TX4927_PCIC_PCICSTATUS_ALL;
+	/* Clear All Initiator Status */
+	tx4927_pcicptr->g2pstatus = TX4927_PCIC_G2PSTATUS_ALL;
+	/* Enable All Initiator Interrupts */
+	tx4927_pcicptr->g2pmask = TX4927_PCIC_G2PSTATUS_ALL;
+	/* Clear All PCI Status Error */
+	tx4927_pcicptr->pcistatus =
+	    (tx4927_pcicptr->pcistatus & 0x0000ffff) |
+	    (TX4927_PCIC_PCISTATUS_ALL << 16);
+	/* Enable All PCI Status Error Interrupts */
+	tx4927_pcicptr->pcimask = TX4927_PCIC_PCISTATUS_ALL;
+
+	/* PCIC Int => IRC IRQ16 */
+	tx4927_pcicptr->pcicfg2 =
+	    (tx4927_pcicptr->pcicfg2 & 0xffffff00) | TX4927_IR_PCIC;
+
+	if (!(tx4927_ccfgptr->ccfg & TX4927_CCFG_PCIXARB)) {
+		/* XXX */
+	} else {
+		/* Reset Bus Arbiter */
+		tx4927_pcicptr->pbacfg = TX4927_PCIC_PBACFG_RPBA;
+		/* Enable Bus Arbiter */
+		tx4927_pcicptr->pbacfg = TX4927_PCIC_PBACFG_PBAEN;
+	}
+
+	tx4927_pcicptr->pcistatus = PCI_COMMAND_MASTER |
+	    PCI_COMMAND_MEMORY |
+	    PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
+
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2,
+				       ":pci setup complete:\n");
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, "+\n");
+}
+
+#endif /* CONFIG_PCI */
+
+void toshiba_rbtx4927_restart(char *command)
+{
+	printk(KERN_NOTICE "System Rebooting...\n");
+
+	/* enable the s/w reset register */
+	reg_wr08(RBTX4927_SW_RESET_ENABLE, RBTX4927_SW_RESET_ENABLE_SET);
+
+	/* wait for enable to be seen */
+	while ((reg_rd08(RBTX4927_SW_RESET_ENABLE) &
+		RBTX4927_SW_RESET_ENABLE_SET) == 0x00);
+
+	/* do a s/w reset */
+	reg_wr08(RBTX4927_SW_RESET_DO, RBTX4927_SW_RESET_DO_SET);
+
+	/* do something passive while waiting for reset */
+	local_irq_disable();
+	while (1)
+		asm_wait();
+
+	/* no return */
+}
+
+
+void toshiba_rbtx4927_halt(void)
+{
+	printk(KERN_NOTICE "System Halted\n");
+	local_irq_disable();
+	while (1) {
+		asm_wait();
+	}
+	/* no return */
+}
+
+void toshiba_rbtx4927_power_off(void)
+{
+	toshiba_rbtx4927_halt();
+	/* no return */
+}
+
+void __init toshiba_rbtx4927_setup(void)
+{
+	vu32 cp0_config;
+	char *argptr;
+
+	printk("CPU is %s\n", toshiba_name);
+
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP,
+				       "-\n");
+
+	/* f/w leaves this on at startup */
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP,
+				       ":Clearing STO_ERL.\n");
+	clear_c0_status(ST0_ERL);
+
+	/* enable caches -- HCP5 does this, pmon does not */
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP,
+				       ":Enabling TX49_CONF_IC,TX49_CONF_DC.\n");
+	cp0_config = read_c0_config();
+	cp0_config = cp0_config & ~(TX49_CONF_IC | TX49_CONF_DC);
+	write_c0_config(cp0_config);
+
+#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG
+	{
+		extern void dump_cp0(char *);
+		dump_cp0("toshiba_rbtx4927_early_fw_fixup");
+	}
+#endif
+
+	/* setup irq stuff */
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP,
+				       ":Setting up tx4927 pic.\n");
+	TX4927_WR(0xff1ff604, 0x00000400);	/* irq trigger */
+	TX4927_WR(0xff1ff608, 0x00000000);	/* irq trigger */
+
+	/* setup serial stuff */
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP,
+				       ":Setting up tx4927 sio.\n");
+	TX4927_WR(0xff1ff314, 0x00000000);	/* h/w flow control off */
+	TX4927_WR(0xff1ff414, 0x00000000);	/* h/w flow control off */
+
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP,
+				       "+\n");
+
+	set_io_port_base(KSEG1 + TBTX4927_ISA_IO_OFFSET);
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP,
+				       ":mips_io_port_base=0x%08lx\n",
+				       mips_io_port_base);
+
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP,
+				       ":Resource\n");
+	ioport_resource.end = 0xffffffff;
+	iomem_resource.end = 0xffffffff;
+
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP,
+				       ":ResetRoutines\n");
+	_machine_restart = toshiba_rbtx4927_restart;
+	_machine_halt = toshiba_rbtx4927_halt;
+	_machine_power_off = toshiba_rbtx4927_power_off;
+
+#ifdef CONFIG_PCI
+
+	/* PCIC */
+	/*
+	   * ASSUMPTION: PCIDIVMODE is configured for PCI 33MHz or 66MHz.
+	   * PCIDIVMODE[12:11]'s initial value are given by S9[4:3] (ON:0, OFF:1).
+	   * CPU 166MHz: PCI 66MHz : PCIDIVMODE: 00 (1/2.5)
+	   * CPU 200MHz: PCI 66MHz : PCIDIVMODE: 01 (1/3)
+	   * CPU 166MHz: PCI 33MHz : PCIDIVMODE: 10 (1/5)
+	   * CPU 200MHz: PCI 33MHz : PCIDIVMODE: 11 (1/6)
+	   * i.e. S9[3]: ON (83MHz), OFF (100MHz)
+	 */
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1,
+				       "ccfg is %lx, DIV is %x\n",
+				       (unsigned long) tx4927_ccfgptr->
+				       ccfg, TX4927_CCFG_PCIDIVMODE_MASK);
+
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1,
+				       "PCI66 mode is %lx, PCI mode is %lx, pci arb is %lx\n",
+				       (unsigned long) tx4927_ccfgptr->
+				       ccfg & TX4927_CCFG_PCI66,
+				       (unsigned long) tx4927_ccfgptr->
+				       ccfg & TX4927_CCFG_PCIMIDE,
+				       (unsigned long) tx4927_ccfgptr->
+				       ccfg & TX4927_CCFG_PCIXARB);
+
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1,
+				       "PCIDIVMODE is %lx\n",
+				       (unsigned long) tx4927_ccfgptr->
+				       ccfg & TX4927_CCFG_PCIDIVMODE_MASK);
+
+	switch ((unsigned long) tx4927_ccfgptr->
+		ccfg & TX4927_CCFG_PCIDIVMODE_MASK) {
+	case TX4927_CCFG_PCIDIVMODE_2_5:
+	case TX4927_CCFG_PCIDIVMODE_5:
+		tx4927_cpu_clock = 166000000;	/* 166MHz */
+		break;
+	default:
+		tx4927_cpu_clock = 200000000;	/* 200MHz */
+	}
+
+	/* CCFG */
+	/* enable Timeout BusError */
+	if (tx4927_ccfg_toeon)
+		tx4927_ccfgptr->ccfg |= TX4927_CCFG_TOE;
+
+	/* SDRAMC fixup */
+#ifdef CONFIG_TX4927BUG_WORKAROUND
+	/*
+	 * TX4927-BUG: INF 01-01-18/ BUG 01-01-22
+	 * G-bus timeout error detection is incorrect
+	 */
+	if (tx4927_ccfg_toeon)
+		tx4927_sdramcptr->tr |= 0x02000000;	/* RCD:3tck */
+#endif
+
+	tx4927_pci_setup();
+	if (tx4927_using_backplane == 1)
+		printk("backplane board IS installed\n");
+	else
+		printk("No Backplane \n");
+
+	/* this is on ISA bus behind PCI bus, so need PCI up first */
+#ifdef CONFIG_TOSHIBA_FPCIB0
+	{
+		if (tx4927_using_backplane) {
+			TOSHIBA_RBTX4927_SETUP_DPRINTK
+			    (TOSHIBA_RBTX4927_SETUP_SETUP,
+			     ":fpcibo=yes\n");
+
+			TOSHIBA_RBTX4927_SETUP_DPRINTK
+			    (TOSHIBA_RBTX4927_SETUP_SETUP,
+			     ":smsc_fdc37m81x_init()\n");
+			smsc_fdc37m81x_init(0x3f0);
+
+			TOSHIBA_RBTX4927_SETUP_DPRINTK
+			    (TOSHIBA_RBTX4927_SETUP_SETUP,
+			     ":smsc_fdc37m81x_config_beg()\n");
+			smsc_fdc37m81x_config_beg();
+
+			TOSHIBA_RBTX4927_SETUP_DPRINTK
+			    (TOSHIBA_RBTX4927_SETUP_SETUP,
+			     ":smsc_fdc37m81x_config_set(KBD)\n");
+			smsc_fdc37m81x_config_set(SMSC_FDC37M81X_DNUM,
+						  SMSC_FDC37M81X_KBD);
+			smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT, 1);
+			smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT2, 12);
+			smsc_fdc37m81x_config_set(SMSC_FDC37M81X_ACTIVE,
+						  1);
+
+			smsc_fdc37m81x_config_end();
+			TOSHIBA_RBTX4927_SETUP_DPRINTK
+			    (TOSHIBA_RBTX4927_SETUP_SETUP,
+			     ":smsc_fdc37m81x_config_end()\n");
+		} else {
+			TOSHIBA_RBTX4927_SETUP_DPRINTK
+			    (TOSHIBA_RBTX4927_SETUP_SETUP,
+			     ":fpcibo=not_found\n");
+		}
+	}
+#else
+	{
+		TOSHIBA_RBTX4927_SETUP_DPRINTK
+		    (TOSHIBA_RBTX4927_SETUP_SETUP, ":fpcibo=no\n");
+	}
+#endif
+
+#endif /* CONFIG_PCI */
+
+#ifdef CONFIG_SERIAL_TXX9_CONSOLE
+        argptr = prom_getcmdline();
+        if (strstr(argptr, "console=") == NULL) {
+                strcat(argptr, " console=ttyS0,38400");
+        }
+#endif
+
+#ifdef CONFIG_ROOT_NFS
+        argptr = prom_getcmdline();
+        if (strstr(argptr, "root=") == NULL) {
+                strcat(argptr, " root=/dev/nfs rw");
+        }
+#endif
+
+
+#ifdef CONFIG_IP_PNP
+        argptr = prom_getcmdline();
+        if (strstr(argptr, "ip=") == NULL) {
+                strcat(argptr, " ip=any");
+        }
+#endif
+
+
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP,
+			       "+\n");
+}
+
+#ifdef CONFIG_RTC_DS1742
+extern unsigned long rtc_ds1742_get_time(void);
+extern int rtc_ds1742_set_time(unsigned long);
+extern void rtc_ds1742_wait(void);
+#endif
+
+void __init
+toshiba_rbtx4927_time_init(void)
+{
+	u32 c1;
+	u32 c2;
+
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, "-\n");
+
+#ifdef CONFIG_RTC_DS1742
+
+	rtc_get_time = rtc_ds1742_get_time;
+	rtc_set_time = rtc_ds1742_set_time;
+
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT,
+				       ":rtc_ds1742_init()-\n");
+	rtc_ds1742_init(0xbc010000);
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT,
+				       ":rtc_ds1742_init()+\n");
+
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT,
+				       ":Calibrate mips_hpt_frequency-\n");
+	rtc_ds1742_wait();
+
+	/* get the count */
+	c1 = read_c0_count();
+
+	/* wait for the seconds to change again */
+	rtc_ds1742_wait();
+
+	/* get the count again */
+	c2 = read_c0_count();
+
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT,
+				       ":Calibrate mips_hpt_frequency+\n");
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT,
+				       ":c1=%12u\n", c1);
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT,
+				       ":c2=%12u\n", c2);
+
+	/* this diff is as close as we are going to get to counter ticks per sec */
+	mips_hpt_frequency = abs(c2 - c1);
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT,
+				       ":f1=%12u\n", mips_hpt_frequency);
+
+	/* round to 1/10th of a MHz */
+	mips_hpt_frequency /= (100 * 1000);
+	mips_hpt_frequency *= (100 * 1000);
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT,
+				       ":f2=%12u\n", mips_hpt_frequency);
+
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_INFO,
+				       ":mips_hpt_frequency=%uHz (%uMHz)\n",
+				       mips_hpt_frequency,
+				       mips_hpt_frequency / 1000000);
+#else
+	mips_hpt_frequency = 100000000;
+#endif
+
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, "+\n");
+
+}
+
+void __init toshiba_rbtx4927_timer_setup(struct irqaction *irq)
+{
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIMER_SETUP,
+				       "-\n");
+	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIMER_SETUP,
+				       "+\n");
+}
diff --git a/arch/mips/vr4181/common/Makefile b/arch/mips/vr4181/common/Makefile
new file mode 100644
index 0000000..f7587ca
--- /dev/null
+++ b/arch/mips/vr4181/common/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for common code of NEC vr4181 based boards
+#
+
+obj-y	 := irq.o int_handler.o serial.o time.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/vr4181/common/int_handler.S b/arch/mips/vr4181/common/int_handler.S
new file mode 100644
index 0000000..2c041b8
--- /dev/null
+++ b/arch/mips/vr4181/common/int_handler.S
@@ -0,0 +1,206 @@
+/*
+ * arch/mips/vr4181/common/int_handler.S
+ *
+ * Adapted to the VR4181 and almost entirely rewritten:
+ * Copyright (C) 1999 Bradley D. LaRonde and Michael Klar
+ *
+ * Clean up to conform to the new IRQ
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+
+#include <asm/vr4181/vr4181.h>
+
+/*
+ * [jsun]
+ * See include/asm/vr4181/irq.h for IRQ assignment and strategy.
+ */
+
+	.text
+	.set	noreorder
+
+	.align	5
+	NESTED(vr4181_handle_irq, PT_SIZE, ra)
+
+	.set	noat
+	SAVE_ALL
+	CLI
+
+	.set	at
+	.set	noreorder
+
+	mfc0	t0, CP0_CAUSE
+	mfc0	t2, CP0_STATUS
+
+	and	t0, t2
+
+	/* we check IP3 first; it happens most frequently */
+	andi	t1, t0, STATUSF_IP3
+	bnez	t1, ll_cpu_ip3
+	andi	t1, t0, STATUSF_IP2
+	bnez	t1, ll_cpu_ip2
+	andi	t1, t0, STATUSF_IP7	/* cpu timer */
+	bnez	t1, ll_cputimer_irq
+	andi	t1, t0, STATUSF_IP4
+	bnez	t1, ll_cpu_ip4
+	andi	t1, t0, STATUSF_IP5
+	bnez	t1, ll_cpu_ip5
+	andi	t1, t0, STATUSF_IP6
+	bnez	t1, ll_cpu_ip6
+	andi	t1, t0, STATUSF_IP0	/* software int 0 */
+	bnez	t1, ll_cpu_ip0
+	andi	t1, t0, STATUSF_IP1	/* software int 1 */
+	bnez	t1, ll_cpu_ip1
+	nop
+
+	.set	reorder
+do_spurious:
+	j	spurious_interrupt
+
+/*
+ * regular CPU irqs
+ */
+ll_cputimer_irq:
+	li	a0, VR4181_IRQ_TIMER
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+
+ll_cpu_ip0:
+	li	a0, VR4181_IRQ_SW1
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+ll_cpu_ip1:
+	li	a0, VR4181_IRQ_SW2
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+ll_cpu_ip3:
+	li	a0, VR4181_IRQ_INT1
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+ll_cpu_ip4:
+	li	a0, VR4181_IRQ_INT2
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+ll_cpu_ip5:
+	li	a0, VR4181_IRQ_INT3
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+ll_cpu_ip6:
+	li	a0, VR4181_IRQ_INT4
+	move	a1, sp
+	jal	do_IRQ
+	j	ret_from_irq
+
+/*
+ *  One of the sys irq has happend.
+ *
+ *  In the interest of speed, we first determine in the following order
+ *  which 16-irq block have pending interrupts:
+ *	sysint1 (16 sources, including cascading intrs from GPIO)
+ *	sysint2
+ *	gpio (16 intr sources)
+ *
+ *  Then we do binary search to find the exact interrupt source.
+ */
+ll_cpu_ip2:
+
+	lui	t3,%hi(VR4181_SYSINT1REG)
+	lhu	t0,%lo(VR4181_SYSINT1REG)(t3)
+	lhu	t2,%lo(VR4181_MSYSINT1REG)(t3)
+	and	t0, 0xfffb		/* hack - remove RTC Long 1 intr */
+	and	t0, t2
+	beqz	t0, check_sysint2
+
+	/* check for GPIO interrupts */
+	andi	t1, t0, 0x0100
+	bnez	t1, check_gpio_int
+
+	/* so we have an interrupt in sysint1 which is not gpio int */
+	li	a0, VR4181_SYS_IRQ_BASE - 1
+	j	check_16
+
+check_sysint2:
+
+	lhu	t0,%lo(VR4181_SYSINT2REG)(t3)
+	lhu	t2,%lo(VR4181_MSYSINT2REG)(t3)
+	and	t0, 0xfffe		/* hack - remove RTC Long 2 intr */
+	and	t0, t2
+	li	a0, VR4181_SYS_IRQ_BASE + 16 - 1
+	j	check_16
+
+check_gpio_int:
+	lui	t3,%hi(VR4181_GPINTMSK)
+	lhu	t0,%lo(VR4181_GPINTMSK)(t3)
+	lhu	t2,%lo(VR4181_GPINTSTAT)(t3)
+	xori	t0, 0xffff			/* why? reverse logic? */
+	and	t0, t2
+	li	a0, VR4181_GPIO_IRQ_BASE - 1
+	j	check_16
+
+/*
+ *  When we reach check_16, we have 16-bit status in t0 and base irq number
+ *  in a0.
+ */
+check_16:
+	andi	t1, t0, 0xff
+	bnez	t1, check_8
+
+	srl	t0, 8
+	addi	a0, 8
+	j	check_8
+
+/*
+ *  When we reach check_8, we have 8-bit status in t0 and base irq number
+ *  in a0.
+ */
+check_8:
+	andi	t1, t0, 0xf
+	bnez	t1, check_4
+
+	srl	t0, 4
+	addi	a0, 4
+	j	check_4
+
+/*
+ *  When we reach check_4, we have 4-bit status in t0 and base irq number
+ *  in a0.
+ */
+check_4:
+	andi	t0, t0, 0xf
+	beqz	t0, do_spurious
+
+loop:
+	andi	t2, t0, 0x1
+	srl	t0, 1
+	addi	a0, 1
+	beqz	t2, loop
+
+found_it:
+	move	a1, sp
+	jal	do_IRQ
+
+	j	ret_from_irq
+
+	END(vr4181_handle_irq)
diff --git a/arch/mips/vr4181/common/irq.c b/arch/mips/vr4181/common/irq.c
new file mode 100644
index 0000000..2cdf77c
--- /dev/null
+++ b/arch/mips/vr4181/common/irq.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
+ *
+ * linux/arch/mips/vr4181/common/irq.c
+ *	Completely re-written to use the new irq.c
+ *
+ * Credits to Bradley D. LaRonde and Michael Klar for writing the original
+ * irq.c file which was derived from the common irq.c file.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/gdb-stub.h>
+
+#include <asm/vr4181/vr4181.h>
+
+/*
+ * Strategy:
+ *
+ * We essentially have three irq controllers, CPU, system, and gpio.
+ *
+ * CPU irq controller is taken care by arch/mips/kernel/irq_cpu.c and
+ * CONFIG_IRQ_CPU config option.
+ *
+ * We here provide sys_irq and gpio_irq controller code.
+ */
+
+static int sys_irq_base;
+static int gpio_irq_base;
+
+/* ---------------------- sys irq ------------------------ */
+static void
+sys_irq_enable(unsigned int irq)
+{
+	irq -= sys_irq_base;
+	if (irq < 16) {
+		*VR4181_MSYSINT1REG |= (u16)(1 << irq);
+	} else {
+		irq -= 16;
+		*VR4181_MSYSINT2REG |= (u16)(1 << irq);
+	}
+}
+
+static void
+sys_irq_disable(unsigned int irq)
+{
+	irq -= sys_irq_base;
+	if (irq < 16) {
+		*VR4181_MSYSINT1REG &= ~((u16)(1 << irq));
+	} else {
+		irq -= 16;
+		*VR4181_MSYSINT2REG &= ~((u16)(1 << irq));
+	}
+
+}
+
+static unsigned int
+sys_irq_startup(unsigned int irq)
+{
+	sys_irq_enable(irq);
+	return 0;
+}
+
+#define sys_irq_shutdown	sys_irq_disable
+#define sys_irq_ack		sys_irq_disable
+
+static void
+sys_irq_end(unsigned int irq)
+{
+	if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		sys_irq_enable(irq);
+}
+
+static hw_irq_controller sys_irq_controller = {
+	"vr4181_sys_irq",
+	sys_irq_startup,
+	sys_irq_shutdown,
+	sys_irq_enable,
+	sys_irq_disable,
+	sys_irq_ack,
+	sys_irq_end,
+	NULL			/* no affinity stuff for UP */
+};
+
+/* ---------------------- gpio irq ------------------------ */
+/* gpio irq lines use reverse logic */
+static void
+gpio_irq_enable(unsigned int irq)
+{
+	irq -= gpio_irq_base;
+	*VR4181_GPINTMSK &= ~((u16)(1 << irq));
+}
+
+static void
+gpio_irq_disable(unsigned int irq)
+{
+	irq -= gpio_irq_base;
+	*VR4181_GPINTMSK |= (u16)(1 << irq);
+}
+
+static unsigned int
+gpio_irq_startup(unsigned int irq)
+{
+	gpio_irq_enable(irq);
+
+	irq -= gpio_irq_base;
+	*VR4181_GPINTEN |= (u16)(1 << irq );
+
+	return 0;
+}
+
+static void
+gpio_irq_shutdown(unsigned int irq)
+{
+	gpio_irq_disable(irq);
+
+	irq -= gpio_irq_base;
+	*VR4181_GPINTEN &= ~((u16)(1 << irq ));
+}
+
+static void
+gpio_irq_ack(unsigned int irq)
+{
+	u16 irqtype;
+	u16 irqshift;
+
+	gpio_irq_disable(irq);
+
+	/* we clear interrupt if it is edge triggered */
+	irq -= gpio_irq_base;
+	if (irq < 8) {
+		irqtype = *VR4181_GPINTTYPL;
+		irqshift = 2 << (irq*2);
+	} else {
+		irqtype = *VR4181_GPINTTYPH;
+		irqshift = 2 << ((irq-8)*2);
+	}
+	if ( ! (irqtype & irqshift) ) {
+		*VR4181_GPINTSTAT = (u16) (1 << irq);
+	}
+}
+
+static void
+gpio_irq_end(unsigned int irq)
+{
+	if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		gpio_irq_enable(irq);
+}
+
+static hw_irq_controller gpio_irq_controller = {
+	"vr4181_gpio_irq",
+	gpio_irq_startup,
+	gpio_irq_shutdown,
+	gpio_irq_enable,
+	gpio_irq_disable,
+	gpio_irq_ack,
+	gpio_irq_end,
+	NULL			/* no affinity stuff for UP */
+};
+
+/* ---------------------  IRQ init stuff ---------------------- */
+
+extern asmlinkage void vr4181_handle_irq(void);
+extern void breakpoint(void);
+extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
+extern void mips_cpu_irq_init(u32 irq_base);
+
+static struct irqaction cascade =
+	{ no_action, SA_INTERRUPT, CPU_MASK_NONE, "cascade", NULL, NULL };
+static struct irqaction reserved =
+	{ no_action, SA_INTERRUPT, CPU_MASK_NONE, "cascade", NULL, NULL };
+
+void __init arch_init_irq(void)
+{
+	int i;
+
+	set_except_vector(0, vr4181_handle_irq);
+
+	/* init CPU irqs */
+	mips_cpu_irq_init(VR4181_CPU_IRQ_BASE);
+
+	/* init sys irqs */
+	sys_irq_base = VR4181_SYS_IRQ_BASE;
+	for (i=sys_irq_base; i < sys_irq_base + VR4181_NUM_SYS_IRQ; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &sys_irq_controller;
+	}
+
+	/* init gpio irqs */
+	gpio_irq_base = VR4181_GPIO_IRQ_BASE;
+	for (i=gpio_irq_base; i < gpio_irq_base + VR4181_NUM_GPIO_IRQ; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &gpio_irq_controller;
+	}
+
+	/* Default all ICU IRQs to off ... */
+	*VR4181_MSYSINT1REG = 0;
+	*VR4181_MSYSINT2REG = 0;
+
+	/* We initialize the level 2 ICU registers to all bits disabled. */
+	*VR4181_MPIUINTREG = 0;
+	*VR4181_MAIUINTREG = 0;
+	*VR4181_MKIUINTREG = 0;
+
+	/* disable all GPIO intrs */
+	*VR4181_GPINTMSK = 0xffff;
+
+	/* vector handler.  What these do is register the IRQ as non-sharable */
+	setup_irq(VR4181_IRQ_INT0, &cascade);
+	setup_irq(VR4181_IRQ_GIU, &cascade);
+
+	/*
+	 * RTC interrupts are interesting.  They have two destinations.
+	 * One is at sys irq controller, and the other is at CPU IP3 and IP4.
+	 * RTC timer is used as system timer.
+	 * We enable them here, but timer routine will register later
+	 * with CPU IP3/IP4.
+	 */
+	setup_irq(VR4181_IRQ_RTCL1, &reserved);
+	setup_irq(VR4181_IRQ_RTCL2, &reserved);
+}
diff --git a/arch/mips/vr4181/common/serial.c b/arch/mips/vr4181/common/serial.c
new file mode 100644
index 0000000..3f62c62
--- /dev/null
+++ b/arch/mips/vr4181/common/serial.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/vr4181/common/serial.c
+ *     initialize serial port on vr4181.
+ *
+ * This program is free software; you can redistribute	it and/or modify it
+ * under  the terms of	the GNU General	 Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+/*
+ * [jsun, 010925]
+ * You need to make sure rs_table has at least one element in
+ * drivers/char/serial.c file.	There is no good way to do it right
+ * now.	 A workaround is to include CONFIG_SERIAL_MANY_PORTS in your
+ * configure file, which would gives you 64 ports and wastes 11K ram.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/serial.h>
+
+#include <asm/vr4181/vr4181.h>
+
+void __init vr4181_init_serial(void)
+{
+	struct serial_struct s;
+
+	/* turn on UART clock */
+	*VR4181_CMUCLKMSK |= VR4181_CMUCLKMSK_MSKSIU;
+
+	/* clear memory */
+	memset(&s, 0, sizeof(s));
+
+	s.line = 0;			/* we set the first one */
+	s.baud_base = 1152000;
+	s.irq = VR4181_IRQ_SIU;
+	s.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; /* STD_COM_FLAGS */
+	s.iomem_base = (u8*)VR4181_SIURB;
+	s.iomem_reg_shift = 0;
+	s.io_type = SERIAL_IO_MEM;
+	if (early_serial_setup(&s) != 0) {
+		panic("vr4181_init_serial() failed!");
+	}
+}
+
diff --git a/arch/mips/vr4181/common/time.c b/arch/mips/vr4181/common/time.c
new file mode 100644
index 0000000..1781407
--- /dev/null
+++ b/arch/mips/vr4181/common/time.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * rtc and time ops for vr4181.	 Part of code is drived from
+ * linux-vr, originally written	 by Bradley D. LaRonde & Michael Klar.
+ *
+ * This program is free software; you can redistribute	it and/or modify it
+ * under  the terms of	the GNU General	 Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/param.h>			/* for HZ */
+#include <linux/time.h>
+#include <linux/interrupt.h>
+
+#include <asm/system.h>
+#include <asm/time.h>
+
+#include <asm/vr4181/vr4181.h>
+
+#define COUNTS_PER_JIFFY ((32768 + HZ/2) / HZ)
+
+/*
+ * RTC ops
+ */
+
+DEFINE_SPINLOCK(rtc_lock);
+
+/* per VR41xx docs, bad data can be read if between 2 counts */
+static inline unsigned short
+read_time_reg(volatile unsigned short *reg)
+{
+	unsigned short value;
+	do {
+		value = *reg;
+		barrier();
+	} while (value != *reg);
+	return value;
+}
+
+static unsigned long
+vr4181_rtc_get_time(void)
+{
+	unsigned short regh, regm, regl;
+
+	// why this crazy order, you ask?  to guarantee that neither m
+	// nor l wrap before all 3 read
+	do {
+		regm = read_time_reg(VR4181_ETIMEMREG);
+		barrier();
+		regh = read_time_reg(VR4181_ETIMEHREG);
+		barrier();
+		regl = read_time_reg(VR4181_ETIMELREG);
+	} while (regm != read_time_reg(VR4181_ETIMEMREG));
+	return ((regh << 17) | (regm << 1) | (regl >> 15));
+}
+
+static int
+vr4181_rtc_set_time(unsigned long timeval)
+{
+	unsigned short intreg;
+	unsigned long flags;
+
+	spin_lock_irqsave(&rtc_lock, flags);
+	intreg = *VR4181_RTCINTREG & 0x05;
+	barrier();
+	*VR4181_ETIMELREG = timeval << 15;
+	*VR4181_ETIMEMREG = timeval >> 1;
+	*VR4181_ETIMEHREG = timeval >> 17;
+	barrier();
+	// assume that any ints that just triggered are invalid, since the
+	// time value is written non-atomically in 3 separate regs
+	*VR4181_RTCINTREG = 0x05 ^ intreg;
+	spin_unlock_irqrestore(&rtc_lock, flags);
+
+	return 0;
+}
+
+
+/*
+ * timer interrupt routine (wrapper)
+ *
+ * we need our own interrupt routine because we need to clear
+ * RTC1 interrupt.
+ */
+static void
+vr4181_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	/* Clear the interrupt. */
+	*VR4181_RTCINTREG = 0x2;
+
+	/* call the generic one */
+	timer_interrupt(irq, dev_id, regs);
+}
+
+
+/*
+ * vr4181_time_init:
+ *
+ * We pick the following choices:
+ *   . we use elapsed timer as the RTC.	 We set some reasonable init data since
+ *     it does not persist across reset
+ *   . we use RTC1 as the system timer interrupt source.
+ *   . we use CPU counter for fast_gettimeoffset and we calivrate the cpu
+ *     frequency.  In other words, we use calibrate_div64_gettimeoffset().
+ *   . we use our own timer interrupt routine which clears the interrupt
+ *     and then calls the generic high-level timer interrupt routine.
+ *
+ */
+
+extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
+
+static void
+vr4181_timer_setup(struct irqaction *irq)
+{
+	/* over-write the handler to be our own one */
+	irq->handler = vr4181_timer_interrupt;
+
+	/* sets up the frequency */
+	*VR4181_RTCL1LREG = COUNTS_PER_JIFFY;
+	*VR4181_RTCL1HREG = 0;
+
+	/* and ack any pending ints */
+	*VR4181_RTCINTREG = 0x2;
+
+	/* setup irqaction */
+	setup_irq(VR4181_IRQ_INT1, irq);
+
+}
+
+void
+vr4181_init_time(void)
+{
+	/* setup hookup functions */
+	rtc_get_time = vr4181_rtc_get_time;
+	rtc_set_time = vr4181_rtc_set_time;
+
+	board_timer_setup = vr4181_timer_setup;
+}
+
diff --git a/arch/mips/vr4181/osprey/Makefile b/arch/mips/vr4181/osprey/Makefile
new file mode 100644
index 0000000..34be057
--- /dev/null
+++ b/arch/mips/vr4181/osprey/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for common code of NEC Osprey board
+#
+
+obj-y	 := setup.o prom.o reset.o
+
+obj-$(CONFIG_KGDB)	+= dbg_io.o
diff --git a/arch/mips/vr4181/osprey/dbg_io.c b/arch/mips/vr4181/osprey/dbg_io.c
new file mode 100644
index 0000000..5e8a840
--- /dev/null
+++ b/arch/mips/vr4181/osprey/dbg_io.c
@@ -0,0 +1,136 @@
+/*
+ * kgdb io functions for osprey.  We use the serial port on debug board.
+ *
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+/* ======================= CONFIG ======================== */
+
+/* [jsun] we use the second serial port for kdb */
+#define         BASE                    0xb7fffff0
+#define         MAX_BAUD                115200
+
+/* distance in bytes between two serial registers */
+#define         REG_OFFSET              1
+
+/*
+ * 0 - kgdb does serial init
+ * 1 - kgdb skip serial init
+ */
+static int remoteDebugInitialized = 1;
+
+/*
+ * the default baud rate *if* kgdb does serial init
+ */
+#define		BAUD_DEFAULT		UART16550_BAUD_38400
+
+/* ======================= END OF CONFIG ======================== */
+
+typedef unsigned char uint8;
+typedef unsigned int uint32;
+
+#define         UART16550_BAUD_2400             2400
+#define         UART16550_BAUD_4800             4800
+#define         UART16550_BAUD_9600             9600
+#define         UART16550_BAUD_19200            19200
+#define         UART16550_BAUD_38400            38400
+#define         UART16550_BAUD_57600            57600
+#define         UART16550_BAUD_115200           115200
+
+#define         UART16550_PARITY_NONE           0
+#define         UART16550_PARITY_ODD            0x08
+#define         UART16550_PARITY_EVEN           0x18
+#define         UART16550_PARITY_MARK           0x28
+#define         UART16550_PARITY_SPACE          0x38
+
+#define         UART16550_DATA_5BIT             0x0
+#define         UART16550_DATA_6BIT             0x1
+#define         UART16550_DATA_7BIT             0x2
+#define         UART16550_DATA_8BIT             0x3
+
+#define         UART16550_STOP_1BIT             0x0
+#define         UART16550_STOP_2BIT             0x4
+
+/* register offset */
+#define         OFS_RCV_BUFFER          0
+#define         OFS_TRANS_HOLD          0
+#define         OFS_SEND_BUFFER         0
+#define         OFS_INTR_ENABLE         (1*REG_OFFSET)
+#define         OFS_INTR_ID             (2*REG_OFFSET)
+#define         OFS_DATA_FORMAT         (3*REG_OFFSET)
+#define         OFS_LINE_CONTROL        (3*REG_OFFSET)
+#define         OFS_MODEM_CONTROL       (4*REG_OFFSET)
+#define         OFS_RS232_OUTPUT        (4*REG_OFFSET)
+#define         OFS_LINE_STATUS         (5*REG_OFFSET)
+#define         OFS_MODEM_STATUS        (6*REG_OFFSET)
+#define         OFS_RS232_INPUT         (6*REG_OFFSET)
+#define         OFS_SCRATCH_PAD         (7*REG_OFFSET)
+
+#define         OFS_DIVISOR_LSB         (0*REG_OFFSET)
+#define         OFS_DIVISOR_MSB         (1*REG_OFFSET)
+
+
+/* memory-mapped read/write of the port */
+#define         UART16550_READ(y)    (*((volatile uint8*)(BASE + y)))
+#define         UART16550_WRITE(y, z)  ((*((volatile uint8*)(BASE + y))) = z)
+
+void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
+{
+        /* disable interrupts */
+        UART16550_WRITE(OFS_INTR_ENABLE, 0);
+
+        /* set up buad rate */
+        {
+                uint32 divisor;
+
+                /* set DIAB bit */
+                UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
+
+                /* set divisor */
+                divisor = MAX_BAUD / baud;
+                UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
+                UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
+
+                /* clear DIAB bit */
+                UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
+        }
+
+        /* set data format */
+        UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
+}
+
+
+uint8 getDebugChar(void)
+{
+        if (!remoteDebugInitialized) {
+                remoteDebugInitialized = 1;
+                debugInit(BAUD_DEFAULT,
+                          UART16550_DATA_8BIT,
+                          UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+        }
+
+        while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
+        return UART16550_READ(OFS_RCV_BUFFER);
+}
+
+
+int putDebugChar(uint8 byte)
+{
+        if (!remoteDebugInitialized) {
+                remoteDebugInitialized = 1;
+                debugInit(BAUD_DEFAULT,
+                          UART16550_DATA_8BIT,
+                          UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+        }
+
+        while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
+        UART16550_WRITE(OFS_SEND_BUFFER, byte);
+        return 1;
+}
diff --git a/arch/mips/vr4181/osprey/prom.c b/arch/mips/vr4181/osprey/prom.c
new file mode 100644
index 0000000..af0d145
--- /dev/null
+++ b/arch/mips/vr4181/osprey/prom.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/vr4181/osprey/prom.c
+ *     prom code for osprey.
+ *
+ * This program is free software; you can redistribute	it and/or modify it
+ * under  the terms of	the GNU General	 Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <asm/bootinfo.h>
+#include <asm/addrspace.h>
+
+const char *get_system_type(void)
+{
+	return "NEC_Vr41xx Osprey";
+}
+
+/*
+ * [jsun] right now we assume it is the nec debug monitor, which does
+ * not pass any arguments.
+ */
+void __init prom_init(void)
+{
+	// cmdline is now set in default config
+	// strcpy(arcs_cmdline, "ip=bootp ");
+	// strcat(arcs_cmdline, "ether=46,0x03fe0300,eth0 ");
+	// strcpy(arcs_cmdline, "ether=0,0x0300,eth0 "
+	// strcat(arcs_cmdline, "video=vr4181fb:xres:240,yres:320,bpp:8 ");
+
+	mips_machgroup = MACH_GROUP_NEC_VR41XX;
+	mips_machtype = MACH_NEC_OSPREY;
+
+	/* 16MB fixed */
+	add_memory_region(0, 16 << 20, BOOT_MEM_RAM);
+}
+
+unsigned long __init prom_free_prom_memory(void)
+{
+	return 0;
+}
diff --git a/arch/mips/vr4181/osprey/reset.c b/arch/mips/vr4181/osprey/reset.c
new file mode 100644
index 0000000..036ae83
--- /dev/null
+++ b/arch/mips/vr4181/osprey/reset.c
@@ -0,0 +1,40 @@
+/*
+ * This program is free software; you can redistribute	it and/or modify it
+ * under  the terms of	the GNU General	 Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Copyright (C) 1997, 2001 Ralf Baechle
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/cacheflush.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+
+void nec_osprey_restart(char *command)
+{
+	set_c0_status(ST0_ERL);
+	change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+	flush_cache_all();
+	write_c0_wired(0);
+	__asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
+}
+
+void nec_osprey_halt(void)
+{
+	printk(KERN_NOTICE "\n** You can safely turn off the power\n");
+	while (1)
+		__asm__(".set\tmips3\n\t"
+			"wait\n\t"
+			".set\tmips0");
+}
+
+void nec_osprey_power_off(void)
+{
+	nec_osprey_halt();
+}
diff --git a/arch/mips/vr4181/osprey/setup.c b/arch/mips/vr4181/osprey/setup.c
new file mode 100644
index 0000000..2ff7140
--- /dev/null
+++ b/arch/mips/vr4181/osprey/setup.c
@@ -0,0 +1,68 @@
+/*
+ * linux/arch/mips/vr4181/setup.c
+ *
+ * VR41xx setup routines
+ *
+ * Copyright (C) 1999 Bradley D. LaRonde
+ * Copyright (C) 1999, 2000 Michael Klar
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+
+#include <linux/ide.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <asm/reboot.h>
+#include <asm/vr4181/vr4181.h>
+#include <asm/io.h>
+
+
+extern void nec_osprey_restart(char* c);
+extern void nec_osprey_halt(void);
+extern void nec_osprey_power_off(void);
+
+extern void vr4181_init_serial(void);
+extern void vr4181_init_time(void);
+
+static void __init nec_osprey_setup(void)
+{
+	set_io_port_base(VR4181_PORT_BASE);
+	isa_slot_offset = VR4181_ISAMEM_BASE;
+
+	vr4181_init_serial();
+	vr4181_init_time();
+
+	_machine_restart = nec_osprey_restart;
+	_machine_halt = nec_osprey_halt;
+	_machine_power_off = nec_osprey_power_off;
+
+	/* setup resource limit */
+	ioport_resource.end = 0xffffffff;
+	iomem_resource.end = 0xffffffff;
+
+	/* [jsun] hack */
+	/*
+	printk("[jsun] hack to change external ISA control register, %x -> %x\n",
+		(*VR4181_XISACTL),
+		(*VR4181_XISACTL) | 0x2);
+	*VR4181_XISACTL |= 0x2;
+	*/
+
+	// *VR4181_GPHIBSTH = 0x2000;
+	// *VR4181_GPMD0REG = 0x00c0;
+	// *VR4181_GPINTEN	 = 1<<6;
+
+	/* [jsun] I believe this will get the interrupt type right
+	 * for the ether port.
+	 */
+	*VR4181_GPINTTYPL = 0x3000;
+}
+
+early_initcall(nec_osprey_setup);
diff --git a/arch/mips/vr41xx/casio-e55/Makefile b/arch/mips/vr41xx/casio-e55/Makefile
new file mode 100644
index 0000000..d4c03cc
--- /dev/null
+++ b/arch/mips/vr41xx/casio-e55/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the CASIO CASSIOPEIA E-55/65 specific parts of the kernel
+#
+
+obj-y			+= setup.o
diff --git a/arch/mips/vr41xx/casio-e55/setup.c b/arch/mips/vr41xx/casio-e55/setup.c
new file mode 100644
index 0000000..aa8605a
--- /dev/null
+++ b/arch/mips/vr41xx/casio-e55/setup.c
@@ -0,0 +1,40 @@
+/*
+ *  setup.c, Setup for the CASIO CASSIOPEIA E-11/15/55/65.
+ *
+ *  Copyright (C) 2002-2005  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/init.h>
+#include <linux/ioport.h>
+
+#include <asm/io.h>
+#include <asm/vr41xx/e55.h>
+
+const char *get_system_type(void)
+{
+	return "CASIO CASSIOPEIA E-11/15/55/65";
+}
+
+static int __init casio_e55_setup(void)
+{
+	set_io_port_base(IO_PORT_BASE);
+	ioport_resource.start = IO_PORT_RESOURCE_START;
+	ioport_resource.end = IO_PORT_RESOURCE_END;
+
+	return 0;
+}
+
+arch_initcall(casio_e55_setup);
diff --git a/arch/mips/vr41xx/common/Makefile b/arch/mips/vr41xx/common/Makefile
new file mode 100644
index 0000000..92c11e9
--- /dev/null
+++ b/arch/mips/vr41xx/common/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for common code of the NEC VR4100 series.
+#
+
+obj-y				+= bcu.o cmu.o giu.o icu.o init.o int-handler.o pmu.o
+obj-$(CONFIG_VRC4173)		+= vrc4173.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/vr41xx/common/bcu.c b/arch/mips/vr41xx/common/bcu.c
new file mode 100644
index 0000000..cdfa427
--- /dev/null
+++ b/arch/mips/vr41xx/common/bcu.c
@@ -0,0 +1,222 @@
+/*
+ *  bcu.c, Bus Control Unit routines for the NEC VR4100 series.
+ *
+ *  Copyright (C) 2002  MontaVista Software Inc.
+ *    Author: Yoichi Yuasa <yyuasa@mvista.com, or source@mvista.com>
+ *  Copyright (C) 2003-2005  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC VR4122 and VR4131 are supported.
+ *  - Added support for NEC VR4111 and VR4121.
+ *
+ *  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *  - Added support for NEC VR4133.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/smp.h>
+#include <linux/types.h>
+
+#include <asm/cpu.h>
+#include <asm/io.h>
+
+#define CLKSPEEDREG_TYPE1	(void __iomem *)KSEG1ADDR(0x0b000014)
+#define CLKSPEEDREG_TYPE2	(void __iomem *)KSEG1ADDR(0x0f000014)
+ #define CLKSP(x)		((x) & 0x001f)
+ #define CLKSP_VR4133(x)	((x) & 0x0007)
+
+ #define DIV2B			0x8000
+ #define DIV3B			0x4000
+ #define DIV4B			0x2000
+
+ #define DIVT(x)		(((x) & 0xf000) >> 12)
+ #define DIVVT(x)		(((x) & 0x0f00) >> 8)
+
+ #define TDIVMODE(x)		(2 << (((x) & 0x1000) >> 12))
+ #define VTDIVMODE(x)		(((x) & 0x0700) >> 8)
+
+static unsigned long vr41xx_vtclock;
+static unsigned long vr41xx_tclock;
+
+unsigned long vr41xx_get_vtclock_frequency(void)
+{
+	return vr41xx_vtclock;
+}
+
+EXPORT_SYMBOL_GPL(vr41xx_get_vtclock_frequency);
+
+unsigned long vr41xx_get_tclock_frequency(void)
+{
+	return vr41xx_tclock;
+}
+
+EXPORT_SYMBOL_GPL(vr41xx_get_tclock_frequency);
+
+static inline uint16_t read_clkspeed(void)
+{
+	switch (current_cpu_data.cputype) {
+	case CPU_VR4111:
+	case CPU_VR4121: return readw(CLKSPEEDREG_TYPE1);
+	case CPU_VR4122:
+	case CPU_VR4131:
+	case CPU_VR4133: return readw(CLKSPEEDREG_TYPE2);
+	default:
+		printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
+		break;
+	}
+
+	return 0;
+}
+
+static inline unsigned long calculate_pclock(uint16_t clkspeed)
+{
+	unsigned long pclock = 0;
+
+	switch (current_cpu_data.cputype) {
+	case CPU_VR4111:
+	case CPU_VR4121:
+		pclock = 18432000 * 64;
+		pclock /= CLKSP(clkspeed);
+		break;
+	case CPU_VR4122:
+		pclock = 18432000 * 98;
+		pclock /= CLKSP(clkspeed);
+		break;
+	case CPU_VR4131:
+		pclock = 18432000 * 108;
+		pclock /= CLKSP(clkspeed);
+		break;
+	case CPU_VR4133:
+		switch (CLKSP_VR4133(clkspeed)) {
+		case 0:
+			pclock = 133000000;
+			break;
+		case 1:
+			pclock = 149000000;
+			break;
+		case 2:
+			pclock = 165900000;
+			break;
+		case 3:
+			pclock = 199100000;
+			break;
+		case 4:
+			pclock = 265900000;
+			break;
+		default:
+			printk(KERN_INFO "Unknown PClock speed for NEC VR4133\n");
+			break;
+		}
+		break;
+	default:
+		printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
+		break;
+	}
+
+	printk(KERN_INFO "PClock: %ldHz\n", pclock);
+
+	return pclock;
+}
+
+static inline unsigned long calculate_vtclock(uint16_t clkspeed, unsigned long pclock)
+{
+	unsigned long vtclock = 0;
+
+	switch (current_cpu_data.cputype) {
+	case CPU_VR4111:
+		/* The NEC VR4111 doesn't have the VTClock. */
+		break;
+	case CPU_VR4121:
+		vtclock = pclock;
+		/* DIVVT == 9 Divide by 1.5 . VTClock = (PClock * 6) / 9 */
+		if (DIVVT(clkspeed) == 9)
+			vtclock = pclock * 6;
+		/* DIVVT == 10 Divide by 2.5 . VTClock = (PClock * 4) / 10 */
+		else if (DIVVT(clkspeed) == 10)
+			vtclock = pclock * 4;
+		vtclock /= DIVVT(clkspeed);
+		printk(KERN_INFO "VTClock: %ldHz\n", vtclock);
+		break;
+	case CPU_VR4122:
+		if(VTDIVMODE(clkspeed) == 7)
+			vtclock = pclock / 1;
+		else if(VTDIVMODE(clkspeed) == 1)
+			vtclock = pclock / 2;
+		else
+			vtclock = pclock / VTDIVMODE(clkspeed);
+		printk(KERN_INFO "VTClock: %ldHz\n", vtclock);
+		break;
+	case CPU_VR4131:
+	case CPU_VR4133:
+		vtclock = pclock / VTDIVMODE(clkspeed);
+		printk(KERN_INFO "VTClock: %ldHz\n", vtclock);
+		break;
+	default:
+		printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
+		break;
+	}
+
+	return vtclock;
+}
+
+static inline unsigned long calculate_tclock(uint16_t clkspeed, unsigned long pclock,
+                                             unsigned long vtclock)
+{
+	unsigned long tclock = 0;
+
+	switch (current_cpu_data.cputype) {
+	case CPU_VR4111:
+		if (!(clkspeed & DIV2B))
+        		tclock = pclock / 2;
+		else if (!(clkspeed & DIV3B))
+        		tclock = pclock / 3;
+		else if (!(clkspeed & DIV4B))
+        		tclock = pclock / 4;
+		break;
+	case CPU_VR4121:
+		tclock = pclock / DIVT(clkspeed);
+		break;
+	case CPU_VR4122:
+	case CPU_VR4131:
+	case CPU_VR4133:
+		tclock = vtclock / TDIVMODE(clkspeed);
+		break;
+	default:
+		printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
+		break;
+	}
+
+	printk(KERN_INFO "TClock: %ldHz\n", tclock);
+
+	return tclock;
+}
+
+void vr41xx_calculate_clock_frequency(void)
+{
+	unsigned long pclock;
+	uint16_t clkspeed;
+
+	clkspeed = read_clkspeed();
+
+	pclock = calculate_pclock(clkspeed);
+	vr41xx_vtclock = calculate_vtclock(clkspeed, pclock);
+	vr41xx_tclock = calculate_tclock(clkspeed, pclock, vr41xx_vtclock);
+}
+
+EXPORT_SYMBOL_GPL(vr41xx_calculate_clock_frequency);
diff --git a/arch/mips/vr41xx/common/cmu.c b/arch/mips/vr41xx/common/cmu.c
new file mode 100644
index 0000000..fcd3cb8
--- /dev/null
+++ b/arch/mips/vr41xx/common/cmu.c
@@ -0,0 +1,257 @@
+/*
+ *  cmu.c, Clock Mask Unit routines for the NEC VR4100 series.
+ *
+ *  Copyright (C) 2001-2002  MontaVista Software Inc.
+ *    Author: Yoichi Yuasa <yyuasa@mvista.com or source@mvista.com>
+ *  Copuright (C) 2003-2005  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC VR4122 and VR4131 are supported.
+ *  - Added support for NEC VR4111 and VR4121.
+ *
+ *  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *  - Added support for NEC VR4133.
+ */
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <asm/vr41xx/vr41xx.h>
+
+#define CMU_TYPE1_BASE	0x0b000060UL
+#define CMU_TYPE1_SIZE	0x4
+
+#define CMU_TYPE2_BASE	0x0f000060UL
+#define CMU_TYPE2_SIZE	0x4
+
+#define CMU_TYPE3_BASE	0x0f000060UL
+#define CMU_TYPE3_SIZE	0x8
+
+#define CMUCLKMSK	0x0
+ #define MSKPIU		0x0001
+ #define MSKSIU		0x0002
+ #define MSKAIU		0x0004
+ #define MSKKIU		0x0008
+ #define MSKFIR		0x0010
+ #define MSKDSIU	0x0820
+ #define MSKCSI		0x0040
+ #define MSKPCIU	0x0080
+ #define MSKSSIU	0x0100
+ #define MSKSHSP	0x0200
+ #define MSKFFIR	0x0400
+ #define MSKSCSI	0x1000
+ #define MSKPPCIU	0x2000
+#define CMUCLKMSK2	0x4
+ #define MSKCEU		0x0001
+ #define MSKMAC0	0x0002
+ #define MSKMAC1	0x0004
+
+static void __iomem *cmu_base;
+static uint16_t cmuclkmsk, cmuclkmsk2;
+static spinlock_t cmu_lock;
+
+#define cmu_read(offset)		readw(cmu_base + (offset))
+#define cmu_write(offset, value)	writew((value), cmu_base + (offset))
+
+void vr41xx_supply_clock(vr41xx_clock_t clock)
+{
+	spin_lock_irq(&cmu_lock);
+
+	switch (clock) {
+	case PIU_CLOCK:
+		cmuclkmsk |= MSKPIU;
+		break;
+	case SIU_CLOCK:
+		cmuclkmsk |= MSKSIU | MSKSSIU;
+		break;
+	case AIU_CLOCK:
+		cmuclkmsk |= MSKAIU;
+		break;
+	case KIU_CLOCK:
+		cmuclkmsk |= MSKKIU;
+		break;
+	case FIR_CLOCK:
+		cmuclkmsk |= MSKFIR | MSKFFIR;
+		break;
+	case DSIU_CLOCK:
+		if (current_cpu_data.cputype == CPU_VR4111 ||
+		    current_cpu_data.cputype == CPU_VR4121)
+			cmuclkmsk |= MSKDSIU;
+		else
+			cmuclkmsk |= MSKSIU | MSKDSIU;
+		break;
+	case CSI_CLOCK:
+		cmuclkmsk |= MSKCSI | MSKSCSI;
+		break;
+	case PCIU_CLOCK:
+		cmuclkmsk |= MSKPCIU;
+		break;
+	case HSP_CLOCK:
+		cmuclkmsk |= MSKSHSP;
+		break;
+	case PCI_CLOCK:
+		cmuclkmsk |= MSKPPCIU;
+		break;
+	case CEU_CLOCK:
+		cmuclkmsk2 |= MSKCEU;
+		break;
+	case ETHER0_CLOCK:
+		cmuclkmsk2 |= MSKMAC0;
+		break;
+	case ETHER1_CLOCK:
+		cmuclkmsk2 |= MSKMAC1;
+		break;
+	default:
+		break;
+	}
+
+	if (clock == CEU_CLOCK || clock == ETHER0_CLOCK ||
+	    clock == ETHER1_CLOCK)
+		cmu_write(CMUCLKMSK2, cmuclkmsk2);
+	else
+		cmu_write(CMUCLKMSK, cmuclkmsk);
+
+	spin_unlock_irq(&cmu_lock);
+}
+
+EXPORT_SYMBOL_GPL(vr41xx_supply_clock);
+
+void vr41xx_mask_clock(vr41xx_clock_t clock)
+{
+	spin_lock_irq(&cmu_lock);
+
+	switch (clock) {
+	case PIU_CLOCK:
+		cmuclkmsk &= ~MSKPIU;
+		break;
+	case SIU_CLOCK:
+		if (current_cpu_data.cputype == CPU_VR4111 ||
+		    current_cpu_data.cputype == CPU_VR4121) {
+			cmuclkmsk &= ~(MSKSIU | MSKSSIU);
+		} else {
+			if (cmuclkmsk & MSKDSIU)
+				cmuclkmsk &= ~MSKSSIU;
+			else
+				cmuclkmsk &= ~(MSKSIU | MSKSSIU);
+		}
+		break;
+	case AIU_CLOCK:
+		cmuclkmsk &= ~MSKAIU;
+		break;
+	case KIU_CLOCK:
+		cmuclkmsk &= ~MSKKIU;
+		break;
+	case FIR_CLOCK:
+		cmuclkmsk &= ~(MSKFIR | MSKFFIR);
+		break;
+	case DSIU_CLOCK:
+		if (current_cpu_data.cputype == CPU_VR4111 ||
+		    current_cpu_data.cputype == CPU_VR4121) {
+			cmuclkmsk &= ~MSKDSIU;
+		} else {
+			if (cmuclkmsk & MSKSSIU)
+				cmuclkmsk &= ~MSKDSIU;
+			else
+				cmuclkmsk &= ~(MSKSIU | MSKDSIU);
+		}
+		break;
+	case CSI_CLOCK:
+		cmuclkmsk &= ~(MSKCSI | MSKSCSI);
+		break;
+	case PCIU_CLOCK:
+		cmuclkmsk &= ~MSKPCIU;
+		break;
+	case HSP_CLOCK:
+		cmuclkmsk &= ~MSKSHSP;
+		break;
+	case PCI_CLOCK:
+		cmuclkmsk &= ~MSKPPCIU;
+		break;
+	case CEU_CLOCK:
+		cmuclkmsk2 &= ~MSKCEU;
+		break;
+	case ETHER0_CLOCK:
+		cmuclkmsk2 &= ~MSKMAC0;
+		break;
+	case ETHER1_CLOCK:
+		cmuclkmsk2 &= ~MSKMAC1;
+		break;
+	default:
+		break;
+	}
+
+	if (clock == CEU_CLOCK || clock == ETHER0_CLOCK ||
+	    clock == ETHER1_CLOCK)
+		cmu_write(CMUCLKMSK2, cmuclkmsk2);
+	else
+		cmu_write(CMUCLKMSK, cmuclkmsk);
+
+	spin_unlock_irq(&cmu_lock);
+}
+
+EXPORT_SYMBOL_GPL(vr41xx_mask_clock);
+
+static int __init vr41xx_cmu_init(void)
+{
+	unsigned long start, size;
+
+	switch (current_cpu_data.cputype) {
+        case CPU_VR4111:
+        case CPU_VR4121:
+		start = CMU_TYPE1_BASE;
+		size = CMU_TYPE1_SIZE;
+                break;
+        case CPU_VR4122:
+        case CPU_VR4131:
+		start = CMU_TYPE2_BASE;
+		size = CMU_TYPE2_SIZE;
+		break;
+        case CPU_VR4133:
+		start = CMU_TYPE3_BASE;
+		size = CMU_TYPE3_SIZE;
+                break;
+	default:
+		panic("Unexpected CPU of NEC VR4100 series");
+		break;
+        }
+
+	if (request_mem_region(start, size, "CMU") == NULL)
+		return -EBUSY;
+
+	cmu_base = ioremap(start, size);
+	if (cmu_base == NULL) {
+		release_mem_region(start, size);
+		return -EBUSY;
+	}
+
+	cmuclkmsk = cmu_read(CMUCLKMSK);
+	if (current_cpu_data.cputype == CPU_VR4133)
+		cmuclkmsk2 = cmu_read(CMUCLKMSK2);
+
+	spin_lock_init(&cmu_lock);
+
+	return 0;
+}
+
+core_initcall(vr41xx_cmu_init);
diff --git a/arch/mips/vr41xx/common/giu.c b/arch/mips/vr41xx/common/giu.c
new file mode 100644
index 0000000..9c6b21a
--- /dev/null
+++ b/arch/mips/vr41xx/common/giu.c
@@ -0,0 +1,455 @@
+/*
+ *  giu.c, General-purpose I/O Unit Interrupt routines for NEC VR4100 series.
+ *
+ *  Copyright (C) 2002 MontaVista Software Inc.
+ *    Author: Yoichi Yuasa <yyuasa@mvista.com or source@mvista.com>
+ *  Copyright (C) 2003-2004  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *  Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC VR4111, VR4121, VR4122 and VR4131 are supported.
+ *
+ *  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *  - Added support for NEC VR4133.
+ *  - Removed board_irq_init.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/smp.h>
+#include <linux/types.h>
+
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <asm/vr41xx/vr41xx.h>
+
+#define GIUIOSELL_TYPE1	KSEG1ADDR(0x0b000100)
+#define GIUIOSELL_TYPE2	KSEG1ADDR(0x0f000140)
+
+#define GIUIOSELL	0x00
+#define GIUIOSELH	0x02
+#define GIUINTSTATL	0x08
+#define GIUINTSTATH	0x0a
+#define GIUINTENL	0x0c
+#define GIUINTENH	0x0e
+#define GIUINTTYPL	0x10
+#define GIUINTTYPH	0x12
+#define GIUINTALSELL	0x14
+#define GIUINTALSELH	0x16
+#define GIUINTHTSELL	0x18
+#define GIUINTHTSELH	0x1a
+#define GIUFEDGEINHL	0x20
+#define GIUFEDGEINHH	0x22
+#define GIUREDGEINHL	0x24
+#define GIUREDGEINHH	0x26
+
+static uint32_t giu_base;
+
+static struct irqaction giu_cascade = {
+	.handler	= no_action,
+	.mask		= CPU_MASK_NONE,
+	.name		= "cascade",
+};
+
+#define read_giuint(offset)		readw(giu_base + (offset))
+#define write_giuint(val, offset)	writew((val), giu_base + (offset))
+
+#define GIUINT_HIGH_OFFSET	16
+
+static inline uint16_t set_giuint(uint8_t offset, uint16_t set)
+{
+	uint16_t res;
+
+	res = read_giuint(offset);
+	res |= set;
+	write_giuint(res, offset);
+
+	return res;
+}
+
+static inline uint16_t clear_giuint(uint8_t offset, uint16_t clear)
+{
+	uint16_t res;
+
+	res = read_giuint(offset);
+	res &= ~clear;
+	write_giuint(res, offset);
+
+	return res;
+}
+
+static unsigned int startup_giuint_low_irq(unsigned int irq)
+{
+	unsigned int pin;
+
+	pin = GIU_IRQ_TO_PIN(irq);
+	write_giuint((uint16_t)1 << pin, GIUINTSTATL);
+	set_giuint(GIUINTENL, (uint16_t)1 << pin);
+
+	return 0;
+}
+
+static void shutdown_giuint_low_irq(unsigned int irq)
+{
+	clear_giuint(GIUINTENL, (uint16_t)1 << GIU_IRQ_TO_PIN(irq));
+}
+
+static void enable_giuint_low_irq(unsigned int irq)
+{
+	set_giuint(GIUINTENL, (uint16_t)1 << GIU_IRQ_TO_PIN(irq));
+}
+
+#define disable_giuint_low_irq	shutdown_giuint_low_irq
+
+static void ack_giuint_low_irq(unsigned int irq)
+{
+	unsigned int pin;
+
+	pin = GIU_IRQ_TO_PIN(irq);
+	clear_giuint(GIUINTENL, (uint16_t)1 << pin);
+	write_giuint((uint16_t)1 << pin, GIUINTSTATL);
+}
+
+static void end_giuint_low_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		set_giuint(GIUINTENL, (uint16_t)1 << GIU_IRQ_TO_PIN(irq));
+}
+
+static struct hw_interrupt_type giuint_low_irq_type = {
+	.typename	= "GIUINTL",
+	.startup	= startup_giuint_low_irq,
+	.shutdown	= shutdown_giuint_low_irq,
+	.enable		= enable_giuint_low_irq,
+	.disable	= disable_giuint_low_irq,
+	.ack		= ack_giuint_low_irq,
+	.end		= end_giuint_low_irq,
+};
+
+static unsigned int startup_giuint_high_irq(unsigned int irq)
+{
+	unsigned int pin;
+
+	pin = GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET);
+	write_giuint((uint16_t)1 << pin, GIUINTSTATH);
+	set_giuint(GIUINTENH, (uint16_t)1 << pin);
+
+	return 0;
+}
+
+static void shutdown_giuint_high_irq(unsigned int irq)
+{
+	clear_giuint(GIUINTENH, (uint16_t)1 << GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET));
+}
+
+static void enable_giuint_high_irq(unsigned int irq)
+{
+	set_giuint(GIUINTENH, (uint16_t)1 << GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET));
+}
+
+#define disable_giuint_high_irq	shutdown_giuint_high_irq
+
+static void ack_giuint_high_irq(unsigned int irq)
+{
+	unsigned int pin;
+
+	pin = GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET);
+	clear_giuint(GIUINTENH, (uint16_t)1 << pin);
+	write_giuint((uint16_t)1 << pin, GIUINTSTATH);
+}
+
+static void end_giuint_high_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		set_giuint(GIUINTENH, (uint16_t)1 << GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET));
+}
+
+static struct hw_interrupt_type giuint_high_irq_type = {
+	.typename	= "GIUINTH",
+	.startup	= startup_giuint_high_irq,
+	.shutdown	= shutdown_giuint_high_irq,
+	.enable		= enable_giuint_high_irq,
+	.disable	= disable_giuint_high_irq,
+	.ack		= ack_giuint_high_irq,
+	.end		= end_giuint_high_irq,
+};
+
+void __init init_vr41xx_giuint_irq(void)
+{
+	int i;
+
+	for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) {
+		if (i < (GIU_IRQ_BASE + GIUINT_HIGH_OFFSET))
+			irq_desc[i].handler = &giuint_low_irq_type;
+		else
+			irq_desc[i].handler = &giuint_high_irq_type;
+	}
+
+	setup_irq(GIUINT_CASCADE_IRQ, &giu_cascade);
+}
+
+void vr41xx_set_irq_trigger(int pin, int trigger, int hold)
+{
+	uint16_t mask;
+
+	if (pin < GIUINT_HIGH_OFFSET) {
+		mask = (uint16_t)1 << pin;
+		if (trigger != TRIGGER_LEVEL) {
+        		set_giuint(GIUINTTYPL, mask);
+			if (hold == SIGNAL_HOLD)
+				set_giuint(GIUINTHTSELL, mask);
+			else
+				clear_giuint(GIUINTHTSELL, mask);
+			if (current_cpu_data.cputype == CPU_VR4133) {
+				switch (trigger) {
+				case TRIGGER_EDGE_FALLING:
+					set_giuint(GIUFEDGEINHL, mask);
+					clear_giuint(GIUREDGEINHL, mask);
+					break;
+				case TRIGGER_EDGE_RISING:
+					clear_giuint(GIUFEDGEINHL, mask);
+					set_giuint(GIUREDGEINHL, mask);
+					break;
+				default:
+					set_giuint(GIUFEDGEINHL, mask);
+					set_giuint(GIUREDGEINHL, mask);
+					break;
+				}
+			}
+		} else {
+			clear_giuint(GIUINTTYPL, mask);
+			clear_giuint(GIUINTHTSELL, mask);
+		}
+		write_giuint(mask, GIUINTSTATL);
+	} else {
+		mask = (uint16_t)1 << (pin - GIUINT_HIGH_OFFSET);
+		if (trigger != TRIGGER_LEVEL) {
+			set_giuint(GIUINTTYPH, mask);
+			if (hold == SIGNAL_HOLD)
+				set_giuint(GIUINTHTSELH, mask);
+			else
+				clear_giuint(GIUINTHTSELH, mask);
+			if (current_cpu_data.cputype == CPU_VR4133) {
+				switch (trigger) {
+				case TRIGGER_EDGE_FALLING:
+					set_giuint(GIUFEDGEINHH, mask);
+					clear_giuint(GIUREDGEINHH, mask);
+					break;
+				case TRIGGER_EDGE_RISING:
+					clear_giuint(GIUFEDGEINHH, mask);
+					set_giuint(GIUREDGEINHH, mask);
+					break;
+				default:
+					set_giuint(GIUFEDGEINHH, mask);
+					set_giuint(GIUREDGEINHH, mask);
+					break;
+				}
+			}
+		} else {
+			clear_giuint(GIUINTTYPH, mask);
+			clear_giuint(GIUINTHTSELH, mask);
+		}
+		write_giuint(mask, GIUINTSTATH);
+	}
+}
+
+EXPORT_SYMBOL(vr41xx_set_irq_trigger);
+
+void vr41xx_set_irq_level(int pin, int level)
+{
+	uint16_t mask;
+
+	if (pin < GIUINT_HIGH_OFFSET) {
+		mask = (uint16_t)1 << pin;
+		if (level == LEVEL_HIGH)
+			set_giuint(GIUINTALSELL, mask);
+		else
+			clear_giuint(GIUINTALSELL, mask);
+		write_giuint(mask, GIUINTSTATL);
+	} else {
+		mask = (uint16_t)1 << (pin - GIUINT_HIGH_OFFSET);
+		if (level == LEVEL_HIGH)
+			set_giuint(GIUINTALSELH, mask);
+		else
+			clear_giuint(GIUINTALSELH, mask);
+		write_giuint(mask, GIUINTSTATH);
+	}
+}
+
+EXPORT_SYMBOL(vr41xx_set_irq_level);
+
+#define GIUINT_NR_IRQS		32
+
+enum {
+	GIUINT_NO_CASCADE,
+	GIUINT_CASCADE
+};
+
+struct vr41xx_giuint_cascade {
+	unsigned int flag;
+	int (*get_irq_number)(int irq);
+};
+
+static struct vr41xx_giuint_cascade giuint_cascade[GIUINT_NR_IRQS];
+
+static int no_irq_number(int irq)
+{
+	return -EINVAL;
+}
+
+int vr41xx_cascade_irq(unsigned int irq, int (*get_irq_number)(int irq))
+{
+	unsigned int pin;
+	int retval;
+
+	if (irq < GIU_IRQ(0) || irq > GIU_IRQ(31))
+		return -EINVAL;
+
+	if(!get_irq_number)
+		return -EINVAL;
+
+	pin = GIU_IRQ_TO_PIN(irq);
+	giuint_cascade[pin].flag = GIUINT_CASCADE;
+	giuint_cascade[pin].get_irq_number = get_irq_number;
+
+	retval = setup_irq(irq, &giu_cascade);
+	if (retval != 0) {
+		giuint_cascade[pin].flag = GIUINT_NO_CASCADE;
+		giuint_cascade[pin].get_irq_number = no_irq_number;
+	}
+
+	return retval;
+}
+
+EXPORT_SYMBOL(vr41xx_cascade_irq);
+
+static inline int get_irq_pin_number(void)
+{
+	uint16_t pendl, pendh, maskl, maskh;
+	int i;
+
+	pendl = read_giuint(GIUINTSTATL);
+	pendh = read_giuint(GIUINTSTATH);
+	maskl = read_giuint(GIUINTENL);
+	maskh = read_giuint(GIUINTENH);
+
+	maskl &= pendl;
+	maskh &= pendh;
+
+	if (maskl) {
+		for (i = 0; i < 16; i++) {
+			if (maskl & ((uint16_t)1 << i))
+				return i;
+		}
+	} else if (maskh) {
+		for (i = 0; i < 16; i++) {
+			if (maskh & ((uint16_t)1 << i))
+				return i + GIUINT_HIGH_OFFSET;
+		}
+	}
+
+	printk(KERN_ERR "spurious GIU interrupt: %04x(%04x),%04x(%04x)\n",
+	       maskl, pendl, maskh, pendh);
+
+	atomic_inc(&irq_err_count);
+
+	return -1;
+}
+
+static inline void ack_giuint_irq(int pin)
+{
+	if (pin < GIUINT_HIGH_OFFSET) {
+		clear_giuint(GIUINTENL, (uint16_t)1 << pin);
+		write_giuint((uint16_t)1 << pin, GIUINTSTATL);
+	} else {
+		pin -= GIUINT_HIGH_OFFSET;
+		clear_giuint(GIUINTENH, (uint16_t)1 << pin);
+		write_giuint((uint16_t)1 << pin, GIUINTSTATH);
+	}
+}
+
+static inline void end_giuint_irq(int pin)
+{
+	if (pin < GIUINT_HIGH_OFFSET)
+		set_giuint(GIUINTENL, (uint16_t)1 << pin);
+	else
+		set_giuint(GIUINTENH, (uint16_t)1 << (pin - GIUINT_HIGH_OFFSET));
+}
+
+void giuint_irq_dispatch(struct pt_regs *regs)
+{
+	struct vr41xx_giuint_cascade *cascade;
+	unsigned int giuint_irq;
+	int pin;
+
+	pin = get_irq_pin_number();
+	if (pin < 0)
+		return;
+
+	disable_irq(GIUINT_CASCADE_IRQ);
+
+	cascade = &giuint_cascade[pin];
+	giuint_irq = GIU_IRQ(pin);
+	if (cascade->flag == GIUINT_CASCADE) {
+		int irq = cascade->get_irq_number(giuint_irq);
+		ack_giuint_irq(pin);
+		if (irq >= 0)
+			do_IRQ(irq, regs);
+		end_giuint_irq(pin);
+	} else {
+		do_IRQ(giuint_irq, regs);
+	}
+
+	enable_irq(GIUINT_CASCADE_IRQ);
+}
+
+static int __init vr41xx_giu_init(void)
+{
+	int i;
+
+	switch (current_cpu_data.cputype) {
+	case CPU_VR4111:
+	case CPU_VR4121:
+		giu_base = GIUIOSELL_TYPE1;
+		break;
+	case CPU_VR4122:
+	case CPU_VR4131:
+	case CPU_VR4133:
+		giu_base = GIUIOSELL_TYPE2;
+		break;
+	default:
+		printk(KERN_ERR "GIU: Unexpected CPU of NEC VR4100 series\n");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < GIUINT_NR_IRQS; i++) {
+		if (i < GIUINT_HIGH_OFFSET)
+			clear_giuint(GIUINTENL, (uint16_t)1 << i);
+		else
+			clear_giuint(GIUINTENH, (uint16_t)1 << (i - GIUINT_HIGH_OFFSET));
+		giuint_cascade[i].flag = GIUINT_NO_CASCADE;
+		giuint_cascade[i].get_irq_number = no_irq_number;
+	}
+
+	return 0;
+}
+
+early_initcall(vr41xx_giu_init);
diff --git a/arch/mips/vr41xx/common/icu.c b/arch/mips/vr41xx/common/icu.c
new file mode 100644
index 0000000..c842661
--- /dev/null
+++ b/arch/mips/vr41xx/common/icu.c
@@ -0,0 +1,757 @@
+/*
+ *  icu.c, Interrupt Control Unit routines for the NEC VR4100 series.
+ *
+ *  Copyright (C) 2001-2002  MontaVista Software Inc.
+ *    Author: Yoichi Yuasa <yyuasa@mvista.com or source@mvista.com>
+ *  Copyright (C) 2003-2004  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *  Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC VR4122 and VR4131 are supported.
+ *  - Added support for NEC VR4111 and VR4121.
+ *
+ *  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *  - Coped with INTASSIGN of NEC VR4133.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/smp.h>
+#include <linux/types.h>
+
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/irq_cpu.h>
+#include <asm/vr41xx/vr41xx.h>
+
+extern asmlinkage void vr41xx_handle_interrupt(void);
+
+extern void init_vr41xx_giuint_irq(void);
+extern void giuint_irq_dispatch(struct pt_regs *regs);
+
+static uint32_t icu1_base;
+static uint32_t icu2_base;
+
+static struct irqaction icu_cascade = {
+	.handler	= no_action,
+	.mask		= CPU_MASK_NONE,
+	.name		= "cascade",
+};
+
+static unsigned char sysint1_assign[16] = {
+	0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+static unsigned char sysint2_assign[16] = {
+	2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+#define SYSINT1REG_TYPE1	KSEG1ADDR(0x0b000080)
+#define SYSINT2REG_TYPE1	KSEG1ADDR(0x0b000200)
+
+#define SYSINT1REG_TYPE2	KSEG1ADDR(0x0f000080)
+#define SYSINT2REG_TYPE2	KSEG1ADDR(0x0f0000a0)
+
+#define SYSINT1REG	0x00
+#define PIUINTREG	0x02
+#define INTASSIGN0	0x04
+#define INTASSIGN1	0x06
+#define GIUINTLREG	0x08
+#define DSIUINTREG	0x0a
+#define MSYSINT1REG	0x0c
+#define MPIUINTREG	0x0e
+#define MAIUINTREG	0x10
+#define MKIUINTREG	0x12
+#define MGIUINTLREG	0x14
+#define MDSIUINTREG	0x16
+#define NMIREG		0x18
+#define SOFTREG		0x1a
+#define INTASSIGN2	0x1c
+#define INTASSIGN3	0x1e
+
+#define SYSINT2REG	0x00
+#define GIUINTHREG	0x02
+#define FIRINTREG	0x04
+#define MSYSINT2REG	0x06
+#define MGIUINTHREG	0x08
+#define MFIRINTREG	0x0a
+#define PCIINTREG	0x0c
+ #define PCIINT0	0x0001
+#define SCUINTREG	0x0e
+ #define SCUINT0	0x0001
+#define CSIINTREG	0x10
+#define MPCIINTREG	0x12
+#define MSCUINTREG	0x14
+#define MCSIINTREG	0x16
+#define BCUINTREG	0x18
+ #define BCUINTR	0x0001
+#define MBCUINTREG	0x1a
+
+#define SYSINT1_IRQ_TO_PIN(x)	((x) - SYSINT1_IRQ_BASE)	/* Pin 0-15 */
+#define SYSINT2_IRQ_TO_PIN(x)	((x) - SYSINT2_IRQ_BASE)	/* Pin 0-15 */
+
+#define read_icu1(offset)	readw(icu1_base + (offset))
+#define write_icu1(val, offset)	writew((val), icu1_base + (offset))
+
+#define read_icu2(offset)	readw(icu2_base + (offset))
+#define write_icu2(val, offset)	writew((val), icu2_base + (offset))
+
+#define INTASSIGN_MAX	4
+#define INTASSIGN_MASK	0x0007
+
+static inline uint16_t set_icu1(uint8_t offset, uint16_t set)
+{
+	uint16_t res;
+
+	res = read_icu1(offset);
+	res |= set;
+	write_icu1(res, offset);
+
+	return res;
+}
+
+static inline uint16_t clear_icu1(uint8_t offset, uint16_t clear)
+{
+	uint16_t res;
+
+	res = read_icu1(offset);
+	res &= ~clear;
+	write_icu1(res, offset);
+
+	return res;
+}
+
+static inline uint16_t set_icu2(uint8_t offset, uint16_t set)
+{
+	uint16_t res;
+
+	res = read_icu2(offset);
+	res |= set;
+	write_icu2(res, offset);
+
+	return res;
+}
+
+static inline uint16_t clear_icu2(uint8_t offset, uint16_t clear)
+{
+	uint16_t res;
+
+	res = read_icu2(offset);
+	res &= ~clear;
+	write_icu2(res, offset);
+
+	return res;
+}
+
+/*=======================================================================*/
+
+void vr41xx_enable_piuint(uint16_t mask)
+{
+	irq_desc_t *desc = irq_desc + PIU_IRQ;
+	unsigned long flags;
+
+	if (current_cpu_data.cputype == CPU_VR4111 ||
+	    current_cpu_data.cputype == CPU_VR4121) {
+		spin_lock_irqsave(&desc->lock, flags);
+		set_icu1(MPIUINTREG, mask);
+		spin_unlock_irqrestore(&desc->lock, flags);
+	}
+}
+
+EXPORT_SYMBOL(vr41xx_enable_piuint);
+
+void vr41xx_disable_piuint(uint16_t mask)
+{
+	irq_desc_t *desc = irq_desc + PIU_IRQ;
+	unsigned long flags;
+
+	if (current_cpu_data.cputype == CPU_VR4111 ||
+	    current_cpu_data.cputype == CPU_VR4121) {
+		spin_lock_irqsave(&desc->lock, flags);
+		clear_icu1(MPIUINTREG, mask);
+		spin_unlock_irqrestore(&desc->lock, flags);
+	}
+}
+
+EXPORT_SYMBOL(vr41xx_disable_piuint);
+
+void vr41xx_enable_aiuint(uint16_t mask)
+{
+	irq_desc_t *desc = irq_desc + AIU_IRQ;
+	unsigned long flags;
+
+	if (current_cpu_data.cputype == CPU_VR4111 ||
+	    current_cpu_data.cputype == CPU_VR4121) {
+		spin_lock_irqsave(&desc->lock, flags);
+		set_icu1(MAIUINTREG, mask);
+		spin_unlock_irqrestore(&desc->lock, flags);
+	}
+}
+
+EXPORT_SYMBOL(vr41xx_enable_aiuint);
+
+void vr41xx_disable_aiuint(uint16_t mask)
+{
+	irq_desc_t *desc = irq_desc + AIU_IRQ;
+	unsigned long flags;
+
+	if (current_cpu_data.cputype == CPU_VR4111 ||
+	    current_cpu_data.cputype == CPU_VR4121) {
+		spin_lock_irqsave(&desc->lock, flags);
+		clear_icu1(MAIUINTREG, mask);
+		spin_unlock_irqrestore(&desc->lock, flags);
+	}
+}
+
+EXPORT_SYMBOL(vr41xx_disable_aiuint);
+
+void vr41xx_enable_kiuint(uint16_t mask)
+{
+	irq_desc_t *desc = irq_desc + KIU_IRQ;
+	unsigned long flags;
+
+	if (current_cpu_data.cputype == CPU_VR4111 ||
+	    current_cpu_data.cputype == CPU_VR4121) {
+		spin_lock_irqsave(&desc->lock, flags);
+		set_icu1(MKIUINTREG, mask);
+		spin_unlock_irqrestore(&desc->lock, flags);
+	}
+}
+
+EXPORT_SYMBOL(vr41xx_enable_kiuint);
+
+void vr41xx_disable_kiuint(uint16_t mask)
+{
+	irq_desc_t *desc = irq_desc + KIU_IRQ;
+	unsigned long flags;
+
+	if (current_cpu_data.cputype == CPU_VR4111 ||
+	    current_cpu_data.cputype == CPU_VR4121) {
+		spin_lock_irqsave(&desc->lock, flags);
+		clear_icu1(MKIUINTREG, mask);
+		spin_unlock_irqrestore(&desc->lock, flags);
+	}
+}
+
+EXPORT_SYMBOL(vr41xx_disable_kiuint);
+
+void vr41xx_enable_dsiuint(uint16_t mask)
+{
+	irq_desc_t *desc = irq_desc + DSIU_IRQ;
+	unsigned long flags;
+
+	spin_lock_irqsave(&desc->lock, flags);
+	set_icu1(MDSIUINTREG, mask);
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+EXPORT_SYMBOL(vr41xx_enable_dsiuint);
+
+void vr41xx_disable_dsiuint(uint16_t mask)
+{
+	irq_desc_t *desc = irq_desc + DSIU_IRQ;
+	unsigned long flags;
+
+	spin_lock_irqsave(&desc->lock, flags);
+	clear_icu1(MDSIUINTREG, mask);
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+EXPORT_SYMBOL(vr41xx_disable_dsiuint);
+
+void vr41xx_enable_firint(uint16_t mask)
+{
+	irq_desc_t *desc = irq_desc + FIR_IRQ;
+	unsigned long flags;
+
+	spin_lock_irqsave(&desc->lock, flags);
+	set_icu2(MFIRINTREG, mask);
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+EXPORT_SYMBOL(vr41xx_enable_firint);
+
+void vr41xx_disable_firint(uint16_t mask)
+{
+	irq_desc_t *desc = irq_desc + FIR_IRQ;
+	unsigned long flags;
+
+	spin_lock_irqsave(&desc->lock, flags);
+	clear_icu2(MFIRINTREG, mask);
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+EXPORT_SYMBOL(vr41xx_disable_firint);
+
+void vr41xx_enable_pciint(void)
+{
+	irq_desc_t *desc = irq_desc + PCI_IRQ;
+	unsigned long flags;
+
+	if (current_cpu_data.cputype == CPU_VR4122 ||
+	    current_cpu_data.cputype == CPU_VR4131 ||
+	    current_cpu_data.cputype == CPU_VR4133) {
+		spin_lock_irqsave(&desc->lock, flags);
+		write_icu2(PCIINT0, MPCIINTREG);
+		spin_unlock_irqrestore(&desc->lock, flags);
+	}
+}
+
+EXPORT_SYMBOL(vr41xx_enable_pciint);
+
+void vr41xx_disable_pciint(void)
+{
+	irq_desc_t *desc = irq_desc + PCI_IRQ;
+	unsigned long flags;
+
+	if (current_cpu_data.cputype == CPU_VR4122 ||
+	    current_cpu_data.cputype == CPU_VR4131 ||
+	    current_cpu_data.cputype == CPU_VR4133) {
+		spin_lock_irqsave(&desc->lock, flags);
+		write_icu2(0, MPCIINTREG);
+		spin_unlock_irqrestore(&desc->lock, flags);
+	}
+}
+
+EXPORT_SYMBOL(vr41xx_disable_pciint);
+
+void vr41xx_enable_scuint(void)
+{
+	irq_desc_t *desc = irq_desc + SCU_IRQ;
+	unsigned long flags;
+
+	if (current_cpu_data.cputype == CPU_VR4122 ||
+	    current_cpu_data.cputype == CPU_VR4131 ||
+	    current_cpu_data.cputype == CPU_VR4133) {
+		spin_lock_irqsave(&desc->lock, flags);
+		write_icu2(SCUINT0, MSCUINTREG);
+		spin_unlock_irqrestore(&desc->lock, flags);
+	}
+}
+
+EXPORT_SYMBOL(vr41xx_enable_scuint);
+
+void vr41xx_disable_scuint(void)
+{
+	irq_desc_t *desc = irq_desc + SCU_IRQ;
+	unsigned long flags;
+
+	if (current_cpu_data.cputype == CPU_VR4122 ||
+	    current_cpu_data.cputype == CPU_VR4131 ||
+	    current_cpu_data.cputype == CPU_VR4133) {
+		spin_lock_irqsave(&desc->lock, flags);
+		write_icu2(0, MSCUINTREG);
+		spin_unlock_irqrestore(&desc->lock, flags);
+	}
+}
+
+EXPORT_SYMBOL(vr41xx_disable_scuint);
+
+void vr41xx_enable_csiint(uint16_t mask)
+{
+	irq_desc_t *desc = irq_desc + CSI_IRQ;
+	unsigned long flags;
+
+	if (current_cpu_data.cputype == CPU_VR4122 ||
+	    current_cpu_data.cputype == CPU_VR4131 ||
+	    current_cpu_data.cputype == CPU_VR4133) {
+		spin_lock_irqsave(&desc->lock, flags);
+		set_icu2(MCSIINTREG, mask);
+		spin_unlock_irqrestore(&desc->lock, flags);
+	}
+}
+
+EXPORT_SYMBOL(vr41xx_enable_csiint);
+
+void vr41xx_disable_csiint(uint16_t mask)
+{
+	irq_desc_t *desc = irq_desc + CSI_IRQ;
+	unsigned long flags;
+
+	if (current_cpu_data.cputype == CPU_VR4122 ||
+	    current_cpu_data.cputype == CPU_VR4131 ||
+	    current_cpu_data.cputype == CPU_VR4133) {
+		spin_lock_irqsave(&desc->lock, flags);
+		clear_icu2(MCSIINTREG, mask);
+		spin_unlock_irqrestore(&desc->lock, flags);
+	}
+}
+
+EXPORT_SYMBOL(vr41xx_disable_csiint);
+
+void vr41xx_enable_bcuint(void)
+{
+	irq_desc_t *desc = irq_desc + BCU_IRQ;
+	unsigned long flags;
+
+	if (current_cpu_data.cputype == CPU_VR4122 ||
+	    current_cpu_data.cputype == CPU_VR4131 ||
+	    current_cpu_data.cputype == CPU_VR4133) {
+		spin_lock_irqsave(&desc->lock, flags);
+		write_icu2(BCUINTR, MBCUINTREG);
+		spin_unlock_irqrestore(&desc->lock, flags);
+	}
+}
+
+EXPORT_SYMBOL(vr41xx_enable_bcuint);
+
+void vr41xx_disable_bcuint(void)
+{
+	irq_desc_t *desc = irq_desc + BCU_IRQ;
+	unsigned long flags;
+
+	if (current_cpu_data.cputype == CPU_VR4122 ||
+	    current_cpu_data.cputype == CPU_VR4131 ||
+	    current_cpu_data.cputype == CPU_VR4133) {
+		spin_lock_irqsave(&desc->lock, flags);
+		write_icu2(0, MBCUINTREG);
+		spin_unlock_irqrestore(&desc->lock, flags);
+	}
+}
+
+EXPORT_SYMBOL(vr41xx_disable_bcuint);
+
+/*=======================================================================*/
+
+static unsigned int startup_sysint1_irq(unsigned int irq)
+{
+	set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq));
+
+	return 0; /* never anything pending */
+}
+
+static void shutdown_sysint1_irq(unsigned int irq)
+{
+	clear_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq));
+}
+
+static void enable_sysint1_irq(unsigned int irq)
+{
+	set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq));
+}
+
+#define disable_sysint1_irq	shutdown_sysint1_irq
+#define ack_sysint1_irq		shutdown_sysint1_irq
+
+static void end_sysint1_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq));
+}
+
+static struct hw_interrupt_type sysint1_irq_type = {
+	.typename	= "SYSINT1",
+	.startup	= startup_sysint1_irq,
+	.shutdown	= shutdown_sysint1_irq,
+	.enable		= enable_sysint1_irq,
+	.disable	= disable_sysint1_irq,
+	.ack		= ack_sysint1_irq,
+	.end		= end_sysint1_irq,
+};
+
+/*=======================================================================*/
+
+static unsigned int startup_sysint2_irq(unsigned int irq)
+{
+	set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq));
+
+	return 0; /* never anything pending */
+}
+
+static void shutdown_sysint2_irq(unsigned int irq)
+{
+	clear_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq));
+}
+
+static void enable_sysint2_irq(unsigned int irq)
+{
+	set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq));
+}
+
+#define disable_sysint2_irq	shutdown_sysint2_irq
+#define ack_sysint2_irq		shutdown_sysint2_irq
+
+static void end_sysint2_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq));
+}
+
+static struct hw_interrupt_type sysint2_irq_type = {
+	.typename	= "SYSINT2",
+	.startup	= startup_sysint2_irq,
+	.shutdown	= shutdown_sysint2_irq,
+	.enable		= enable_sysint2_irq,
+	.disable	= disable_sysint2_irq,
+	.ack		= ack_sysint2_irq,
+	.end		= end_sysint2_irq,
+};
+
+/*=======================================================================*/
+
+static inline int set_sysint1_assign(unsigned int irq, unsigned char assign)
+{
+	irq_desc_t *desc = irq_desc + irq;
+	uint16_t intassign0, intassign1;
+	unsigned int pin;
+
+	pin = SYSINT1_IRQ_TO_PIN(irq);
+
+	spin_lock_irq(&desc->lock);
+
+	intassign0 = read_icu1(INTASSIGN0);
+	intassign1 = read_icu1(INTASSIGN1);
+
+	switch (pin) {
+	case 0:
+		intassign0 &= ~INTASSIGN_MASK;
+		intassign0 |= (uint16_t)assign;
+		break;
+	case 1:
+		intassign0 &= ~(INTASSIGN_MASK << 3);
+		intassign0 |= (uint16_t)assign << 3;
+		break;
+	case 2:
+		intassign0 &= ~(INTASSIGN_MASK << 6);
+		intassign0 |= (uint16_t)assign << 6;
+		break;
+	case 3:
+		intassign0 &= ~(INTASSIGN_MASK << 9);
+		intassign0 |= (uint16_t)assign << 9;
+		break;
+	case 8:
+		intassign0 &= ~(INTASSIGN_MASK << 12);
+		intassign0 |= (uint16_t)assign << 12;
+		break;
+	case 9:
+		intassign1 &= ~INTASSIGN_MASK;
+		intassign1 |= (uint16_t)assign;
+		break;
+	case 11:
+		intassign1 &= ~(INTASSIGN_MASK << 6);
+		intassign1 |= (uint16_t)assign << 6;
+		break;
+	case 12:
+		intassign1 &= ~(INTASSIGN_MASK << 9);
+		intassign1 |= (uint16_t)assign << 9;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	sysint1_assign[pin] = assign;
+	write_icu1(intassign0, INTASSIGN0);
+	write_icu1(intassign1, INTASSIGN1);
+
+	spin_unlock_irq(&desc->lock);
+
+	return 0;
+}
+
+static inline int set_sysint2_assign(unsigned int irq, unsigned char assign)
+{
+	irq_desc_t *desc = irq_desc + irq;
+	uint16_t intassign2, intassign3;
+	unsigned int pin;
+
+	pin = SYSINT2_IRQ_TO_PIN(irq);
+
+	spin_lock_irq(&desc->lock);
+
+	intassign2 = read_icu1(INTASSIGN2);
+	intassign3 = read_icu1(INTASSIGN3);
+
+	switch (pin) {
+	case 0:
+		intassign2 &= ~INTASSIGN_MASK;
+		intassign2 |= (uint16_t)assign;
+		break;
+	case 1:
+		intassign2 &= ~(INTASSIGN_MASK << 3);
+		intassign2 |= (uint16_t)assign << 3;
+		break;
+	case 3:
+		intassign2 &= ~(INTASSIGN_MASK << 6);
+		intassign2 |= (uint16_t)assign << 6;
+		break;
+	case 4:
+		intassign2 &= ~(INTASSIGN_MASK << 9);
+		intassign2 |= (uint16_t)assign << 9;
+		break;
+	case 5:
+		intassign2 &= ~(INTASSIGN_MASK << 12);
+		intassign2 |= (uint16_t)assign << 12;
+		break;
+	case 6:
+		intassign3 &= ~INTASSIGN_MASK;
+		intassign3 |= (uint16_t)assign;
+		break;
+	case 7:
+		intassign3 &= ~(INTASSIGN_MASK << 3);
+		intassign3 |= (uint16_t)assign << 3;
+		break;
+	case 8:
+		intassign3 &= ~(INTASSIGN_MASK << 6);
+		intassign3 |= (uint16_t)assign << 6;
+		break;
+	case 9:
+		intassign3 &= ~(INTASSIGN_MASK << 9);
+		intassign3 |= (uint16_t)assign << 9;
+		break;
+	case 10:
+		intassign3 &= ~(INTASSIGN_MASK << 12);
+		intassign3 |= (uint16_t)assign << 12;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	sysint2_assign[pin] = assign;
+	write_icu1(intassign2, INTASSIGN2);
+	write_icu1(intassign3, INTASSIGN3);
+
+	spin_unlock_irq(&desc->lock);
+
+	return 0;
+}
+
+int vr41xx_set_intassign(unsigned int irq, unsigned char intassign)
+{
+	int retval = -EINVAL;
+
+	if (current_cpu_data.cputype != CPU_VR4133)
+		return -EINVAL;
+
+	if (intassign > INTASSIGN_MAX)
+		return -EINVAL;
+
+	if (irq >= SYSINT1_IRQ_BASE && irq <= SYSINT1_IRQ_LAST)
+		retval = set_sysint1_assign(irq, intassign);
+	else if (irq >= SYSINT2_IRQ_BASE && irq <= SYSINT2_IRQ_LAST)
+		retval = set_sysint2_assign(irq, intassign);
+
+	return retval;
+}
+
+EXPORT_SYMBOL(vr41xx_set_intassign);
+
+/*=======================================================================*/
+
+asmlinkage void irq_dispatch(unsigned char intnum, struct pt_regs *regs)
+{
+	uint16_t pend1, pend2;
+	uint16_t mask1, mask2;
+	int i;
+
+	pend1 = read_icu1(SYSINT1REG);
+	mask1 = read_icu1(MSYSINT1REG);
+
+	pend2 = read_icu2(SYSINT2REG);
+	mask2 = read_icu2(MSYSINT2REG);
+
+	mask1 &= pend1;
+	mask2 &= pend2;
+
+	if (mask1) {
+		for (i = 0; i < 16; i++) {
+			if (intnum == sysint1_assign[i] &&
+			    (mask1 & ((uint16_t)1 << i))) {
+				if (i == 8)
+					giuint_irq_dispatch(regs);
+				else
+					do_IRQ(SYSINT1_IRQ(i), regs);
+				return;
+			}
+		}
+	}
+
+	if (mask2) {
+		for (i = 0; i < 16; i++) {
+			if (intnum == sysint2_assign[i] &&
+			    (mask2 & ((uint16_t)1 << i))) {
+				do_IRQ(SYSINT2_IRQ(i), regs);
+				return;
+			}
+		}
+	}
+
+	printk(KERN_ERR "spurious ICU interrupt: %04x,%04x\n", pend1, pend2);
+
+	atomic_inc(&irq_err_count);
+}
+
+/*=======================================================================*/
+
+static int __init vr41xx_icu_init(void)
+{
+	switch (current_cpu_data.cputype) {
+	case CPU_VR4111:
+	case CPU_VR4121:
+		icu1_base = SYSINT1REG_TYPE1;
+		icu2_base = SYSINT2REG_TYPE1;
+		break;
+	case CPU_VR4122:
+	case CPU_VR4131:
+	case CPU_VR4133:
+		icu1_base = SYSINT1REG_TYPE2;
+		icu2_base = SYSINT2REG_TYPE2;
+		break;
+	default:
+		printk(KERN_ERR "ICU: Unexpected CPU of NEC VR4100 series\n");
+		return -EINVAL;
+	}
+
+	write_icu1(0, MSYSINT1REG);
+	write_icu1(0xffff, MGIUINTLREG);
+
+	write_icu2(0, MSYSINT2REG);
+	write_icu2(0xffff, MGIUINTHREG);
+
+	return 0;
+}
+
+early_initcall(vr41xx_icu_init);
+
+/*=======================================================================*/
+
+static inline void init_vr41xx_icu_irq(void)
+{
+	int i;
+
+	for (i = SYSINT1_IRQ_BASE; i <= SYSINT1_IRQ_LAST; i++)
+		irq_desc[i].handler = &sysint1_irq_type;
+
+	for (i = SYSINT2_IRQ_BASE; i <= SYSINT2_IRQ_LAST; i++)
+		irq_desc[i].handler = &sysint2_irq_type;
+
+	setup_irq(INT0_CASCADE_IRQ, &icu_cascade);
+	setup_irq(INT1_CASCADE_IRQ, &icu_cascade);
+	setup_irq(INT2_CASCADE_IRQ, &icu_cascade);
+	setup_irq(INT3_CASCADE_IRQ, &icu_cascade);
+	setup_irq(INT4_CASCADE_IRQ, &icu_cascade);
+}
+
+void __init arch_init_irq(void)
+{
+	mips_cpu_irq_init(MIPS_CPU_IRQ_BASE);
+	init_vr41xx_icu_irq();
+	init_vr41xx_giuint_irq();
+
+	set_except_vector(0, vr41xx_handle_interrupt);
+}
diff --git a/arch/mips/vr41xx/common/init.c b/arch/mips/vr41xx/common/init.c
new file mode 100644
index 0000000..e03be89
--- /dev/null
+++ b/arch/mips/vr41xx/common/init.c
@@ -0,0 +1,85 @@
+/*
+ *  init.c, Common initialization routines for NEC VR4100 series.
+ *
+ *  Copyright (C) 2003-2005  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/time.h>
+#include <asm/vr41xx/vr41xx.h>
+
+#define IO_MEM_RESOURCE_START	0UL
+#define IO_MEM_RESOURCE_END	0x1fffffffUL
+
+static void __init iomem_resource_init(void)
+{
+	iomem_resource.start = IO_MEM_RESOURCE_START;
+	iomem_resource.end = IO_MEM_RESOURCE_END;
+}
+
+static void __init setup_timer_frequency(void)
+{
+	unsigned long tclock;
+
+	tclock = vr41xx_get_tclock_frequency();
+	if (current_cpu_data.processor_id == PRID_VR4131_REV2_0 ||
+	    current_cpu_data.processor_id == PRID_VR4131_REV2_1)
+		mips_hpt_frequency = tclock / 2;
+	else
+		mips_hpt_frequency = tclock / 4;
+}
+
+static void __init setup_timer_irq(struct irqaction *irq)
+{
+	setup_irq(TIMER_IRQ, irq);
+}
+
+static void __init timer_init(void)
+{
+	board_time_init = setup_timer_frequency;
+	board_timer_setup = setup_timer_irq;
+}
+
+void __init prom_init(void)
+{
+	int argc, i;
+	char **argv;
+
+	argc = fw_arg0;
+	argv = (char **)fw_arg1;
+
+	for (i = 1; i < argc; i++) {
+		strcat(arcs_cmdline, argv[i]);
+		if (i < (argc - 1))
+			strcat(arcs_cmdline, " ");
+	}
+
+	vr41xx_calculate_clock_frequency();
+
+	timer_init();
+
+	iomem_resource_init();
+}
+
+unsigned long __init prom_free_prom_memory (void)
+{
+	return 0UL;
+}
diff --git a/arch/mips/vr41xx/common/int-handler.S b/arch/mips/vr41xx/common/int-handler.S
new file mode 100644
index 0000000..38ff89b
--- /dev/null
+++ b/arch/mips/vr41xx/common/int-handler.S
@@ -0,0 +1,114 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/common/int-handler.S
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Interrupt dispatcher for the NEC VR4100 series.
+ *
+ * Author: Yoichi Yuasa
+ *         yyuasa@mvista.com or source@mvista.com
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC VR4100 series are supported.
+ *
+ *  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *  - Coped with INTASSIGN of NEC VR4133.
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+
+		.text
+		.set	noreorder
+
+		.align	5
+		NESTED(vr41xx_handle_interrupt, PT_SIZE, ra)
+		.set	noat
+		SAVE_ALL
+		CLI
+		.set	at
+		.set	noreorder
+
+		/*
+		 * Get the pending interrupts
+		 */
+		mfc0	t0, CP0_CAUSE
+		mfc0	t1, CP0_STATUS
+		andi	t0, 0xff00
+		and	t0, t0, t1
+
+		andi	t1, t0, CAUSEF_IP7	# MIPS timer interrupt
+		bnez	t1, handle_irq
+		li	a0, 7
+
+		andi	t1, t0, 0x7800		# check for Int1-4
+		beqz	t1, 1f
+
+		andi	t1, t0, CAUSEF_IP3	# check for Int1
+		bnez	t1, handle_int
+		li	a0, 1
+
+		andi	t1, t0, CAUSEF_IP4	# check for Int2
+		bnez	t1, handle_int
+		li	a0, 2
+
+		andi	t1, t0, CAUSEF_IP5	# check for Int3
+		bnez	t1, handle_int
+		li	a0, 3
+
+		andi	t1, t0, CAUSEF_IP6	# check for Int4
+		bnez	t1, handle_int
+		li	a0, 4
+
+1:
+		andi	t1, t0, CAUSEF_IP2	# check for Int0
+		bnez	t1, handle_int
+		li	a0, 0
+
+		andi	t1, t0, CAUSEF_IP0	# check for IP0
+		bnez	t1, handle_irq
+		li	a0, 0
+
+		andi	t1, t0, CAUSEF_IP1	# check for IP1
+		bnez	t1, handle_irq
+		li	a0, 1
+
+		j	spurious_interrupt
+		nop
+
+handle_int:
+		jal	irq_dispatch
+		move	a1, sp
+		j	ret_from_irq
+		nop
+
+handle_irq:
+		jal	do_IRQ
+		move	a1, sp
+		j	ret_from_irq
+		END(vr41xx_handle_interrupt)
diff --git a/arch/mips/vr41xx/common/pmu.c b/arch/mips/vr41xx/common/pmu.c
new file mode 100644
index 0000000..c5f1043
--- /dev/null
+++ b/arch/mips/vr41xx/common/pmu.c
@@ -0,0 +1,81 @@
+/*
+ *  pmu.c, Power Management Unit routines for NEC VR4100 series.
+ *
+ *  Copyright (C) 2003-2004  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/types.h>
+
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+
+#define PMUCNT2REG	KSEG1ADDR(0x0f0000c6)
+ #define SOFTRST	0x0010
+
+static inline void software_reset(void)
+{
+	uint16_t val;
+
+	switch (current_cpu_data.cputype) {
+	case CPU_VR4122:
+	case CPU_VR4131:
+	case CPU_VR4133:
+		val = readw(PMUCNT2REG);
+		val |= SOFTRST;
+		writew(val, PMUCNT2REG);
+		break;
+	default:
+		break;
+	}
+}
+
+static void vr41xx_restart(char *command)
+{
+	local_irq_disable();
+	software_reset();
+	printk(KERN_NOTICE "\nYou can reset your system\n");
+	while (1) ;
+}
+
+static void vr41xx_halt(void)
+{
+	local_irq_disable();
+	printk(KERN_NOTICE "\nYou can turn off the power supply\n");
+	while (1) ;
+}
+
+static void vr41xx_power_off(void)
+{
+	local_irq_disable();
+	printk(KERN_NOTICE "\nYou can turn off the power supply\n");
+	while (1) ;
+}
+
+static int __init vr41xx_pmu_init(void)
+{
+	_machine_restart = vr41xx_restart;
+	_machine_halt = vr41xx_halt;
+	_machine_power_off = vr41xx_power_off;
+
+	return 0;
+}
+
+early_initcall(vr41xx_pmu_init);
diff --git a/arch/mips/vr41xx/common/vrc4173.c b/arch/mips/vr41xx/common/vrc4173.c
new file mode 100644
index 0000000..5475dd7
--- /dev/null
+++ b/arch/mips/vr41xx/common/vrc4173.c
@@ -0,0 +1,581 @@
+/*
+ *  vrc4173.c, NEC VRC4173 base driver for NEC VR4122/VR4131.
+ *
+ *  Copyright (C) 2001-2003  MontaVista Software Inc.
+ *    Author: Yoichi Yuasa <yyuasa@mvista.com, or source@mvista.com>
+ *  Copyright (C) 2004  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *  Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <asm/vr41xx/vr41xx.h>
+#include <asm/vr41xx/vrc4173.h>
+
+MODULE_DESCRIPTION("NEC VRC4173 base driver for NEC VR4122/4131");
+MODULE_AUTHOR("Yoichi Yuasa <yyuasa@mvista.com>");
+MODULE_LICENSE("GPL");
+
+#define VRC4173_CMUCLKMSK	0x040
+ #define MSKPIU			0x0001
+ #define MSKKIU			0x0002
+ #define MSKAIU			0x0004
+ #define MSKPS2CH1		0x0008
+ #define MSKPS2CH2		0x0010
+ #define MSKUSB			0x0020
+ #define MSKCARD1		0x0040
+ #define MSKCARD2		0x0080
+ #define MSKAC97		0x0100
+ #define MSK48MUSB		0x0400
+ #define MSK48MPIN		0x0800
+ #define MSK48MOSC		0x1000
+#define VRC4173_CMUSRST		0x042
+ #define USBRST			0x0001
+ #define CARD1RST		0x0002
+ #define CARD2RST		0x0004
+ #define AC97RST		0x0008
+
+#define VRC4173_SYSINT1REG	0x060
+#define VRC4173_MSYSINT1REG	0x06c
+#define VRC4173_MPIUINTREG	0x06e
+#define VRC4173_MAIUINTREG	0x070
+#define VRC4173_MKIUINTREG	0x072
+
+#define VRC4173_SELECTREG	0x09e
+ #define SEL3			0x0008
+ #define SEL2			0x0004
+ #define SEL1			0x0002
+ #define SEL0			0x0001
+
+static struct pci_device_id vrc4173_id_table[] __devinitdata = {
+	{	.vendor		= PCI_VENDOR_ID_NEC,
+		.device		= PCI_DEVICE_ID_NEC_VRC4173,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,			},
+	{	.vendor		= 0,				},
+};
+
+unsigned long vrc4173_io_offset = 0;
+
+EXPORT_SYMBOL(vrc4173_io_offset);
+
+static int vrc4173_initialized;
+static uint16_t vrc4173_cmuclkmsk;
+static uint16_t vrc4173_selectreg;
+static spinlock_t vrc4173_cmu_lock;
+static spinlock_t vrc4173_giu_lock;
+
+static inline void set_cmusrst(uint16_t val)
+{
+	uint16_t cmusrst;
+
+	cmusrst = vrc4173_inw(VRC4173_CMUSRST);
+	cmusrst |= val;
+	vrc4173_outw(cmusrst, VRC4173_CMUSRST);
+}
+
+static inline void clear_cmusrst(uint16_t val)
+{
+	uint16_t cmusrst;
+
+	cmusrst = vrc4173_inw(VRC4173_CMUSRST);
+	cmusrst &= ~val;
+	vrc4173_outw(cmusrst, VRC4173_CMUSRST);
+}
+
+void vrc4173_supply_clock(vrc4173_clock_t clock)
+{
+	if (vrc4173_initialized) {
+		spin_lock_irq(&vrc4173_cmu_lock);
+
+		switch (clock) {
+		case VRC4173_PIU_CLOCK:
+			vrc4173_cmuclkmsk |= MSKPIU;
+			break;
+		case VRC4173_KIU_CLOCK:
+			vrc4173_cmuclkmsk |= MSKKIU;
+			break;
+		case VRC4173_AIU_CLOCK:
+			vrc4173_cmuclkmsk |= MSKAIU;
+			break;
+		case VRC4173_PS2_CH1_CLOCK:
+			vrc4173_cmuclkmsk |= MSKPS2CH1;
+			break;
+		case VRC4173_PS2_CH2_CLOCK:
+			vrc4173_cmuclkmsk |= MSKPS2CH2;
+			break;
+		case VRC4173_USBU_PCI_CLOCK:
+			set_cmusrst(USBRST);
+			vrc4173_cmuclkmsk |= MSKUSB;
+			break;
+		case VRC4173_CARDU1_PCI_CLOCK:
+			set_cmusrst(CARD1RST);
+			vrc4173_cmuclkmsk |= MSKCARD1;
+			break;
+		case VRC4173_CARDU2_PCI_CLOCK:
+			set_cmusrst(CARD2RST);
+			vrc4173_cmuclkmsk |= MSKCARD2;
+			break;
+		case VRC4173_AC97U_PCI_CLOCK:
+			set_cmusrst(AC97RST);
+			vrc4173_cmuclkmsk |= MSKAC97;
+			break;
+		case VRC4173_USBU_48MHz_CLOCK:
+			set_cmusrst(USBRST);
+			vrc4173_cmuclkmsk |= MSK48MUSB;
+			break;
+		case VRC4173_EXT_48MHz_CLOCK:
+			if (vrc4173_cmuclkmsk & MSK48MOSC)
+				vrc4173_cmuclkmsk |= MSK48MPIN;
+			else
+				printk(KERN_WARNING
+				       "vrc4173_supply_clock: "
+				       "Please supply VRC4173_48MHz_CLOCK first "
+				       "rather than VRC4173_EXT_48MHz_CLOCK.\n");
+			break;
+		case VRC4173_48MHz_CLOCK:
+			vrc4173_cmuclkmsk |= MSK48MOSC;
+			break;
+		default:
+			printk(KERN_WARNING
+			       "vrc4173_supply_clock: Invalid CLOCK value %u\n", clock);
+			break;
+		}
+
+		vrc4173_outw(vrc4173_cmuclkmsk, VRC4173_CMUCLKMSK);
+
+		switch (clock) {
+		case VRC4173_USBU_PCI_CLOCK:
+		case VRC4173_USBU_48MHz_CLOCK:
+			clear_cmusrst(USBRST);
+			break;
+		case VRC4173_CARDU1_PCI_CLOCK:
+			clear_cmusrst(CARD1RST);
+			break;
+		case VRC4173_CARDU2_PCI_CLOCK:
+			clear_cmusrst(CARD2RST);
+			break;
+		case VRC4173_AC97U_PCI_CLOCK:
+			clear_cmusrst(AC97RST);
+			break;
+		default:
+			break;
+		}
+
+		spin_unlock_irq(&vrc4173_cmu_lock);
+	}
+}
+
+EXPORT_SYMBOL(vrc4173_supply_clock);
+
+void vrc4173_mask_clock(vrc4173_clock_t clock)
+{
+	if (vrc4173_initialized) {
+		spin_lock_irq(&vrc4173_cmu_lock);
+
+		switch (clock) {
+		case VRC4173_PIU_CLOCK:
+			vrc4173_cmuclkmsk &= ~MSKPIU;
+			break;
+		case VRC4173_KIU_CLOCK:
+			vrc4173_cmuclkmsk &= ~MSKKIU;
+			break;
+		case VRC4173_AIU_CLOCK:
+			vrc4173_cmuclkmsk &= ~MSKAIU;
+			break;
+		case VRC4173_PS2_CH1_CLOCK:
+			vrc4173_cmuclkmsk &= ~MSKPS2CH1;
+			break;
+		case VRC4173_PS2_CH2_CLOCK:
+			vrc4173_cmuclkmsk &= ~MSKPS2CH2;
+			break;
+		case VRC4173_USBU_PCI_CLOCK:
+			set_cmusrst(USBRST);
+			vrc4173_cmuclkmsk &= ~MSKUSB;
+			break;
+		case VRC4173_CARDU1_PCI_CLOCK:
+			set_cmusrst(CARD1RST);
+			vrc4173_cmuclkmsk &= ~MSKCARD1;
+			break;
+		case VRC4173_CARDU2_PCI_CLOCK:
+			set_cmusrst(CARD2RST);
+			vrc4173_cmuclkmsk &= ~MSKCARD2;
+			break;
+		case VRC4173_AC97U_PCI_CLOCK:
+			set_cmusrst(AC97RST);
+			vrc4173_cmuclkmsk &= ~MSKAC97;
+			break;
+		case VRC4173_USBU_48MHz_CLOCK:
+			set_cmusrst(USBRST);
+			vrc4173_cmuclkmsk &= ~MSK48MUSB;
+			break;
+		case VRC4173_EXT_48MHz_CLOCK:
+			vrc4173_cmuclkmsk &= ~MSK48MPIN;
+			break;
+		case VRC4173_48MHz_CLOCK:
+			vrc4173_cmuclkmsk &= ~MSK48MOSC;
+			break;
+		default:
+			printk(KERN_WARNING "vrc4173_mask_clock: Invalid CLOCK value %u\n", clock);
+			break;
+		}
+
+		vrc4173_outw(vrc4173_cmuclkmsk, VRC4173_CMUCLKMSK);
+
+		switch (clock) {
+		case VRC4173_USBU_PCI_CLOCK:
+		case VRC4173_USBU_48MHz_CLOCK:
+			clear_cmusrst(USBRST);
+			break;
+		case VRC4173_CARDU1_PCI_CLOCK:
+			clear_cmusrst(CARD1RST);
+			break;
+		case VRC4173_CARDU2_PCI_CLOCK:
+			clear_cmusrst(CARD2RST);
+			break;
+		case VRC4173_AC97U_PCI_CLOCK:
+			clear_cmusrst(AC97RST);
+			break;
+		default:
+			break;
+		}
+
+		spin_unlock_irq(&vrc4173_cmu_lock);
+	}
+}
+
+EXPORT_SYMBOL(vrc4173_mask_clock);
+
+static inline void vrc4173_cmu_init(void)
+{
+	vrc4173_cmuclkmsk = vrc4173_inw(VRC4173_CMUCLKMSK);
+
+	spin_lock_init(&vrc4173_cmu_lock);
+}
+
+void vrc4173_select_function(vrc4173_function_t function)
+{
+	if (vrc4173_initialized) {
+		spin_lock_irq(&vrc4173_giu_lock);
+
+		switch(function) {
+		case PS2_CHANNEL1:
+			vrc4173_selectreg |= SEL2;
+			break;
+		case PS2_CHANNEL2:
+			vrc4173_selectreg |= SEL1;
+			break;
+		case TOUCHPANEL:
+			vrc4173_selectreg &= SEL2 | SEL1 | SEL0;
+			break;
+		case KEYBOARD_8SCANLINES:
+			vrc4173_selectreg &= SEL3 | SEL2 | SEL1;
+			break;
+		case KEYBOARD_10SCANLINES:
+			vrc4173_selectreg &= SEL3 | SEL2;
+			break;
+		case KEYBOARD_12SCANLINES:
+			vrc4173_selectreg &= SEL3;
+			break;
+		case GPIO_0_15PINS:
+			vrc4173_selectreg |= SEL0;
+			break;
+		case GPIO_16_20PINS:
+			vrc4173_selectreg |= SEL3;
+			break;
+		}
+
+		vrc4173_outw(vrc4173_selectreg, VRC4173_SELECTREG);
+
+		spin_unlock_irq(&vrc4173_giu_lock);
+	}
+}
+
+EXPORT_SYMBOL(vrc4173_select_function);
+
+static inline void vrc4173_giu_init(void)
+{
+	vrc4173_selectreg = vrc4173_inw(VRC4173_SELECTREG);
+
+	spin_lock_init(&vrc4173_giu_lock);
+}
+
+void vrc4173_enable_piuint(uint16_t mask)
+{
+	irq_desc_t *desc = irq_desc + VRC4173_PIU_IRQ;
+	unsigned long flags;
+	uint16_t val;
+
+	spin_lock_irqsave(&desc->lock, flags);
+	val = vrc4173_inw(VRC4173_MPIUINTREG);
+	val |= mask;
+	vrc4173_outw(val, VRC4173_MPIUINTREG);
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+EXPORT_SYMBOL(vrc4173_enable_piuint);
+
+void vrc4173_disable_piuint(uint16_t mask)
+{
+	irq_desc_t *desc = irq_desc + VRC4173_PIU_IRQ;
+	unsigned long flags;
+	uint16_t val;
+
+	spin_lock_irqsave(&desc->lock, flags);
+	val = vrc4173_inw(VRC4173_MPIUINTREG);
+	val &= ~mask;
+	vrc4173_outw(val, VRC4173_MPIUINTREG);
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+EXPORT_SYMBOL(vrc4173_disable_piuint);
+
+void vrc4173_enable_aiuint(uint16_t mask)
+{
+	irq_desc_t *desc = irq_desc + VRC4173_AIU_IRQ;
+	unsigned long flags;
+	uint16_t val;
+
+	spin_lock_irqsave(&desc->lock, flags);
+	val = vrc4173_inw(VRC4173_MAIUINTREG);
+	val |= mask;
+	vrc4173_outw(val, VRC4173_MAIUINTREG);
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+EXPORT_SYMBOL(vrc4173_enable_aiuint);
+
+void vrc4173_disable_aiuint(uint16_t mask)
+{
+	irq_desc_t *desc = irq_desc + VRC4173_AIU_IRQ;
+	unsigned long flags;
+	uint16_t val;
+
+	spin_lock_irqsave(&desc->lock, flags);
+	val = vrc4173_inw(VRC4173_MAIUINTREG);
+	val &= ~mask;
+	vrc4173_outw(val, VRC4173_MAIUINTREG);
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+EXPORT_SYMBOL(vrc4173_disable_aiuint);
+
+void vrc4173_enable_kiuint(uint16_t mask)
+{
+	irq_desc_t *desc = irq_desc + VRC4173_KIU_IRQ;
+	unsigned long flags;
+	uint16_t val;
+
+	spin_lock_irqsave(&desc->lock, flags);
+	val = vrc4173_inw(VRC4173_MKIUINTREG);
+	val |= mask;
+	vrc4173_outw(val, VRC4173_MKIUINTREG);
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+EXPORT_SYMBOL(vrc4173_enable_kiuint);
+
+void vrc4173_disable_kiuint(uint16_t mask)
+{
+	irq_desc_t *desc = irq_desc + VRC4173_KIU_IRQ;
+	unsigned long flags;
+	uint16_t val;
+
+	spin_lock_irqsave(&desc->lock, flags);
+	val = vrc4173_inw(VRC4173_MKIUINTREG);
+	val &= ~mask;
+	vrc4173_outw(val, VRC4173_MKIUINTREG);
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+EXPORT_SYMBOL(vrc4173_disable_kiuint);
+
+static void enable_vrc4173_irq(unsigned int irq)
+{
+	uint16_t val;
+
+	val = vrc4173_inw(VRC4173_MSYSINT1REG);
+	val |= (uint16_t)1 << (irq - VRC4173_IRQ_BASE);
+	vrc4173_outw(val, VRC4173_MSYSINT1REG);
+}
+
+static void disable_vrc4173_irq(unsigned int irq)
+{
+	uint16_t val;
+
+	val = vrc4173_inw(VRC4173_MSYSINT1REG);
+	val &= ~((uint16_t)1 << (irq - VRC4173_IRQ_BASE));
+	vrc4173_outw(val, VRC4173_MSYSINT1REG);
+}
+
+static unsigned int startup_vrc4173_irq(unsigned int irq)
+{
+	enable_vrc4173_irq(irq);
+	return 0; /* never anything pending */
+}
+
+#define shutdown_vrc4173_irq	disable_vrc4173_irq
+#define ack_vrc4173_irq		disable_vrc4173_irq
+
+static void end_vrc4173_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		enable_vrc4173_irq(irq);
+}
+
+static struct hw_interrupt_type vrc4173_irq_type = {
+	.typename	= "VRC4173",
+	.startup	= startup_vrc4173_irq,
+	.shutdown	= shutdown_vrc4173_irq,
+	.enable		= enable_vrc4173_irq,
+	.disable	= disable_vrc4173_irq,
+	.ack		= ack_vrc4173_irq,
+	.end		= end_vrc4173_irq,
+};
+
+static int vrc4173_get_irq_number(int irq)
+{
+	uint16_t status, mask;
+	int i;
+
+        status = vrc4173_inw(VRC4173_SYSINT1REG);
+        mask = vrc4173_inw(VRC4173_MSYSINT1REG);
+
+	status &= mask;
+	if (status) {
+		for (i = 0; i < 16; i++)
+			if (status & (0x0001 << i))
+				return VRC4173_IRQ(i);
+	}
+
+	return -EINVAL;
+}
+
+static inline int vrc4173_icu_init(int cascade_irq)
+{
+	int i;
+
+	if (cascade_irq < GIU_IRQ(0) || cascade_irq > GIU_IRQ(15))
+		return -EINVAL;
+	
+	vrc4173_outw(0, VRC4173_MSYSINT1REG);
+
+	vr41xx_set_irq_trigger(GIU_IRQ_TO_PIN(cascade_irq), TRIGGER_LEVEL, SIGNAL_THROUGH);
+	vr41xx_set_irq_level(GIU_IRQ_TO_PIN(cascade_irq), LEVEL_LOW);
+
+	for (i = VRC4173_IRQ_BASE; i <= VRC4173_IRQ_LAST; i++)
+                irq_desc[i].handler = &vrc4173_irq_type;
+
+	return 0;
+}
+
+static int __devinit vrc4173_probe(struct pci_dev *dev,
+                                   const struct pci_device_id *id)
+{
+	unsigned long start, flags;
+	int err;
+
+	err = pci_enable_device(dev);
+	if (err < 0) {
+		printk(KERN_ERR "vrc4173: Failed to enable PCI device, aborting\n");
+		return err;
+	}
+
+	pci_set_master(dev);
+
+	start = pci_resource_start(dev, 0);
+	if (start == 0) {
+		printk(KERN_ERR "vrc4173:No such PCI I/O resource, aborting\n");
+		return -ENXIO;
+	}
+
+	flags = pci_resource_flags(dev, 0);
+	if ((flags & IORESOURCE_IO) == 0) {
+		printk(KERN_ERR "vrc4173: No such PCI I/O resource, aborting\n");
+		return -ENXIO;
+	}
+
+	err = pci_request_regions(dev, "NEC VRC4173");
+	if (err < 0) {
+		printk(KERN_ERR "vrc4173: PCI resources are busy, aborting\n");
+		return err;
+	}
+
+	set_vrc4173_io_offset(start);
+
+	vrc4173_cmu_init();
+	vrc4173_giu_init();
+
+	err = vrc4173_icu_init(dev->irq);
+	if (err < 0) {
+		printk(KERN_ERR "vrc4173: Invalid IRQ %d, aborting\n", dev->irq);
+		return err;
+	}
+
+	err = vr41xx_cascade_irq(dev->irq, vrc4173_get_irq_number);
+	if (err < 0) {
+		printk(KERN_ERR "vrc4173: IRQ resource %d is busy, aborting\n", dev->irq);
+		return err;
+	}
+
+	printk(KERN_INFO
+	       "NEC VRC4173 at 0x%#08lx, IRQ is cascaded to %d\n", start, dev->irq);
+
+	return 0;
+}
+
+static void vrc4173_remove(struct pci_dev *dev)
+{
+	free_irq(dev->irq, NULL);
+
+	pci_release_regions(dev);
+}
+
+static struct pci_driver vrc4173_driver = {
+	.name		= "NEC VRC4173",
+	.probe		= vrc4173_probe,
+	.remove		= vrc4173_remove,
+	.id_table	= vrc4173_id_table,
+};
+
+static int __devinit vrc4173_init(void)
+{
+	int err;
+
+	err = pci_module_init(&vrc4173_driver);
+	if (err < 0)
+		return err;
+
+	vrc4173_initialized = 1;
+
+	return 0;
+}
+
+static void __devexit vrc4173_exit(void)
+{
+	vrc4173_initialized = 0;
+
+	pci_unregister_driver(&vrc4173_driver);
+}
+
+module_init(vrc4173_init);
+module_exit(vrc4173_exit);
diff --git a/arch/mips/vr41xx/ibm-workpad/Makefile b/arch/mips/vr41xx/ibm-workpad/Makefile
new file mode 100644
index 0000000..5ffaff0
--- /dev/null
+++ b/arch/mips/vr41xx/ibm-workpad/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the IBM WorkPad z50 specific parts of the kernel
+#
+
+obj-y			+= setup.o
diff --git a/arch/mips/vr41xx/ibm-workpad/setup.c b/arch/mips/vr41xx/ibm-workpad/setup.c
new file mode 100644
index 0000000..cff4460
--- /dev/null
+++ b/arch/mips/vr41xx/ibm-workpad/setup.c
@@ -0,0 +1,40 @@
+/*
+ *  setup.c, Setup for the IBM WorkPad z50.
+ *
+ *  Copyright (C) 2002-2005  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/init.h>
+#include <linux/ioport.h>
+
+#include <asm/io.h>
+#include <asm/vr41xx/workpad.h>
+
+const char *get_system_type(void)
+{
+	return "IBM WorkPad z50";
+}
+
+static int __init ibm_workpad_setup(void)
+{
+	set_io_port_base(IO_PORT_BASE);
+	ioport_resource.start = IO_PORT_RESOURCE_START;
+	ioport_resource.end = IO_PORT_RESOURCE_END;
+
+	return 0;
+}
+
+arch_initcall(ibm_workpad_setup);
diff --git a/arch/mips/vr41xx/nec-cmbvr4133/Makefile b/arch/mips/vr41xx/nec-cmbvr4133/Makefile
new file mode 100644
index 0000000..5835cae
--- /dev/null
+++ b/arch/mips/vr41xx/nec-cmbvr4133/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the NEC-CMBVR4133
+#
+
+obj-y				:= init.o setup.o
+
+obj-$(CONFIG_PCI)		+= m1535plus.o
+obj-$(CONFIG_ROCKHOPPER)	+= irq.o
diff --git a/arch/mips/vr41xx/nec-cmbvr4133/init.c b/arch/mips/vr41xx/nec-cmbvr4133/init.c
new file mode 100644
index 0000000..87f06b3
--- /dev/null
+++ b/arch/mips/vr41xx/nec-cmbvr4133/init.c
@@ -0,0 +1,78 @@
+/*
+ * arch/mips/vr41xx/nec-cmbvr4133/init.c
+ *
+ * PROM library initialisation code for NEC CMB-VR4133 board.
+ *
+ * Author: Yoichi Yuasa <yyuasa@mvista.com, or source@mvista.com> and
+ *         Jun Sun <jsun@mvista.com, or source@mvista.com> and
+ *         Alex Sapkov <asapkov@ru.mvista.com>
+ *
+ * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for NEC-CMBVR4133 in 2.6
+ * Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+
+#ifdef CONFIG_ROCKHOPPER
+#include <asm/io.h>
+#include <linux/pci.h>
+
+#define PCICONFDREG	0xaf000c14
+#define PCICONFAREG	0xaf000c18
+#endif
+
+const char *get_system_type(void)
+{
+	return "NEC CMB-VR4133";
+}
+
+#ifdef CONFIG_ROCKHOPPER
+void disable_pcnet(void)
+{
+	u32 data;
+
+	/*
+	 * Workaround for the bug in PMON on VR4133. PMON leaves
+	 * AMD PCNet controller (on Rockhopper) initialized and running in
+	 * bus master mode. We have do disable it before doing any
+	 * further initialization. Or we get problems with PCI bus 2
+	 * and random lockups and crashes.
+	 */
+
+	writel((2 << 16)		|
+	       (PCI_DEVFN(1,0) << 8)	|
+	       (0 & 0xfc)		|
+               1UL,
+	       PCICONFAREG);
+
+	data = readl(PCICONFDREG);
+
+	writel((2 << 16)		|
+	       (PCI_DEVFN(1,0) << 8)	|
+	       (4 & 0xfc)		|
+               1UL,
+	       PCICONFAREG);
+
+	data = readl(PCICONFDREG);
+
+	writel((2 << 16)		|
+	       (PCI_DEVFN(1,0) << 8)	|
+	       (4 & 0xfc)		|
+               1UL,
+	       PCICONFAREG);
+
+	data &= ~4;
+
+	writel(data, PCICONFDREG);
+}
+#endif
+
diff --git a/arch/mips/vr41xx/nec-cmbvr4133/irq.c b/arch/mips/vr41xx/nec-cmbvr4133/irq.c
new file mode 100644
index 0000000..31db6b6
--- /dev/null
+++ b/arch/mips/vr41xx/nec-cmbvr4133/irq.c
@@ -0,0 +1,114 @@
+/*
+ * arch/mips/vr41xx/nec-cmbvr4133/irq.c
+ *
+ * Interrupt routines for the NEC CMB-VR4133 board.
+ *
+ * Author: Yoichi Yuasa <yyuasa@mvista.com, or source@mvista.com> and
+ *         Alex Sapkov <asapkov@ru.mvista.com>
+ *
+ * 2003-2004 (c) MontaVista, Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for NEC-CMBVR4133 in 2.6
+ * Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/bitops.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+
+#include <asm/io.h>
+#include <asm/vr41xx/cmbvr4133.h>
+
+extern void enable_8259A_irq(unsigned int irq);
+extern void disable_8259A_irq(unsigned int irq);
+extern void mask_and_ack_8259A(unsigned int irq);
+extern void init_8259A(int hoge);
+
+extern int vr4133_rockhopper;
+
+static unsigned int startup_i8259_irq(unsigned int irq)
+{
+	enable_8259A_irq(irq - I8259_IRQ_BASE);
+	return 0;
+}
+
+static void shutdown_i8259_irq(unsigned int irq)
+{
+	disable_8259A_irq(irq - I8259_IRQ_BASE);
+}
+
+static void enable_i8259_irq(unsigned int irq)
+{
+	enable_8259A_irq(irq - I8259_IRQ_BASE);
+}
+
+static void disable_i8259_irq(unsigned int irq)
+{
+	disable_8259A_irq(irq - I8259_IRQ_BASE);
+}
+
+static void ack_i8259_irq(unsigned int irq)
+{
+	mask_and_ack_8259A(irq - I8259_IRQ_BASE);
+}
+
+static void end_i8259_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_8259A_irq(irq - I8259_IRQ_BASE);
+}
+
+static struct hw_interrupt_type i8259_irq_type = {
+	.typename       = "XT-PIC",
+	.startup        = startup_i8259_irq,
+	.shutdown       = shutdown_i8259_irq,
+	.enable         = enable_i8259_irq,
+	.disable        = disable_i8259_irq,
+	.ack            = ack_i8259_irq,
+	.end            = end_i8259_irq,
+};
+
+static int i8259_get_irq_number(int irq)
+{
+	unsigned long isr;
+
+	isr = inb(0x20);
+	irq = ffz(~isr);
+	if (irq == 2) {
+		isr = inb(0xa0);
+		irq = 8 + ffz(~isr);
+	}
+
+	if (irq < 0 || irq > 15)
+		return -EINVAL;
+
+	return I8259_IRQ_BASE + irq;
+}
+
+static struct irqaction i8259_slave_cascade = {
+	.handler        = &no_action,
+	.name           = "cascade",
+};
+
+void __init rockhopper_init_irq(void)
+{
+	int i;
+
+	if(!vr4133_rockhopper) {
+		printk(KERN_ERR "Not a Rockhopper Board \n");
+		return;
+	}
+
+	for (i = I8259_IRQ_BASE; i <= I8259_IRQ_LAST; i++)
+		irq_desc[i].handler = &i8259_irq_type;
+
+	setup_irq(I8259_SLAVE_IRQ, &i8259_slave_cascade);
+
+	vr41xx_set_irq_trigger(CMBVR41XX_INTC_PIN, TRIGGER_LEVEL, SIGNAL_THROUGH);
+	vr41xx_set_irq_level(CMBVR41XX_INTC_PIN, LEVEL_HIGH);
+	vr41xx_cascade_irq(CMBVR41XX_INTC_IRQ, i8259_get_irq_number);
+}
diff --git a/arch/mips/vr41xx/nec-cmbvr4133/m1535plus.c b/arch/mips/vr41xx/nec-cmbvr4133/m1535plus.c
new file mode 100644
index 0000000..1f6b24e
--- /dev/null
+++ b/arch/mips/vr41xx/nec-cmbvr4133/m1535plus.c
@@ -0,0 +1,250 @@
+/*
+ * arch/mips/vr41xx/nec-cmbvr4133/m1535plus.c
+ *
+ * Initialize for ALi M1535+(included M5229 and M5237).
+ *
+ * Author: Yoichi Yuasa <yyuasa@mvista.com, or source@mvista.com> and
+ *         Alex Sapkov <asapkov@ru.mvista.com>
+ *
+ * 2003-2004 (c) MontaVista, Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for NEC-CMBVR4133 in 2.6
+ * Author: Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/serial.h>
+
+#include <asm/vr41xx/cmbvr4133.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+#define CONFIG_PORT(port)	((port) ? 0x3f0 : 0x370)
+#define DATA_PORT(port)		((port) ? 0x3f1 : 0x371)
+#define INDEX_PORT(port)	CONFIG_PORT(port)
+
+#define ENTER_CONFIG_MODE(port)				\
+	do {						\
+		outb_p(0x51, CONFIG_PORT(port));	\
+		outb_p(0x23, CONFIG_PORT(port));	\
+	} while(0)
+
+#define SELECT_LOGICAL_DEVICE(port, dev_no)		\
+	do {						\
+		outb_p(0x07, INDEX_PORT(port));		\
+		outb_p((dev_no), DATA_PORT(port));	\
+	} while(0)
+
+#define WRITE_CONFIG_DATA(port,index,data)		\
+	do {						\
+		outb_p((index), INDEX_PORT(port));	\
+		outb_p((data), DATA_PORT(port));	\
+	} while(0)
+
+#define EXIT_CONFIG_MODE(port)	outb(0xbb, CONFIG_PORT(port))
+
+#define PCI_CONFIG_ADDR	KSEG1ADDR(0x0f000c18)
+#define PCI_CONFIG_DATA	KSEG1ADDR(0x0f000c14)
+
+#ifdef CONFIG_BLK_DEV_FD
+
+void __devinit ali_m1535plus_fdc_init(int port)
+{
+	ENTER_CONFIG_MODE(port);
+	SELECT_LOGICAL_DEVICE(port, 0);		/* FDC */
+	WRITE_CONFIG_DATA(port, 0x30, 0x01);	/* FDC: enable */
+	WRITE_CONFIG_DATA(port, 0x60, 0x03);	/* I/O port base: 0x3f0 */
+	WRITE_CONFIG_DATA(port, 0x61, 0xf0);
+	WRITE_CONFIG_DATA(port, 0x70, 0x06);	/* IRQ: 6 */
+	WRITE_CONFIG_DATA(port, 0x74, 0x02);	/* DMA: channel 2 */
+	WRITE_CONFIG_DATA(port, 0xf0, 0x08);
+	WRITE_CONFIG_DATA(port, 0xf1, 0x00);
+	WRITE_CONFIG_DATA(port, 0xf2, 0xff);
+	WRITE_CONFIG_DATA(port, 0xf4, 0x00);
+	EXIT_CONFIG_MODE(port);
+}
+
+#endif
+
+void __devinit ali_m1535plus_parport_init(int port)
+{
+	ENTER_CONFIG_MODE(port);
+	SELECT_LOGICAL_DEVICE(port, 3);		/* Parallel Port */
+	WRITE_CONFIG_DATA(port, 0x30, 0x01);
+	WRITE_CONFIG_DATA(port, 0x60, 0x03);	/* I/O port base: 0x378 */
+	WRITE_CONFIG_DATA(port, 0x61, 0x78);
+	WRITE_CONFIG_DATA(port, 0x70, 0x07);	/* IRQ: 7 */
+	WRITE_CONFIG_DATA(port, 0x74, 0x04);	/* DMA: None */
+	WRITE_CONFIG_DATA(port, 0xf0, 0x8c);	/* IRQ polarity: Active Low */
+	WRITE_CONFIG_DATA(port, 0xf1, 0xc5);
+	EXIT_CONFIG_MODE(port);
+}
+
+void __devinit ali_m1535plus_keyboard_init(int port)
+{
+	ENTER_CONFIG_MODE(port);
+	SELECT_LOGICAL_DEVICE(port, 7);		/* KEYBOARD */
+	WRITE_CONFIG_DATA(port, 0x30, 0x01);	/* KEYBOARD: eable */
+	WRITE_CONFIG_DATA(port, 0x70, 0x01);	/* IRQ: 1 */
+	WRITE_CONFIG_DATA(port, 0x72, 0x0c);	/* PS/2 Mouse IRQ: 12 */
+	WRITE_CONFIG_DATA(port, 0xf0, 0x00);
+	EXIT_CONFIG_MODE(port);
+}
+
+void __devinit ali_m1535plus_hotkey_init(int port)
+{
+	ENTER_CONFIG_MODE(port);
+	SELECT_LOGICAL_DEVICE(port, 0xc);	/* HOTKEY */
+	WRITE_CONFIG_DATA(port, 0x30, 0x00);
+	WRITE_CONFIG_DATA(port, 0xf0, 0x35);
+	WRITE_CONFIG_DATA(port, 0xf1, 0x14);
+	WRITE_CONFIG_DATA(port, 0xf2, 0x11);
+	WRITE_CONFIG_DATA(port, 0xf3, 0x71);
+	WRITE_CONFIG_DATA(port, 0xf5, 0x05);
+	EXIT_CONFIG_MODE(port);
+}
+
+void ali_m1535plus_init(struct pci_dev *dev)
+{
+	pci_write_config_byte(dev, 0x40, 0x18); /* PCI Interface Control */
+	pci_write_config_byte(dev, 0x41, 0xc0); /* PS2 keyb & mouse enable */
+	pci_write_config_byte(dev, 0x42, 0x41); /* ISA bus cycle control */
+	pci_write_config_byte(dev, 0x43, 0x00); /* ISA bus cycle control 2 */
+	pci_write_config_byte(dev, 0x44, 0x5d); /* IDE enable & IRQ 14 */
+	pci_write_config_byte(dev, 0x45, 0x0b); /* PCI int polling mode */
+	pci_write_config_byte(dev, 0x47, 0x00); /* BIOS chip select control */
+
+	/* IRQ routing */
+	pci_write_config_byte(dev, 0x48, 0x03); /* INTA IRQ10, INTB disable */
+	pci_write_config_byte(dev, 0x49, 0x00); /* INTC and INTD disable */
+	pci_write_config_byte(dev, 0x4a, 0x00); /* INTE and INTF disable */
+	pci_write_config_byte(dev, 0x4b, 0x90); /* Audio IRQ11, Modem disable */
+
+	pci_write_config_word(dev, 0x50, 0x4000); /* Parity check IDE enable */
+	pci_write_config_word(dev, 0x52, 0x0000); /* USB & RTC disable */
+	pci_write_config_word(dev, 0x54, 0x0002); /* ??? no info */
+	pci_write_config_word(dev, 0x56, 0x0002); /* PCS1J signal disable */
+
+	pci_write_config_byte(dev, 0x59, 0x00); /* PCSDS */
+	pci_write_config_byte(dev, 0x5a, 0x00);
+	pci_write_config_byte(dev, 0x5b, 0x00);
+	pci_write_config_word(dev, 0x5c, 0x0000);
+	pci_write_config_byte(dev, 0x5e, 0x00);
+	pci_write_config_byte(dev, 0x5f, 0x00);
+	pci_write_config_word(dev, 0x60, 0x0000);
+
+	pci_write_config_byte(dev, 0x6c, 0x00);
+	pci_write_config_byte(dev, 0x6d, 0x48); /* ROM address mapping */
+	pci_write_config_byte(dev, 0x6e, 0x00); /* ??? what for? */
+
+	pci_write_config_byte(dev, 0x70, 0x12); /* Serial IRQ control */
+	pci_write_config_byte(dev, 0x71, 0xEF); /* DMA channel select */
+	pci_write_config_byte(dev, 0x72, 0x03); /* USB IDSEL */
+	pci_write_config_byte(dev, 0x73, 0x00); /* ??? no info */
+
+	/*
+	 * IRQ setup ALi M5237 USB Host Controller
+	 * IRQ: 9
+	 */
+	pci_write_config_byte(dev, 0x74, 0x01); /* USB IRQ9 */
+
+	pci_write_config_byte(dev, 0x75, 0x1f); /* IDE2 IRQ 15  */
+	pci_write_config_byte(dev, 0x76, 0x80); /* ACPI disable */
+	pci_write_config_byte(dev, 0x77, 0x40); /* Modem disable */
+	pci_write_config_dword(dev, 0x78, 0x20000000); /* Pin select 2 */
+	pci_write_config_byte(dev, 0x7c, 0x00); /* Pin select 3 */
+	pci_write_config_byte(dev, 0x81, 0x00); /* ID read/write control */
+	pci_write_config_byte(dev, 0x90, 0x00); /* PCI PM block control */
+	pci_write_config_word(dev, 0xa4, 0x0000); /* PMSCR */
+
+#ifdef CONFIG_BLK_DEV_FD
+	ali_m1535plus_fdc_init(1);
+#endif
+
+	ali_m1535plus_keyboard_init(1);
+	ali_m1535plus_hotkey_init(1);
+}
+
+static inline void ali_config_writeb(u8 reg, u8 val, int devfn)
+{
+	u32 data;
+	int shift;
+
+	writel((1 << 16) | (devfn << 8) | (reg & 0xfc) | 1UL, PCI_CONFIG_ADDR);
+        data = readl(PCI_CONFIG_DATA);
+
+	shift = (reg & 3) << 3;
+	data &= ~(0xff << shift);
+	data |= (((u32)val) << shift);
+
+	writel(data, PCI_CONFIG_DATA);
+}
+
+static inline u8 ali_config_readb(u8 reg, int devfn)
+{
+	u32 data;
+
+	writel((1 << 16) | (devfn << 8) | (reg & 0xfc) | 1UL, PCI_CONFIG_ADDR);
+	data = readl(PCI_CONFIG_DATA);
+
+	return (u8)(data >> ((reg & 3) << 3));
+}
+
+static inline u16 ali_config_readw(u8 reg, int devfn)
+{
+	u32 data;
+
+	writel((1 << 16) | (devfn << 8) | (reg & 0xfc) | 1UL, PCI_CONFIG_ADDR);
+	data = readl(PCI_CONFIG_DATA);
+
+	return (u16)(data >> ((reg & 2) << 3));
+}
+
+int vr4133_rockhopper = 0;
+void __init ali_m5229_preinit(void)
+{
+	if (ali_config_readw(PCI_VENDOR_ID,16) == PCI_VENDOR_ID_AL &&
+	    ali_config_readw(PCI_DEVICE_ID,16) == PCI_DEVICE_ID_AL_M1533) {
+		printk(KERN_INFO "Found an NEC Rockhopper \n");
+		vr4133_rockhopper = 1;
+		/*
+		 * Enable ALi M5229 IDE Controller (both channels)
+		 * IDSEL: A27
+		 */
+		ali_config_writeb(0x58, 0x4c, 16);
+	}
+}
+
+void __init ali_m5229_init(struct pci_dev *dev)
+{
+	/*
+	 * Enable Primary/Secondary Channel Cable Detect 40-Pin
+	 */
+	pci_write_config_word(dev, 0x4a, 0xc023);
+
+	/*
+	 * Set only the 3rd byteis for the master IDE's cycle and
+	 * enable Internal IDE Function
+	 */
+	pci_write_config_byte(dev, 0x50, 0x23); /* Class code attr register */
+
+	pci_write_config_byte(dev, 0x09, 0xff); /* Set native mode & stuff */
+	pci_write_config_byte(dev, 0x52, 0x00); /* use timing registers */
+	pci_write_config_byte(dev, 0x58, 0x02); /* Primary addr setup timing */
+	pci_write_config_byte(dev, 0x59, 0x22); /* Primary cmd block timing */
+	pci_write_config_byte(dev, 0x5a, 0x22); /* Pr drv 0 R/W timing */
+	pci_write_config_byte(dev, 0x5b, 0x22); /* Pr drv 1 R/W timing */
+	pci_write_config_byte(dev, 0x5c, 0x02); /* Sec addr setup timing */
+	pci_write_config_byte(dev, 0x5d, 0x22); /* Sec cmd block timing */
+	pci_write_config_byte(dev, 0x5e, 0x22); /* Sec drv 0 R/W timing */
+	pci_write_config_byte(dev, 0x5f, 0x22); /* Sec drv 1 R/W timing */
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
+	pci_write_config_word(dev, PCI_COMMAND,
+	                           PCI_COMMAND_PARITY | PCI_COMMAND_MASTER |
+				   PCI_COMMAND_IO);
+}
+
diff --git a/arch/mips/vr41xx/nec-cmbvr4133/setup.c b/arch/mips/vr41xx/nec-cmbvr4133/setup.c
new file mode 100644
index 0000000..db686ce
--- /dev/null
+++ b/arch/mips/vr41xx/nec-cmbvr4133/setup.c
@@ -0,0 +1,96 @@
+/*
+ * arch/mips/vr41xx/nec-cmbvr4133/setup.c
+ *
+ * Setup for the NEC CMB-VR4133.
+ *
+ * Author: Yoichi Yuasa <yyuasa@mvista.com, or source@mvista.com> and
+ *         Alex Sapkov <asapkov@ru.mvista.com>
+ *
+ * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for CMBVR4133 board in 2.6
+ * Author: Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/ide.h>
+#include <linux/ioport.h>
+
+#include <asm/reboot.h>
+#include <asm/time.h>
+#include <asm/vr41xx/cmbvr4133.h>
+#include <asm/bootinfo.h>
+
+#ifdef CONFIG_MTD
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+
+static struct mtd_partition cmbvr4133_mtd_parts[] = {
+	{
+		.name =		"User FS",
+		.size =		0x1be0000,
+		.offset =	0,
+		.mask_flags = 	0,
+	},
+	{
+		.name =		"PMON",
+		.size =		0x140000,
+		.offset =	MTDPART_OFS_APPEND,
+		.mask_flags =	MTD_WRITEABLE,  /* force read-only */
+	},
+	{
+		.name =		"User FS2",
+		.size =		MTDPART_SIZ_FULL,
+		.offset =	MTDPART_OFS_APPEND,
+		.mask_flags = 	0,
+	}
+};
+
+#define number_partitions (sizeof(cmbvr4133_mtd_parts)/sizeof(struct mtd_partition))
+#endif
+
+extern void i8259_init(void);
+
+static int __init nec_cmbvr4133_setup(void)
+{
+#ifdef CONFIG_ROCKHOPPER
+	extern void disable_pcnet(void);
+
+	disable_pcnet();
+#endif
+	set_io_port_base(KSEG1ADDR(0x16000000));
+
+	mips_machgroup = MACH_GROUP_NEC_VR41XX;
+	mips_machtype = MACH_NEC_CMBVR4133;
+
+#ifdef CONFIG_PCI
+#ifdef CONFIG_ROCKHOPPER
+	ali_m5229_preinit();
+#endif
+#endif
+
+#ifdef CONFIG_ROCKHOPPER
+	rockhopper_init_irq();
+#endif
+
+#ifdef CONFIG_MTD
+	/* we use generic physmap mapping driver and we use partitions */
+	physmap_configure(0x1C000000, 0x02000000, 4, NULL);
+	physmap_set_partitions(cmbvr4133_mtd_parts, number_partitions);
+#endif
+
+	/* 128 MB memory support */
+	add_memory_region(0, 0x08000000, BOOT_MEM_RAM);
+
+#ifdef CONFIG_ROCKHOPPER
+	i8259_init();
+#endif
+	return 0;
+}
+
+early_initcall(nec_cmbvr4133_setup);
diff --git a/arch/mips/vr41xx/tanbac-tb0226/Makefile b/arch/mips/vr41xx/tanbac-tb0226/Makefile
new file mode 100644
index 0000000..372f953
--- /dev/null
+++ b/arch/mips/vr41xx/tanbac-tb0226/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the TANBAC TB0226 specific parts of the kernel
+#
+
+obj-y			+= setup.o
diff --git a/arch/mips/vr41xx/tanbac-tb0226/setup.c b/arch/mips/vr41xx/tanbac-tb0226/setup.c
new file mode 100644
index 0000000..60027e5
--- /dev/null
+++ b/arch/mips/vr41xx/tanbac-tb0226/setup.c
@@ -0,0 +1,24 @@
+/*
+ *  setup.c, Setup for the TANBAC TB0226.
+ *
+ *  Copyright (C) 2002-2005  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+const char *get_system_type(void)
+{
+	return "TANBAC TB0226";
+}
diff --git a/arch/mips/vr41xx/tanbac-tb0229/Makefile b/arch/mips/vr41xx/tanbac-tb0229/Makefile
new file mode 100644
index 0000000..9c6b864
--- /dev/null
+++ b/arch/mips/vr41xx/tanbac-tb0229/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the TANBAC TB0229(VR4131DIMM) specific parts of the kernel
+#
+
+obj-y				:= setup.o
diff --git a/arch/mips/vr41xx/tanbac-tb0229/setup.c b/arch/mips/vr41xx/tanbac-tb0229/setup.c
new file mode 100644
index 0000000..5c1b757
--- /dev/null
+++ b/arch/mips/vr41xx/tanbac-tb0229/setup.c
@@ -0,0 +1,27 @@
+/*
+ *  setup.c, Setup for the TANBAC TB0229 (VR4131DIMM)
+ *
+ *  Copyright (C) 2002-2005  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *
+ *  Modified for TANBAC TB0229:
+ *  Copyright (C) 2003  Megasolution Inc.  <matsu@megasolution.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+const char *get_system_type(void)
+{
+	return "TANBAC TB0229";
+}
diff --git a/arch/mips/vr41xx/victor-mpc30x/Makefile b/arch/mips/vr41xx/victor-mpc30x/Makefile
new file mode 100644
index 0000000..a2e8086
--- /dev/null
+++ b/arch/mips/vr41xx/victor-mpc30x/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the Victor MP-C303/304 specific parts of the kernel
+#
+
+obj-y			+= setup.o
diff --git a/arch/mips/vr41xx/victor-mpc30x/setup.c b/arch/mips/vr41xx/victor-mpc30x/setup.c
new file mode 100644
index 0000000..f591e36
--- /dev/null
+++ b/arch/mips/vr41xx/victor-mpc30x/setup.c
@@ -0,0 +1,24 @@
+/*
+ *  setup.c, Setup for the Victor MP-C303/304.
+ *
+ *  Copyright (C) 2002-2005  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+const char *get_system_type(void)
+{
+	return "Victor MP-C303/304";
+}
diff --git a/arch/mips/vr41xx/zao-capcella/Makefile b/arch/mips/vr41xx/zao-capcella/Makefile
new file mode 100644
index 0000000..cf42019
--- /dev/null
+++ b/arch/mips/vr41xx/zao-capcella/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the ZAO Networks Capcella  specific parts of the kernel
+#
+
+obj-y			+= setup.o
diff --git a/arch/mips/vr41xx/zao-capcella/setup.c b/arch/mips/vr41xx/zao-capcella/setup.c
new file mode 100644
index 0000000..17bade2
--- /dev/null
+++ b/arch/mips/vr41xx/zao-capcella/setup.c
@@ -0,0 +1,24 @@
+/*
+ *  setup.c, Setup for the ZAO Networks Capcella.
+ *
+ *  Copyright (C) 2002-2005  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+const char *get_system_type(void)
+{
+	return "ZAO Networks Capcella";
+}