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/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;
+}