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/arm/mach-iop3xx/Kconfig b/arch/arm/mach-iop3xx/Kconfig
new file mode 100644
index 0000000..2bfe8c7
--- /dev/null
+++ b/arch/arm/mach-iop3xx/Kconfig
@@ -0,0 +1,63 @@
+if ARCH_IOP3XX
+
+menu "IOP3xx Implementation Options"
+
+comment "IOP3xx Platform Types"
+
+config ARCH_IQ80321
+	bool "Enable support for IQ80321"
+	select ARCH_IOP321
+	help
+	  Say Y here if you want to run your kernel on the Intel IQ80321
+	  evaluation kit for the IOP321 chipset.
+
+config ARCH_IQ31244
+	bool "Enable support for IQ31244"
+	select ARCH_IOP321
+	help
+	  Say Y here if you want to run your kernel on the Intel IQ31244
+	  evaluation kit for the IOP321 chipset.
+
+config ARCH_IQ80331
+	bool "Enable support for IQ80331"
+	select ARCH_IOP331
+	help
+	  Say Y here if you want to run your kernel on the Intel IQ80331
+	  evaluation kit for the IOP331 chipset.
+
+config MACH_IQ80332
+	bool "Enable support for IQ80332"
+	select ARCH_IOP331
+	help
+	  Say Y here if you want to run your kernel on the Intel IQ80332
+	  evaluation kit for the IOP332 chipset
+
+config ARCH_EP80219
+    bool "Enable support for EP80219"
+    select ARCH_IOP321
+    select ARCH_IQ31244
+
+# Which IOP variant are we running?
+config ARCH_IOP321
+	bool
+	help
+	  The IQ80321 uses the IOP321 variant.
+	  The IQ31244 and EP80219 uses the IOP321 variant.
+
+config ARCH_IOP331
+	bool
+	default ARCH_IQ80331
+	help
+	  The IQ80331, IQ80332, and IQ80333 uses the IOP331 variant.
+
+comment "IOP3xx Chipset Features"
+
+config IOP331_STEPD
+	bool "Chip stepping D of the IOP80331 processor or IOP80333"
+	depends on (ARCH_IOP331)
+	help
+		  Say Y here if you have StepD of the IOP80331 or IOP8033
+		  based platforms.
+
+endmenu
+endif
diff --git a/arch/arm/mach-iop3xx/Makefile b/arch/arm/mach-iop3xx/Makefile
new file mode 100644
index 0000000..b17eb1f
--- /dev/null
+++ b/arch/arm/mach-iop3xx/Makefile
@@ -0,0 +1,23 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-y			:= common.o
+
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+obj-$(CONFIG_ARCH_IOP321)  += iop321-setup.o iop321-irq.o iop321-pci.o iop321-time.o
+
+obj-$(CONFIG_ARCH_IOP331)  += iop331-setup.o iop331-irq.o iop331-pci.o iop331-time.o
+
+obj-$(CONFIG_ARCH_IQ80321) += iq80321-mm.o iq80321-pci.o
+
+obj-$(CONFIG_ARCH_IQ31244) += iq31244-mm.o iq31244-pci.o
+
+obj-$(CONFIG_ARCH_IQ80331) += iq80331-mm.o iq80331-pci.o
+
+obj-$(CONFIG_MACH_IQ80332) += iq80332-mm.o iq80332-pci.o
diff --git a/arch/arm/mach-iop3xx/Makefile.boot b/arch/arm/mach-iop3xx/Makefile.boot
new file mode 100644
index 0000000..6387aa2
--- /dev/null
+++ b/arch/arm/mach-iop3xx/Makefile.boot
@@ -0,0 +1,9 @@
+   zreladdr-y	:= 0xa0008000
+params_phys-y	:= 0xa0000100
+initrd_phys-y	:= 0xa0800000
+ifeq ($(CONFIG_ARCH_IOP331),y)
+   zreladdr-y	:= 0x00008000
+params_phys-y	:= 0x00000100
+initrd_phys-y	:= 0x00800000
+endif
+
diff --git a/arch/arm/mach-iop3xx/common.c b/arch/arm/mach-iop3xx/common.c
new file mode 100644
index 0000000..bda7394
--- /dev/null
+++ b/arch/arm/mach-iop3xx/common.c
@@ -0,0 +1,74 @@
+/*
+ * arch/arm/mach-iop3xx/common.c
+ *
+ * Common routines shared across all IOP3xx implementations
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright 2003 (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.
+ */
+
+#include <linux/config.h>
+#include <linux/delay.h>
+#include <asm/hardware.h>
+
+/*
+ * Shared variables
+ */
+unsigned long iop3xx_pcibios_min_io = 0;
+unsigned long iop3xx_pcibios_min_mem = 0;
+
+#ifdef CONFIG_ARCH_EP80219
+#include <linux/kernel.h>
+/*
+ * Default power-off for EP80219
+ */
+#include <asm/mach-types.h>
+
+static inline void ep80219_send_to_pic(__u8 c) {
+}
+
+void ep80219_power_off(void)
+{
+	/*
+     * This function will send a SHUTDOWN_COMPLETE message to the PIC controller
+     * over I2C.  We are not using the i2c subsystem since we are going to power
+     * off and it may be removed
+     */
+
+	/* Send the Address byte w/ the start condition */
+	*IOP321_IDBR1 = 0x60;
+	*IOP321_ICR1 = 0xE9;
+    mdelay(1);
+
+	/* Send the START_MSG byte w/ no start or stop condition */
+	*IOP321_IDBR1 = 0x0F;
+	*IOP321_ICR1 = 0xE8;
+    mdelay(1);
+
+	/* Send the SHUTDOWN_COMPLETE Message ID byte w/ no start or stop condition */
+	*IOP321_IDBR1 = 0x03;
+	*IOP321_ICR1 = 0xE8;
+    mdelay(1);
+
+	/* Send an ignored byte w/ stop condition */
+	*IOP321_IDBR1 = 0x00;
+	*IOP321_ICR1 = 0xEA;
+
+	while (1) ;
+}
+
+#include <linux/init.h>
+#include <linux/pm.h>
+
+static int __init ep80219_init(void)
+{
+	pm_power_off = ep80219_power_off;
+	return 0;
+}
+arch_initcall(ep80219_init);
+#endif
diff --git a/arch/arm/mach-iop3xx/iop321-irq.c b/arch/arm/mach-iop3xx/iop321-irq.c
new file mode 100644
index 0000000..d42aae6
--- /dev/null
+++ b/arch/arm/mach-iop3xx/iop321-irq.c
@@ -0,0 +1,96 @@
+/*
+ * linux/arch/arm/mach-iop3xx/iop321-irq.c
+ *
+ * Generic IOP321 IRQ handling functionality
+ *
+ * Author: Rory Bolt <rorybolt@pacbell.net>
+ * Copyright (C) 2002 Rory Bolt
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Added IOP3XX chipset and IQ80321 board masking code.
+ *
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+
+#include <asm/mach/irq.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+
+#include <asm/mach-types.h>
+
+static u32 iop321_mask /* = 0 */;
+
+static inline void intctl_write(u32 val)
+{
+	asm volatile("mcr p6,0,%0,c0,c0,0"::"r" (val));
+}
+
+static inline void intstr_write(u32 val)
+{
+	asm volatile("mcr p6,0,%0,c4,c0,0"::"r" (val));
+}
+
+static void
+iop321_irq_mask (unsigned int irq)
+{
+
+	iop321_mask &= ~(1 << (irq - IOP321_IRQ_OFS));
+
+	intctl_write(iop321_mask);
+}
+
+static void
+iop321_irq_unmask (unsigned int irq)
+{
+	iop321_mask |= (1 << (irq - IOP321_IRQ_OFS));
+
+	intctl_write(iop321_mask);
+}
+
+struct irqchip ext_chip = {
+	.ack    = iop321_irq_mask,
+	.mask   = iop321_irq_mask,
+	.unmask = iop321_irq_unmask,
+};
+
+void __init iop321_init_irq(void)
+{
+	unsigned int i, tmp;
+
+	/* Enable access to coprocessor 6 for dealing with IRQs.
+	 * From RMK:
+	 * Basically, the Intel documentation here is poor.  It appears that
+	 * you need to set the bit to be able to access the coprocessor from
+	 * SVC mode.  Whether that allows access from user space or not is
+	 * unclear.
+	 */
+	asm volatile (
+		"mrc p15, 0, %0, c15, c1, 0\n\t"
+		"orr %0, %0, %1\n\t"
+		"mcr p15, 0, %0, c15, c1, 0\n\t"
+		/* The action is delayed, so we have to do this: */
+		"mrc p15, 0, %0, c15, c1, 0\n\t"
+		"mov %0, %0\n\t"
+		"sub pc, pc, #4"
+		: "=r" (tmp) : "i" (1 << 6) );
+
+	intctl_write(0);		// disable all interrupts
+	intstr_write(0);		// treat all as IRQ
+	if(machine_is_iq80321() ||
+	   machine_is_iq31244()) 	// all interrupts are inputs to chip
+		*IOP321_PCIIRSR = 0x0f;
+
+	for(i = IOP321_IRQ_OFS; i < NR_IOP321_IRQS; i++)
+	{
+		set_irq_chip(i, &ext_chip);
+		set_irq_handler(i, do_level_IRQ);
+		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+
+	}
+}
+
diff --git a/arch/arm/mach-iop3xx/iop321-pci.c b/arch/arm/mach-iop3xx/iop321-pci.c
new file mode 100644
index 0000000..8ba6a0e
--- /dev/null
+++ b/arch/arm/mach-iop3xx/iop321-pci.c
@@ -0,0 +1,220 @@
+/*
+ * arch/arm/mach-iop3xx/iop321-pci.c
+ *
+ * PCI support for the Intel IOP321 chipset
+ *
+ * Author: Rory Bolt <rorybolt@pacbell.net>
+ * Copyright (C) 2002 Rory Bolt
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/hardware.h>
+#include <asm/mach/pci.h>
+
+#include <asm/arch/iop321.h>
+
+// #define DEBUG
+
+#ifdef DEBUG
+#define  DBG(x...) printk(x)
+#else
+#define  DBG(x...) do { } while (0)
+#endif
+
+/*
+ * This routine builds either a type0 or type1 configuration command.  If the
+ * bus is on the 80321 then a type0 made, else a type1 is created.
+ */
+static u32 iop321_cfg_address(struct pci_bus *bus, int devfn, int where)
+{
+	struct pci_sys_data *sys = bus->sysdata;
+	u32 addr;
+
+	if (sys->busnr == bus->number)
+		addr = 1 << (PCI_SLOT(devfn) + 16) | (PCI_SLOT(devfn) << 11);
+	else
+		addr = bus->number << 16 | PCI_SLOT(devfn) << 11 | 1;
+
+	addr |=	PCI_FUNC(devfn) << 8 | (where & ~3);
+
+	return addr;
+}
+
+/*
+ * This routine checks the status of the last configuration cycle.  If an error
+ * was detected it returns a 1, else it returns a 0.  The errors being checked
+ * are parity, master abort, target abort (master and target).  These types of
+ * errors occure during a config cycle where there is no device, like during
+ * the discovery stage.
+ */
+static int iop321_pci_status(void)
+{
+	unsigned int status;
+	int ret = 0;
+
+	/*
+	 * Check the status registers.
+	 */
+	status = *IOP321_ATUSR;
+	if (status & 0xf900)
+	{
+		DBG("\t\t\tPCI: P0 - status = 0x%08x\n", status);
+		*IOP321_ATUSR = status & 0xf900;
+		ret = 1;
+	}
+	status = *IOP321_ATUISR;
+	if (status & 0x679f)
+	{
+		DBG("\t\t\tPCI: P1 - status = 0x%08x\n", status);
+		*IOP321_ATUISR = status & 0x679f;
+		ret = 1;
+	}
+	return ret;
+}
+
+/*
+ * Simply write the address register and read the configuration
+ * data.  Note that the 4 nop's ensure that we are able to handle
+ * a delayed abort (in theory.)
+ */
+static inline u32 iop321_read(unsigned long addr)
+{
+	u32 val;
+
+	__asm__ __volatile__(
+		"str	%1, [%2]\n\t"
+		"ldr	%0, [%3]\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		: "=r" (val)
+		: "r" (addr), "r" (IOP321_OCCAR), "r" (IOP321_OCCDR));
+
+	return val;
+}
+
+/*
+ * The read routines must check the error status of the last configuration
+ * cycle.  If there was an error, the routine returns all hex f's.
+ */
+static int
+iop321_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+		int size, u32 *value)
+{
+	unsigned long addr = iop321_cfg_address(bus, devfn, where);
+	u32 val = iop321_read(addr) >> ((where & 3) * 8);
+
+	if( iop321_pci_status() )
+		val = 0xffffffff;
+
+	*value = val;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+iop321_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+		int size, u32 value)
+{
+	unsigned long addr = iop321_cfg_address(bus, devfn, where);
+	u32 val;
+
+	if (size != 4) {
+		val = iop321_read(addr);
+		if (!iop321_pci_status() == 0)
+			return PCIBIOS_SUCCESSFUL;
+
+		where = (where & 3) * 8;
+
+		if (size == 1)
+			val &= ~(0xff << where);
+		else
+			val &= ~(0xffff << where);
+
+		*IOP321_OCCDR = val | value << where;
+	} else {
+		asm volatile(
+			"str	%1, [%2]\n\t"
+			"str	%0, [%3]\n\t"
+			"nop\n\t"
+			"nop\n\t"
+			"nop\n\t"
+			"nop\n\t"
+			:
+			: "r" (value), "r" (addr),
+			  "r" (IOP321_OCCAR), "r" (IOP321_OCCDR));
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops iop321_ops = {
+	.read	= iop321_read_config,
+	.write	= iop321_write_config,
+};
+
+/*
+ * When a PCI device does not exist during config cycles, the 80200 gets a
+ * bus error instead of returning 0xffffffff. This handler simply returns.
+ */
+int
+iop321_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+{
+	DBG("PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx\n",
+		addr, fsr, regs->ARM_pc, regs->ARM_lr);
+
+	/*
+	 * If it was an imprecise abort, then we need to correct the
+	 * return address to be _after_ the instruction.
+	 */
+	if (fsr & (1 << 10))
+		regs->ARM_pc += 4;
+
+	return 0;
+}
+
+/*
+ * Scan an IOP321 PCI bus.  sys->bus defines which bus we scan.
+ */
+struct pci_bus *iop321_scan_bus(int nr, struct pci_sys_data *sys)
+{
+	return pci_scan_bus(sys->busnr, &iop321_ops, sys);
+}
+
+void iop321_init(void)
+{
+	DBG("PCI:  Intel 80321 PCI init code.\n");
+	DBG("ATU: IOP321_ATUCMD=0x%04x\n", *IOP321_ATUCMD);
+	DBG("ATU: IOP321_OMWTVR0=0x%04x, IOP321_OIOWTVR=0x%04x\n",
+			*IOP321_OMWTVR0,
+			*IOP321_OIOWTVR);
+	DBG("ATU: IOP321_ATUCR=0x%08x\n", *IOP321_ATUCR);
+	DBG("ATU: IOP321_IABAR0=0x%08x IOP321_IALR0=0x%08x IOP321_IATVR0=%08x\n",
+			*IOP321_IABAR0, *IOP321_IALR0, *IOP321_IATVR0);
+	DBG("ATU: IOP321_OMWTVR0=0x%08x\n", *IOP321_OMWTVR0);
+	DBG("ATU: IOP321_IABAR1=0x%08x IOP321_IALR1=0x%08x\n",
+			*IOP321_IABAR1, *IOP321_IALR1);
+	DBG("ATU: IOP321_ERBAR=0x%08x IOP321_ERLR=0x%08x IOP321_ERTVR=%08x\n",
+			*IOP321_ERBAR, *IOP321_ERLR, *IOP321_ERTVR);
+	DBG("ATU: IOP321_IABAR2=0x%08x IOP321_IALR2=0x%08x IOP321_IATVR2=%08x\n",
+			*IOP321_IABAR2, *IOP321_IALR2, *IOP321_IATVR2);
+	DBG("ATU: IOP321_IABAR3=0x%08x IOP321_IALR3=0x%08x IOP321_IATVR3=%08x\n",
+			*IOP321_IABAR3, *IOP321_IALR3, *IOP321_IATVR3);
+
+	hook_fault_code(16+6, iop321_pci_abort, SIGBUS, "imprecise external abort");
+}
+
diff --git a/arch/arm/mach-iop3xx/iop321-setup.c b/arch/arm/mach-iop3xx/iop321-setup.c
new file mode 100644
index 0000000..bf23e0f
--- /dev/null
+++ b/arch/arm/mach-iop3xx/iop321-setup.c
@@ -0,0 +1,169 @@
+/*
+ * linux/arch/arm/mach-iop3xx/iop321-setup.c
+ *
+ * Author: Nicolas Pitre <nico@cam.org>
+ * Copyright (C) 2001 MontaVista Software, Inc.
+ * Copyright (C) 2004 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/major.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_core.h>
+
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/mach/map.h>
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/memory.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#define IOP321_UART_XTAL 1843200
+
+/*
+ * Standard IO mapping for all IOP321 based systems
+ */
+static struct map_desc iop321_std_desc[] __initdata = {
+ /* virtual     physical      length      type */
+
+ /* mem mapped registers */
+ { IOP321_VIRT_MEM_BASE,  IOP321_PHYS_MEM_BASE,   0x00002000,  MT_DEVICE },
+
+ /* PCI IO space */
+ { IOP321_PCI_LOWER_IO_VA,  IOP321_PCI_LOWER_IO_PA,   IOP321_PCI_IO_WINDOW_SIZE,  MT_DEVICE }
+};
+
+#ifdef CONFIG_ARCH_IQ80321
+#define UARTBASE IQ80321_UART
+#define IRQ_UART IRQ_IQ80321_UART
+#endif
+
+#ifdef CONFIG_ARCH_IQ31244
+#define UARTBASE IQ31244_UART
+#define IRQ_UART IRQ_IQ31244_UART
+#endif
+
+static struct uart_port iop321_serial_ports[] = {
+	{
+		.membase	= (char*)(UARTBASE),
+		.mapbase	= (UARTBASE),
+		.irq		= IRQ_UART,
+		.flags		= UPF_SKIP_TEST,
+		.iotype		= UPIO_MEM,
+		.regshift	= 0,
+		.uartclk	= IOP321_UART_XTAL,
+		.line		= 0,
+		.type		= PORT_16550A,
+		.fifosize	= 16
+	}
+};
+
+static struct resource iop32x_i2c_0_resources[] = {
+	[0] = {
+		.start = 0xfffff680,
+		.end = 0xfffff698,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_IOP321_I2C_0,
+		.end = IRQ_IOP321_I2C_0,
+		.flags = IORESOURCE_IRQ
+	}
+};
+
+static struct resource iop32x_i2c_1_resources[] = {
+	[0] = {
+		.start = 0xfffff6a0,
+		.end = 0xfffff6b8,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_IOP321_I2C_1,
+		.end = IRQ_IOP321_I2C_1,
+		.flags = IORESOURCE_IRQ
+	}
+};
+
+static struct platform_device iop32x_i2c_0_controller = {
+	.name = "IOP3xx-I2C",
+	.id = 0,
+	.num_resources = 2,
+	.resource = iop32x_i2c_0_resources
+};
+
+static struct platform_device iop32x_i2c_1_controller = {
+	.name = "IOP3xx-I2C",
+	.id = 1,
+	.num_resources = 2,
+	.resource = iop32x_i2c_1_resources
+};
+
+static struct platform_device *iop32x_devices[] __initdata = {
+	&iop32x_i2c_0_controller,
+	&iop32x_i2c_1_controller
+};
+
+void __init iop32x_init(void)
+{
+	if(iop_is_321())
+	{
+		platform_add_devices(iop32x_devices,
+				ARRAY_SIZE(iop32x_devices));
+	}
+}
+
+void __init iop321_map_io(void)
+{
+	iotable_init(iop321_std_desc, ARRAY_SIZE(iop321_std_desc));
+	early_serial_setup(&iop321_serial_ports[0]);
+}
+
+#ifdef CONFIG_ARCH_IQ80321
+extern void iq80321_map_io(void);
+extern struct sys_timer iop321_timer;
+extern void iop321_init_time(void);
+#endif
+
+#ifdef CONFIG_ARCH_IQ31244
+extern void iq31244_map_io(void);
+extern struct sys_timer iop321_timer;
+extern void iop321_init_time(void);
+#endif
+
+#if defined(CONFIG_ARCH_IQ80321)
+MACHINE_START(IQ80321, "Intel IQ80321")
+	MAINTAINER("Intel Corporation")
+	BOOT_MEM(PHYS_OFFSET, IQ80321_UART, IQ80321_UART)
+	MAPIO(iq80321_map_io)
+	INITIRQ(iop321_init_irq)
+	.timer		= &iop321_timer,
+    BOOT_PARAMS(0xa0000100)
+	INIT_MACHINE(iop32x_init)
+MACHINE_END
+#elif defined(CONFIG_ARCH_IQ31244)
+MACHINE_START(IQ31244, "Intel IQ31244")
+    MAINTAINER("Intel Corp.")
+    BOOT_MEM(PHYS_OFFSET, IQ31244_UART, IQ31244_UART)
+    MAPIO(iq31244_map_io)
+    INITIRQ(iop321_init_irq)
+	.timer		= &iop321_timer,
+    BOOT_PARAMS(0xa0000100)
+	INIT_MACHINE(iop32x_init)
+MACHINE_END
+#else
+#error No machine descriptor defined for this IOP3XX implementation
+#endif
diff --git a/arch/arm/mach-iop3xx/iop321-time.c b/arch/arm/mach-iop3xx/iop321-time.c
new file mode 100644
index 0000000..9b7dd64
--- /dev/null
+++ b/arch/arm/mach-iop3xx/iop321-time.c
@@ -0,0 +1,109 @@
+/*
+ * arch/arm/mach-iop3xx/iop321-time.c
+ *
+ * Timer code for IOP321 based systems
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright 2002-2003 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/timex.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/mach-types.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+
+#define IOP321_TIME_SYNC 0
+
+static inline unsigned long get_elapsed(void)
+{
+	return LATCH - *IOP321_TU_TCR0;
+}
+
+static unsigned long iop321_gettimeoffset(void)
+{
+	unsigned long elapsed, usec;
+	u32 tisr1, tisr2;
+
+	/*
+	 * If an interrupt was pending before we read the timer,
+	 * we've already wrapped.  Factor this into the time.
+	 * If an interrupt was pending after we read the timer,
+	 * it may have wrapped between checking the interrupt
+	 * status and reading the timer.  Re-read the timer to
+	 * be sure its value is after the wrap.
+	 */
+
+	asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr1));
+	elapsed = get_elapsed();
+	asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr2));
+
+	if(tisr1 & 1)
+		elapsed += LATCH;
+	else if (tisr2 & 1)
+		elapsed = LATCH + get_elapsed();
+
+	/*
+	 * Now convert them to usec.
+	 */
+	usec = (unsigned long)(elapsed * (tick_nsec / 1000)) / LATCH;
+
+	return usec;
+}
+
+static irqreturn_t
+iop321_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	u32 tisr;
+
+	write_seqlock(&xtime_lock);
+
+	asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr));
+	tisr |= 1;
+	asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (tisr));
+
+	timer_tick(regs);
+
+	write_sequnlock(&xtime_lock);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction iop321_timer_irq = {
+	.name		= "IOP321 Timer Tick",
+	.handler	= iop321_timer_interrupt,
+	.flags		= SA_INTERRUPT
+};
+
+static void __init iop321_timer_init(void)
+{
+	u32 timer_ctl;
+
+	setup_irq(IRQ_IOP321_TIMER0, &iop321_timer_irq);
+
+	timer_ctl = IOP321_TMR_EN | IOP321_TMR_PRIVILEGED | IOP321_TMR_RELOAD |
+			IOP321_TMR_RATIO_1_1;
+
+	asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (LATCH));
+
+	asm volatile("mcr p6, 0, %0, c0, c1, 0"	: : "r" (timer_ctl));
+}
+
+struct sys_timer iop321_timer = {
+	.init		= &iop321_timer_init,
+	.offset		= iop321_gettimeoffset,
+};
diff --git a/arch/arm/mach-iop3xx/iop331-irq.c b/arch/arm/mach-iop3xx/iop331-irq.c
new file mode 100644
index 0000000..f4d4321
--- /dev/null
+++ b/arch/arm/mach-iop3xx/iop331-irq.c
@@ -0,0 +1,127 @@
+/*
+ * linux/arch/arm/mach-iop3xx/iop331-irq.c
+ *
+ * Generic IOP331 IRQ handling functionality
+ *
+ * Author: Dave Jiang <dave.jiang@intel.com>
+ * Copyright (C) 2003 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+
+#include <asm/mach/irq.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+
+#include <asm/mach-types.h>
+
+static u32 iop331_mask0 = 0;
+static u32 iop331_mask1 = 0;
+
+static inline void intctl_write0(u32 val)
+{
+    // INTCTL0
+	asm volatile("mcr p6,0,%0,c0,c0,0"::"r" (val));
+}
+
+static inline void intctl_write1(u32 val)
+{
+    // INTCTL1
+    asm volatile("mcr p6,0,%0,c1,c0,0"::"r" (val));
+}
+
+static inline void intstr_write0(u32 val)
+{
+    // INTSTR0
+	asm volatile("mcr p6,0,%0,c2,c0,0"::"r" (val));
+}
+
+static inline void intstr_write1(u32 val)
+{
+    // INTSTR1
+	asm volatile("mcr p6,0,%0,c3,c0,0"::"r" (val));
+}
+
+static void
+iop331_irq_mask1 (unsigned int irq)
+{
+        iop331_mask0 &= ~(1 << (irq - IOP331_IRQ_OFS));
+        intctl_write0(iop331_mask0);
+}
+
+static void
+iop331_irq_mask2 (unsigned int irq)
+{
+        iop331_mask1 &= ~(1 << (irq - IOP331_IRQ_OFS - 32));
+        intctl_write1(iop331_mask1);
+}
+
+static void
+iop331_irq_unmask1(unsigned int irq)
+{
+        iop331_mask0 |= (1 << (irq - IOP331_IRQ_OFS));
+        intctl_write0(iop331_mask0);
+}
+
+static void
+iop331_irq_unmask2(unsigned int irq)
+{
+        iop331_mask1 |= (1 << (irq - IOP331_IRQ_OFS - 32));
+        intctl_write1(iop331_mask1);
+}
+
+struct irqchip iop331_irqchip1 = {
+	.ack    = iop331_irq_mask1,
+	.mask   = iop331_irq_mask1,
+	.unmask = iop331_irq_unmask1,
+};
+
+struct irqchip iop331_irqchip2 = {
+	.ack    = iop331_irq_mask2,
+	.mask   = iop331_irq_mask2,
+	.unmask = iop331_irq_unmask2,
+};
+
+void __init iop331_init_irq(void)
+{
+	unsigned int i, tmp;
+
+	/* Enable access to coprocessor 6 for dealing with IRQs.
+	 * From RMK:
+	 * Basically, the Intel documentation here is poor.  It appears that
+	 * you need to set the bit to be able to access the coprocessor from
+	 * SVC mode.  Whether that allows access from user space or not is
+	 * unclear.
+	 */
+	asm volatile (
+		"mrc p15, 0, %0, c15, c1, 0\n\t"
+		"orr %0, %0, %1\n\t"
+		"mcr p15, 0, %0, c15, c1, 0\n\t"
+		/* The action is delayed, so we have to do this: */
+		"mrc p15, 0, %0, c15, c1, 0\n\t"
+		"mov %0, %0\n\t"
+		"sub pc, pc, #4"
+		: "=r" (tmp) : "i" (1 << 6) );
+
+	intctl_write0(0);		// disable all interrupts
+    	intctl_write1(0);
+	intstr_write0(0);		// treat all as IRQ
+    	intstr_write1(0);
+	if(machine_is_iq80331()) 	// all interrupts are inputs to chip
+		*IOP331_PCIIRSR = 0x0f;
+
+	for(i = IOP331_IRQ_OFS; i < NR_IOP331_IRQS; i++)
+	{
+		set_irq_chip(i, (i < 32) ? &iop331_irqchip1 : &iop331_irqchip2);
+		set_irq_handler(i, do_level_IRQ);
+		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+	}
+}
+
diff --git a/arch/arm/mach-iop3xx/iop331-pci.c b/arch/arm/mach-iop3xx/iop331-pci.c
new file mode 100644
index 0000000..44dd213
--- /dev/null
+++ b/arch/arm/mach-iop3xx/iop331-pci.c
@@ -0,0 +1,222 @@
+/*
+ * arch/arm/mach-iop3xx/iop331-pci.c
+ *
+ * PCI support for the Intel IOP331 chipset
+ *
+ * Author: Dave Jiang (dave.jiang@intel.com)
+ * Copyright (C) 2003, 2004 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/hardware.h>
+#include <asm/mach/pci.h>
+
+#include <asm/arch/iop331.h>
+
+#undef DEBUG
+#undef DEBUG1
+
+#ifdef DEBUG
+#define  DBG(x...) printk(x)
+#else
+#define  DBG(x...) do { } while (0)
+#endif
+
+#ifdef DEBUG1
+#define  DBG1(x...) printk(x)
+#else
+#define  DBG1(x...) do { } while (0)
+#endif
+
+/*
+ * This routine builds either a type0 or type1 configuration command.  If the
+ * bus is on the 80331 then a type0 made, else a type1 is created.
+ */
+static u32 iop331_cfg_address(struct pci_bus *bus, int devfn, int where)
+{
+	struct pci_sys_data *sys = bus->sysdata;
+	u32 addr;
+
+	if (sys->busnr == bus->number)
+		addr = 1 << (PCI_SLOT(devfn) + 16) | (PCI_SLOT(devfn) << 11);
+	else
+		addr = bus->number << 16 | PCI_SLOT(devfn) << 11 | 1;
+
+	addr |=	PCI_FUNC(devfn) << 8 | (where & ~3);
+
+	return addr;
+}
+
+/*
+ * This routine checks the status of the last configuration cycle.  If an error
+ * was detected it returns a 1, else it returns a 0.  The errors being checked
+ * are parity, master abort, target abort (master and target).  These types of
+ * errors occure during a config cycle where there is no device, like during
+ * the discovery stage.
+ */
+static int iop331_pci_status(void)
+{
+	unsigned int status;
+	int ret = 0;
+
+	/*
+	 * Check the status registers.
+	 */
+	status = *IOP331_ATUSR;
+	if (status & 0xf900)
+	{
+		DBG("\t\t\tPCI: P0 - status = 0x%08x\n", status);
+		*IOP331_ATUSR = status & 0xf900;
+		ret = 1;
+	}
+	status = *IOP331_ATUISR;
+	if (status & 0x679f)
+	{
+		DBG("\t\t\tPCI: P1 - status = 0x%08x\n", status);
+		*IOP331_ATUISR = status & 0x679f;
+		ret = 1;
+	}
+	return ret;
+}
+
+/*
+ * Simply write the address register and read the configuration
+ * data.  Note that the 4 nop's ensure that we are able to handle
+ * a delayed abort (in theory.)
+ */
+static inline u32 iop331_read(unsigned long addr)
+{
+	u32 val;
+
+	__asm__ __volatile__(
+		"str	%1, [%2]\n\t"
+		"ldr	%0, [%3]\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		"nop\n\t"
+		: "=r" (val)
+		: "r" (addr), "r" (IOP331_OCCAR), "r" (IOP331_OCCDR));
+
+	return val;
+}
+
+/*
+ * The read routines must check the error status of the last configuration
+ * cycle.  If there was an error, the routine returns all hex f's.
+ */
+static int
+iop331_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+		int size, u32 *value)
+{
+	unsigned long addr = iop331_cfg_address(bus, devfn, where);
+	u32 val = iop331_read(addr) >> ((where & 3) * 8);
+
+	if( iop331_pci_status() )
+		val = 0xffffffff;
+
+	*value = val;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+iop331_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+		int size, u32 value)
+{
+	unsigned long addr = iop331_cfg_address(bus, devfn, where);
+	u32 val;
+
+	if (size != 4) {
+		val = iop331_read(addr);
+		if (!iop331_pci_status() == 0)
+			return PCIBIOS_SUCCESSFUL;
+
+		where = (where & 3) * 8;
+
+		if (size == 1)
+			val &= ~(0xff << where);
+		else
+			val &= ~(0xffff << where);
+
+		*IOP331_OCCDR = val | value << where;
+	} else {
+		asm volatile(
+			"str	%1, [%2]\n\t"
+			"str	%0, [%3]\n\t"
+			"nop\n\t"
+			"nop\n\t"
+			"nop\n\t"
+			"nop\n\t"
+			:
+			: "r" (value), "r" (addr),
+			  "r" (IOP331_OCCAR), "r" (IOP331_OCCDR));
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops iop331_ops = {
+	.read	= iop331_read_config,
+	.write	= iop331_write_config,
+};
+
+/*
+ * When a PCI device does not exist during config cycles, the XScale gets a
+ * bus error instead of returning 0xffffffff. This handler simply returns.
+ */
+int
+iop331_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+{
+	DBG("PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx\n",
+		addr, fsr, regs->ARM_pc, regs->ARM_lr);
+
+	/*
+	 * If it was an imprecise abort, then we need to correct the
+	 * return address to be _after_ the instruction.
+	 */
+	if (fsr & (1 << 10))
+		regs->ARM_pc += 4;
+
+	return 0;
+}
+
+/*
+ * Scan an IOP331 PCI bus.  sys->bus defines which bus we scan.
+ */
+struct pci_bus *iop331_scan_bus(int nr, struct pci_sys_data *sys)
+{
+	return pci_scan_bus(sys->busnr, &iop331_ops, sys);
+}
+
+void iop331_init(void)
+{
+	DBG1("PCI:  Intel 80331 PCI init code.\n");
+	DBG1("\tATU: IOP331_ATUCMD=0x%04x\n", *IOP331_ATUCMD);
+	DBG1("\tATU: IOP331_OMWTVR0=0x%04x, IOP331_OIOWTVR=0x%04x\n",
+			*IOP331_OMWTVR0,
+			*IOP331_OIOWTVR);
+	DBG1("\tATU: IOP331_OMWTVR1=0x%04x\n", *IOP331_OMWTVR1);
+	DBG1("\tATU: IOP331_ATUCR=0x%08x\n", *IOP331_ATUCR);
+	DBG1("\tATU: IOP331_IABAR0=0x%08x IOP331_IALR0=0x%08x IOP331_IATVR0=%08x\n", *IOP331_IABAR0, *IOP331_IALR0, *IOP331_IATVR0);
+	DBG1("\tATU: IOP31_IABAR1=0x%08x IOP331_IALR1=0x%08x\n", *IOP331_IABAR1, *IOP331_IALR1);
+	DBG1("\tATU: IOP331_ERBAR=0x%08x IOP331_ERLR=0x%08x IOP331_ERTVR=%08x\n", *IOP331_ERBAR, *IOP331_ERLR, *IOP331_ERTVR);
+	DBG1("\tATU: IOP331_IABAR2=0x%08x IOP331_IALR2=0x%08x IOP331_IATVR2=%08x\n", *IOP331_IABAR2, *IOP331_IALR2, *IOP331_IATVR2);
+	DBG1("\tATU: IOP331_IABAR3=0x%08x IOP331_IALR3=0x%08x IOP331_IATVR3=%08x\n", *IOP331_IABAR3, *IOP331_IALR3, *IOP331_IATVR3);
+
+	hook_fault_code(16+6, iop331_pci_abort, SIGBUS, "imprecise external abort");
+}
+
diff --git a/arch/arm/mach-iop3xx/iop331-setup.c b/arch/arm/mach-iop3xx/iop331-setup.c
new file mode 100644
index 0000000..622e791
--- /dev/null
+++ b/arch/arm/mach-iop3xx/iop331-setup.c
@@ -0,0 +1,177 @@
+/*
+ * linux/arch/arm/mach-iop3xx/iop331-setup.c
+ *
+ * Author: Dave Jiang (dave.jiang@intel.com)
+ * Copyright (C) 2004 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/major.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_core.h>
+
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/mach/map.h>
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/memory.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#define IOP331_UART_XTAL 33334000
+
+/*
+ * Standard IO mapping for all IOP331 based systems
+ */
+static struct map_desc iop331_std_desc[] __initdata = {
+ /* virtual     physical      length      type */
+
+ /* mem mapped registers */
+ { IOP331_VIRT_MEM_BASE,  IOP331_PHYS_MEM_BASE,   0x00002000,  MT_DEVICE },
+
+ /* PCI IO space */
+ { IOP331_PCI_LOWER_IO_VA,  IOP331_PCI_LOWER_IO_PA,   IOP331_PCI_IO_WINDOW_SIZE,  MT_DEVICE }
+};
+
+static struct uart_port iop331_serial_ports[] = {
+	{
+		.membase	= (char*)(IOP331_UART0_VIRT),
+		.mapbase	= (IOP331_UART0_PHYS),
+		.irq		= IRQ_IOP331_UART0,
+		.flags		= UPF_SKIP_TEST,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= IOP331_UART_XTAL,
+		.line		= 0,
+		.type		= PORT_XSCALE,
+		.fifosize	= 32
+	} , {
+		.membase	= (char*)(IOP331_UART1_VIRT),
+		.mapbase	= (IOP331_UART1_PHYS),
+		.irq		= IRQ_IOP331_UART1,
+		.flags		= UPF_SKIP_TEST,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= IOP331_UART_XTAL,
+		.line		= 1,
+		.type		= PORT_XSCALE,
+		.fifosize	= 32
+	}
+};
+
+static struct resource iop33x_i2c_0_resources[] = {
+	[0] = {
+		.start = 0xfffff680,
+		.end = 0xfffff698,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_IOP331_I2C_0,
+		.end = IRQ_IOP331_I2C_0,
+		.flags = IORESOURCE_IRQ
+	}
+};
+
+static struct resource iop33x_i2c_1_resources[] = {
+	[0] = {
+		.start = 0xfffff6a0,
+		.end = 0xfffff6b8,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_IOP331_I2C_1,
+		.end = IRQ_IOP331_I2C_1,
+		.flags = IORESOURCE_IRQ
+	}
+};
+
+static struct platform_device iop33x_i2c_0_controller = {
+	.name = "IOP3xx-I2C",
+	.id = 0,
+	.num_resources = 2,
+	.resource = iop33x_i2c_0_resources
+};
+
+static struct platform_device iop33x_i2c_1_controller = {
+	.name = "IOP3xx-I2C",
+	.id = 1,
+	.num_resources = 2,
+	.resource = iop33x_i2c_1_resources
+};
+
+static struct platform_device *iop33x_devices[] __initdata = {
+	&iop33x_i2c_0_controller,
+	&iop33x_i2c_1_controller
+};
+
+void __init iop33x_init(void)
+{
+	if(iop_is_331())
+	{
+		platform_add_devices(iop33x_devices,
+				ARRAY_SIZE(iop33x_devices));
+	}
+}
+
+void __init iop331_map_io(void)
+{
+	iotable_init(iop331_std_desc, ARRAY_SIZE(iop331_std_desc));
+	early_serial_setup(&iop331_serial_ports[0]);
+	early_serial_setup(&iop331_serial_ports[1]);
+}
+
+#ifdef CONFIG_ARCH_IOP331
+extern void iop331_init_irq(void);
+extern struct sys_timer iop331_timer;
+#endif
+
+#ifdef CONFIG_ARCH_IQ80331
+extern void iq80331_map_io(void);
+#endif
+
+#ifdef CONFIG_MACH_IQ80332
+extern void iq80332_map_io(void);
+#endif
+
+#if defined(CONFIG_ARCH_IQ80331)
+MACHINE_START(IQ80331, "Intel IQ80331")
+    MAINTAINER("Intel Corp.")
+    BOOT_MEM(PHYS_OFFSET, 0xfefff000, 0xfffff000) // virtual, physical
+    //BOOT_MEM(PHYS_OFFSET, IOP331_UART0_VIRT, IOP331_UART0_PHYS)
+    MAPIO(iq80331_map_io)
+    INITIRQ(iop331_init_irq)
+	.timer		= &iop331_timer,
+    BOOT_PARAMS(0x0100)
+	INIT_MACHINE(iop33x_init)
+MACHINE_END
+
+#elif defined(CONFIG_MACH_IQ80332)
+MACHINE_START(IQ80332, "Intel IQ80332")
+    MAINTAINER("Intel Corp.")
+    BOOT_MEM(PHYS_OFFSET, 0xfefff000, 0xfffff000) // virtual, physical
+    //BOOT_MEM(PHYS_OFFSET, IOP331_UART0_VIRT, IOP331_UART0_PHYS)
+    MAPIO(iq80332_map_io)
+    INITIRQ(iop331_init_irq)
+	.timer		= &iop331_timer,
+    BOOT_PARAMS(0x0100)
+	INIT_MACHINE(iop33x_init)
+MACHINE_END
+
+#else
+#error No machine descriptor defined for this IOP3XX implementation
+#endif
+
+
diff --git a/arch/arm/mach-iop3xx/iop331-time.c b/arch/arm/mach-iop3xx/iop331-time.c
new file mode 100644
index 0000000..e016967
--- /dev/null
+++ b/arch/arm/mach-iop3xx/iop331-time.c
@@ -0,0 +1,107 @@
+/*
+ * arch/arm/mach-iop3xx/iop331-time.c
+ *
+ * Timer code for IOP331 based systems
+ *
+ * Author: Dave Jiang <dave.jiang@intel.com>
+ *
+ * Copyright 2003 Intel Corp.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/timex.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/mach-types.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+
+static inline unsigned long get_elapsed(void)
+{
+	return LATCH - *IOP331_TU_TCR0;
+}
+
+static unsigned long iop331_gettimeoffset(void)
+{
+	unsigned long elapsed, usec;
+	u32 tisr1, tisr2;
+
+	/*
+	 * If an interrupt was pending before we read the timer,
+	 * we've already wrapped.  Factor this into the time.
+	 * If an interrupt was pending after we read the timer,
+	 * it may have wrapped between checking the interrupt
+	 * status and reading the timer.  Re-read the timer to
+	 * be sure its value is after the wrap.
+	 */
+
+	asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr1));
+	elapsed = get_elapsed();
+	asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr2));
+
+	if(tisr1 & 1)
+		elapsed += LATCH;
+	else if (tisr2 & 1)
+		elapsed = LATCH + get_elapsed();
+
+	/*
+	 * Now convert them to usec.
+	 */
+	usec = (unsigned long)(elapsed * (tick_nsec / 1000)) / LATCH;
+
+	return usec;
+}
+
+static irqreturn_t
+iop331_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	u32 tisr;
+
+	write_seqlock(&xtime_lock);
+
+	asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr));
+	tisr |= 1;
+	asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (tisr));
+
+	timer_tick(regs);
+
+	write_sequnlock(&xtime_lock);
+	return IRQ_HANDLED;
+}
+
+static struct irqaction iop331_timer_irq = {
+	.name		= "IOP331 Timer Tick",
+	.handler	= iop331_timer_interrupt,
+	.flags		= SA_INTERRUPT
+};
+
+static void __init iop331_timer_init(void)
+{
+	u32 timer_ctl;
+
+	setup_irq(IRQ_IOP331_TIMER0, &iop331_timer_irq);
+
+	timer_ctl = IOP331_TMR_EN | IOP331_TMR_PRIVILEGED | IOP331_TMR_RELOAD |
+			IOP331_TMR_RATIO_1_1;
+
+	asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (LATCH));
+
+	asm volatile("mcr p6, 0, %0, c0, c1, 0"	: : "r" (timer_ctl));
+
+}
+
+struct sys_timer iop331_timer = {
+	.init		= iop331_timer_init,
+	.offset		= iop331_gettimeoffset,
+};
diff --git a/arch/arm/mach-iop3xx/iq31244-mm.c b/arch/arm/mach-iop3xx/iq31244-mm.c
new file mode 100644
index 0000000..b01042f
--- /dev/null
+++ b/arch/arm/mach-iop3xx/iq31244-mm.c
@@ -0,0 +1,44 @@
+/*
+ * linux/arch/arm/mach-iop3xx/mm.c
+ *
+ * Low level memory initialization for iq80321 platform
+ *
+ * Author: Rory Bolt <rorybolt@pacbell.net>
+ * Copyright (C) 2002 Rory Bolt
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the 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/mm.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+
+
+/*
+ * IQ80321 specific IO mappings
+ *
+ * We use RedBoot's setup for the onboard devices.
+ */
+static struct map_desc iq31244_io_desc[] __initdata = {
+ /* virtual     physical      length        type */
+
+ /* on-board devices */
+ { IQ31244_UART, IQ31244_UART,   0x00100000,   MT_DEVICE }
+};
+
+void __init iq31244_map_io(void)
+{
+	iop321_map_io();
+
+	iotable_init(iq31244_io_desc, ARRAY_SIZE(iq31244_io_desc));
+}
diff --git a/arch/arm/mach-iop3xx/iq31244-pci.c b/arch/arm/mach-iop3xx/iq31244-pci.c
new file mode 100644
index 0000000..f997daa
--- /dev/null
+++ b/arch/arm/mach-iop3xx/iq31244-pci.c
@@ -0,0 +1,129 @@
+/*
+ * arch/arm/mach-iop3xx/iq80321-pci.c
+ *
+ * PCI support for the Intel IQ80321 reference board
+ *
+ * Author: Rory Bolt <rorybolt@pacbell.net>
+ * Copyright (C) 2002 Rory Bolt
+ * Copyright (C) 2004 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+/*
+ * The following macro is used to lookup irqs in a standard table
+ * format for those systems that do not already have PCI
+ * interrupts properly routed.  We assume 1 <= pin <= 4
+ */
+#define PCI_IRQ_TABLE_LOOKUP(minid,maxid)	\
+({ int _ctl_ = -1;				\
+   unsigned int _idsel = idsel - minid;		\
+   if (_idsel <= maxid)				\
+      _ctl_ = pci_irq_table[_idsel][pin-1];	\
+   _ctl_; })
+
+#define INTA	IRQ_IQ31244_INTA
+#define INTB	IRQ_IQ31244_INTB
+#define INTC	IRQ_IQ31244_INTC
+#define INTD	IRQ_IQ31244_INTD
+
+#define INTE	IRQ_IQ31244_I82546
+
+static inline int __init
+iq31244_map_irq(struct pci_dev *dev, u8 idsel, u8 pin)
+{
+	static int pci_irq_table[][4] = {
+		/*
+		 * PCI IDSEL/INTPIN->INTLINE
+		 * A       B       C       D
+		 */
+#ifdef CONFIG_ARCH_EP80219
+		{INTB, INTB, INTB, INTB}, /* CFlash */
+		{INTE, INTE, INTE, INTE}, /* 82551 Pro 100 */
+		{INTD, INTD, INTD, INTD}, /* PCI-X Slot */
+		{INTC, INTC, INTC, INTC}, /* SATA   */
+#else
+		{INTB, INTB, INTB, INTB}, /* CFlash */
+		{INTC, INTC, INTC, INTC}, /* SATA   */
+		{INTD, INTD, INTD, INTD}, /* PCI-X Slot */
+		{INTE, INTE, INTE, INTE}, /* 82546 GigE */
+#endif // CONFIG_ARCH_EP80219
+	};
+
+	BUG_ON(pin < 1 || pin > 4);
+
+	return PCI_IRQ_TABLE_LOOKUP(0, 7);
+}
+
+static int iq31244_setup(int nr, struct pci_sys_data *sys)
+{
+	struct resource *res;
+
+	if(nr != 0)
+		return 0;
+
+	res = kmalloc(sizeof(struct resource) * 2, GFP_KERNEL);
+	if (!res)
+		panic("PCI: unable to alloc resources");
+
+	memset(res, 0, sizeof(struct resource) * 2);
+
+	res[0].start = IOP321_PCI_LOWER_IO_VA;
+	res[0].end   = IOP321_PCI_UPPER_IO_VA;
+	res[0].name  = "IQ31244 PCI I/O Space";
+	res[0].flags = IORESOURCE_IO;
+
+	res[1].start = IOP321_PCI_LOWER_MEM_PA;
+	res[1].end   = IOP321_PCI_UPPER_MEM_PA;
+	res[1].name  = "IQ31244 PCI Memory Space";
+	res[1].flags = IORESOURCE_MEM;
+
+	request_resource(&ioport_resource, &res[0]);
+	request_resource(&iomem_resource, &res[1]);
+
+	sys->mem_offset = IOP321_PCI_MEM_OFFSET;
+	sys->io_offset  = IOP321_PCI_IO_OFFSET;
+
+	sys->resource[0] = &res[0];
+	sys->resource[1] = &res[1];
+	sys->resource[2] = NULL;
+
+	return 1;
+}
+
+static void iq31244_preinit(void)
+{
+	iop321_init();
+}
+
+static struct hw_pci iq31244_pci __initdata = {
+	.swizzle	= pci_std_swizzle,
+	.nr_controllers = 1,
+	.setup		= iq31244_setup,
+	.scan		= iop321_scan_bus,
+	.preinit	= iq31244_preinit,
+	.map_irq	= iq31244_map_irq
+};
+
+static int __init iq31244_pci_init(void)
+{
+	if (machine_is_iq31244())
+		pci_common_init(&iq31244_pci);
+	return 0;
+}
+
+subsys_initcall(iq31244_pci_init);
+
+
+
+
diff --git a/arch/arm/mach-iop3xx/iq80321-mm.c b/arch/arm/mach-iop3xx/iq80321-mm.c
new file mode 100644
index 0000000..1580c7e
--- /dev/null
+++ b/arch/arm/mach-iop3xx/iq80321-mm.c
@@ -0,0 +1,44 @@
+/*
+ * linux/arch/arm/mach-iop3xx/mm.c
+ *
+ * Low level memory initialization for iq80321 platform
+ *
+ * Author: Rory Bolt <rorybolt@pacbell.net>
+ * Copyright (C) 2002 Rory Bolt
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the 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/mm.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+
+
+/*
+ * IQ80321 specific IO mappings
+ *
+ * We use RedBoot's setup for the onboard devices.
+ */
+static struct map_desc iq80321_io_desc[] __initdata = {
+ /* virtual     physical      length        type */
+
+ /* on-board devices */
+ { IQ80321_UART, IQ80321_UART,   0x00100000,   MT_DEVICE }
+};
+
+void __init iq80321_map_io(void)
+{
+	iop321_map_io();
+
+	iotable_init(iq80321_io_desc, ARRAY_SIZE(iq80321_io_desc));
+}
diff --git a/arch/arm/mach-iop3xx/iq80321-pci.c b/arch/arm/mach-iop3xx/iq80321-pci.c
new file mode 100644
index 0000000..79fea3d
--- /dev/null
+++ b/arch/arm/mach-iop3xx/iq80321-pci.c
@@ -0,0 +1,123 @@
+/*
+ * arch/arm/mach-iop3xx/iq80321-pci.c
+ *
+ * PCI support for the Intel IQ80321 reference board
+ *
+ * Author: Rory Bolt <rorybolt@pacbell.net>
+ * Copyright (C) 2002 Rory Bolt
+ * Copyright (C) 2004 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+/*
+ * The following macro is used to lookup irqs in a standard table
+ * format for those systems that do not already have PCI
+ * interrupts properly routed.  We assume 1 <= pin <= 4
+ */
+#define PCI_IRQ_TABLE_LOOKUP(minid,maxid)	\
+({ int _ctl_ = -1;				\
+   unsigned int _idsel = idsel - minid;		\
+   if (_idsel <= maxid)				\
+      _ctl_ = pci_irq_table[_idsel][pin-1];	\
+   _ctl_; })
+
+#define INTA	IRQ_IQ80321_INTA
+#define INTB	IRQ_IQ80321_INTB
+#define INTC	IRQ_IQ80321_INTC
+#define INTD	IRQ_IQ80321_INTD
+
+#define INTE	IRQ_IQ80321_I82544
+
+static inline int __init
+iq80321_map_irq(struct pci_dev *dev, u8 idsel, u8 pin)
+{
+	static int pci_irq_table[][4] = {
+		/*
+		 * PCI IDSEL/INTPIN->INTLINE
+		 * A       B       C       D
+		 */
+		{INTE, INTE, INTE, INTE}, /* Gig-E */
+		{-1, -1, -1, -1}, 	  /* Unused */
+		{INTC, INTD, INTA, INTB}, /* PCI-X Slot */
+		{-1, -1, -1, -1},
+	};
+
+	BUG_ON(pin < 1 || pin > 4);
+
+//	return PCI_IRQ_TABLE_LOOKUP(4, 7);
+	return pci_irq_table[idsel%4][pin-1];
+}
+
+static int iq80321_setup(int nr, struct pci_sys_data *sys)
+{
+	struct resource *res;
+
+	if(nr != 0)
+		return 0;
+
+	res = kmalloc(sizeof(struct resource) * 2, GFP_KERNEL);
+	if (!res)
+		panic("PCI: unable to alloc resources");
+
+	memset(res, 0, sizeof(struct resource) * 2);
+
+	res[0].start = IOP321_PCI_LOWER_IO_VA;
+	res[0].end   = IOP321_PCI_UPPER_IO_VA;
+	res[0].name  = "IQ80321 PCI I/O Space";
+	res[0].flags = IORESOURCE_IO;
+
+	res[1].start = IOP321_PCI_LOWER_MEM_PA;
+	res[1].end   = IOP321_PCI_UPPER_MEM_PA;
+	res[1].name  = "IQ80321 PCI Memory Space";
+	res[1].flags = IORESOURCE_MEM;
+
+	request_resource(&ioport_resource, &res[0]);
+	request_resource(&iomem_resource, &res[1]);
+
+	sys->mem_offset = IOP321_PCI_MEM_OFFSET;
+	sys->io_offset  = IOP321_PCI_IO_OFFSET;
+
+	sys->resource[0] = &res[0];
+	sys->resource[1] = &res[1];
+	sys->resource[2] = NULL;
+
+	return 1;
+}
+
+static void iq80321_preinit(void)
+{
+	iop321_init();
+}
+
+static struct hw_pci iq80321_pci __initdata = {
+	.swizzle	= pci_std_swizzle,
+	.nr_controllers = 1,
+	.setup		= iq80321_setup,
+	.scan		= iop321_scan_bus,
+	.preinit	= iq80321_preinit,
+	.map_irq	= iq80321_map_irq
+};
+
+static int __init iq80321_pci_init(void)
+{
+	if (machine_is_iq80321())
+		pci_common_init(&iq80321_pci);
+	return 0;
+}
+
+subsys_initcall(iq80321_pci_init);
+
+
+
+
diff --git a/arch/arm/mach-iop3xx/iq80331-mm.c b/arch/arm/mach-iop3xx/iq80331-mm.c
new file mode 100644
index 0000000..ee8c333
--- /dev/null
+++ b/arch/arm/mach-iop3xx/iq80331-mm.c
@@ -0,0 +1,36 @@
+/*
+ * linux/arch/arm/mach-iop3xx/mm.c
+ *
+ * Low level memory initialization for iq80331 platform
+ *
+ * Author: Dave Jiang <dave.jiang@intel.com>
+ * Copyright (C) 2003 Intel Corp.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+
+
+/*
+ * IQ80331 specific IO mappings
+ *
+ * We use RedBoot's setup for the onboard devices.
+ */
+
+void __init iq80331_map_io(void)
+{
+	iop331_map_io();
+}
diff --git a/arch/arm/mach-iop3xx/iq80331-pci.c b/arch/arm/mach-iop3xx/iq80331-pci.c
new file mode 100644
index 0000000..f37a0e2
--- /dev/null
+++ b/arch/arm/mach-iop3xx/iq80331-pci.c
@@ -0,0 +1,119 @@
+/*
+ * arch/arm/mach-iop3xx/iq80331-pci.c
+ *
+ * PCI support for the Intel IQ80331 reference board
+ *
+ * Author: Dave Jiang <dave.jiang@intel.com>
+ * Copyright (C) 2003, 2004 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+/*
+ * The following macro is used to lookup irqs in a standard table
+ * format for those systems that do not already have PCI
+ * interrupts properly routed.  We assume 1 <= pin <= 4
+ */
+#define PCI_IRQ_TABLE_LOOKUP(minid,maxid)	\
+({ int _ctl_ = -1;				\
+   unsigned int _idsel = idsel - minid;		\
+   if (_idsel <= maxid)				\
+      _ctl_ = pci_irq_table[_idsel][pin-1];	\
+   _ctl_; })
+
+#define INTA	IRQ_IQ80331_INTA
+#define INTB	IRQ_IQ80331_INTB
+#define INTC	IRQ_IQ80331_INTC
+#define INTD	IRQ_IQ80331_INTD
+
+//#define INTE	IRQ_IQ80331_I82544
+
+static inline int __init
+iq80331_map_irq(struct pci_dev *dev, u8 idsel, u8 pin)
+{
+	static int pci_irq_table[][4] = {
+		/*
+		 * PCI IDSEL/INTPIN->INTLINE
+		 * A       B       C       D
+		 */
+		{INTB, INTC, INTD, INTA}, /* PCI-X Slot */
+		{INTC, INTC, INTC, INTC}, /* GigE  */
+	};
+
+	BUG_ON(pin < 1 || pin > 4);
+
+	return PCI_IRQ_TABLE_LOOKUP(1, 7);
+}
+
+static int iq80331_setup(int nr, struct pci_sys_data *sys)
+{
+	struct resource *res;
+
+	if(nr != 0)
+		return 0;
+
+	res = kmalloc(sizeof(struct resource) * 2, GFP_KERNEL);
+	if (!res)
+		panic("PCI: unable to alloc resources");
+
+	memset(res, 0, sizeof(struct resource) * 2);
+
+	res[0].start = IOP331_PCI_LOWER_IO_VA;
+	res[0].end   = IOP331_PCI_UPPER_IO_VA;
+	res[0].name  = "IQ80331 PCI I/O Space";
+	res[0].flags = IORESOURCE_IO;
+
+	res[1].start = IOP331_PCI_LOWER_MEM_PA;
+	res[1].end   = IOP331_PCI_UPPER_MEM_PA;
+	res[1].name  = "IQ80331 PCI Memory Space";
+	res[1].flags = IORESOURCE_MEM;
+
+	request_resource(&ioport_resource, &res[0]);
+	request_resource(&iomem_resource, &res[1]);
+
+	sys->mem_offset = IOP331_PCI_MEM_OFFSET;
+	sys->io_offset  = IOP331_PCI_IO_OFFSET;
+
+	sys->resource[0] = &res[0];
+	sys->resource[1] = &res[1];
+	sys->resource[2] = NULL;
+
+	return 1;
+}
+
+static void iq80331_preinit(void)
+{
+	iop331_init();
+}
+
+static struct hw_pci iq80331_pci __initdata = {
+	.swizzle	= pci_std_swizzle,
+	.nr_controllers = 1,
+	.setup		= iq80331_setup,
+	.scan		= iop331_scan_bus,
+	.preinit	= iq80331_preinit,
+	.map_irq	= iq80331_map_irq
+};
+
+static int __init iq80331_pci_init(void)
+{
+	if (machine_is_iq80331())
+		pci_common_init(&iq80331_pci);
+	return 0;
+}
+
+subsys_initcall(iq80331_pci_init);
+
+
+
+
diff --git a/arch/arm/mach-iop3xx/iq80332-mm.c b/arch/arm/mach-iop3xx/iq80332-mm.c
new file mode 100644
index 0000000..084afcd
--- /dev/null
+++ b/arch/arm/mach-iop3xx/iq80332-mm.c
@@ -0,0 +1,36 @@
+/*
+ * linux/arch/arm/mach-iop3xx/mm.c
+ *
+ * Low level memory initialization for iq80332 platform
+ *
+ * Author: Dave Jiang <dave.jiang@intel.com>
+ * Copyright (C) 2004 Intel Corp.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+
+
+/*
+ * IQ80332 specific IO mappings
+ *
+ * We use RedBoot's setup for the onboard devices.
+ */
+
+void __init iq80332_map_io(void)
+{
+	iop331_map_io();
+}
diff --git a/arch/arm/mach-iop3xx/iq80332-pci.c b/arch/arm/mach-iop3xx/iq80332-pci.c
new file mode 100644
index 0000000..b9807aa
--- /dev/null
+++ b/arch/arm/mach-iop3xx/iq80332-pci.c
@@ -0,0 +1,125 @@
+/*
+ * arch/arm/mach-iop3xx/iq80332-pci.c
+ *
+ * PCI support for the Intel IQ80332 reference board
+ *
+ * Author: Dave Jiang <dave.jiang@intel.com>
+ * Copyright (C) 2004 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+/*
+ * The following macro is used to lookup irqs in a standard table
+ * format for those systems that do not already have PCI
+ * interrupts properly routed.  We assume 1 <= pin <= 4
+ */
+#define PCI_IRQ_TABLE_LOOKUP(minid,maxid)	\
+({ int _ctl_ = -1;				\
+   unsigned int _idsel = idsel - minid;		\
+   if (_idsel <= maxid)				\
+      _ctl_ = pci_irq_table[_idsel][pin-1];	\
+   _ctl_; })
+
+#define INTA	IRQ_IQ80332_INTA
+#define INTB	IRQ_IQ80332_INTB
+#define INTC	IRQ_IQ80332_INTC
+#define INTD	IRQ_IQ80332_INTD
+
+//#define INTE	IRQ_IQ80332_I82544
+
+static inline int __init
+iq80332_map_irq(struct pci_dev *dev, u8 idsel, u8 pin)
+{
+	static int pci_irq_table[][8] = {
+		/*
+		 * PCI IDSEL/INTPIN->INTLINE
+		 * A       B       C       D
+		 */
+		{-1,   -1,   -1,   -1},
+		{-1,   -1,   -1,   -1},
+		{-1,   -1,   -1,   -1},
+		{INTA, INTB, INTC, INTD}, /* PCI-X Slot */
+		{-1,   -1,   -1,   -1},
+		{INTC, INTC, INTC, INTC}, /* GigE  */
+		{-1,   -1,   -1,   -1},
+		{-1,   -1,   -1,   -1},
+	};
+
+	BUG_ON(pin < 1 || pin > 4);
+
+	return PCI_IRQ_TABLE_LOOKUP(1, 7);
+}
+
+static int iq80332_setup(int nr, struct pci_sys_data *sys)
+{
+	struct resource *res;
+
+	if(nr != 0)
+		return 0;
+
+	res = kmalloc(sizeof(struct resource) * 2, GFP_KERNEL);
+	if (!res)
+		panic("PCI: unable to alloc resources");
+
+	memset(res, 0, sizeof(struct resource) * 2);
+
+	res[0].start = IOP331_PCI_LOWER_IO_VA;
+	res[0].end   = IOP331_PCI_UPPER_IO_VA;
+	res[0].name  = "IQ80332 PCI I/O Space";
+	res[0].flags = IORESOURCE_IO;
+
+	res[1].start = IOP331_PCI_LOWER_MEM_PA;
+	res[1].end   = IOP331_PCI_UPPER_MEM_PA;
+	res[1].name  = "IQ80332 PCI Memory Space";
+	res[1].flags = IORESOURCE_MEM;
+
+	request_resource(&ioport_resource, &res[0]);
+	request_resource(&iomem_resource, &res[1]);
+
+	sys->mem_offset = IOP331_PCI_MEM_OFFSET;
+	sys->io_offset  = IOP331_PCI_IO_OFFSET;
+
+	sys->resource[0] = &res[0];
+	sys->resource[1] = &res[1];
+	sys->resource[2] = NULL;
+
+	return 1;
+}
+
+static void iq80332_preinit(void)
+{
+	iop331_init();
+}
+
+static struct hw_pci iq80332_pci __initdata = {
+	.swizzle	= pci_std_swizzle,
+	.nr_controllers = 1,
+	.setup		= iq80332_setup,
+	.scan		= iop331_scan_bus,
+	.preinit	= iq80332_preinit,
+	.map_irq	= iq80332_map_irq
+};
+
+static int __init iq80332_pci_init(void)
+{
+	if (machine_is_iq80332())
+		pci_common_init(&iq80332_pci);
+	return 0;
+}
+
+subsys_initcall(iq80332_pci_init);
+
+
+
+