 arch/arm/common/Makefile          |    1 
 arch/arm/common/it8152.c          |  159 +++++++++++++++++++++++++++++++++++++
 arch/arm/kernel/bios32.c          |   35 +++++++-
 include/asm-arm/hardware/it8152.h |   88 ++++++++++++++++++++
 include/linux/pci_ids.h           |    1 
 5 files changed, 281 insertions(+), 3 deletions(-)

diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index e1289a2..314b6cf 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_SHARPSL_PM)	+= sharpsl_pm.o
 obj-$(CONFIG_SHARP_SCOOP)	+= scoop.o
 obj-$(CONFIG_ARCH_IXP2000)	+= uengine.o
 obj-$(CONFIG_ARCH_IXP23XX)	+= uengine.o
+obj-$(CONFIG_PCI_HOST_ITE8152)	+= it8152.o
diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c
new file mode 100644
index 0000000..ff4cb32
--- /dev/null
+++ b/arch/arm/common/it8152.c
@@ -0,0 +1,159 @@
+/*
+ * linux/arch/arm/common/it8152.c
+ * PCI functions for IT8152
+ *
+ * Copyright (C) 2002-2006 CompuLab, Ltd.
+ *  Daniel Heifetz <danny@compulab.co.il>
+ *  Mike Rapoport <mike@compulab.co.il>
+ *
+ * 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/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/ptrace.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <asm/mach/map.h>
+
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/hardware/it8152.h>
+
+#define MAX_SLOTS		21
+
+#ifdef CONFIG_CM_X270_SB2XX
+#define CARDBUS_FRAME_ON() \
+	do { \
+		if(devfn!=0) \
+			IT8152_GPIO_GPLR=0x00; \
+	} while (0);
+#define CARDBUS_FRAME_OFF() \
+	do { \
+		if(devfn!=0) \
+			IT8152_GPIO_GPLR=0x20;
+	} while (0);
+#else
+#define CARDBUS_FRAME_ON()	do {} while(0);
+#define CARDBUS_FRAME_OFF()	do {} while(0);
+#endif
+
+static unsigned long
+it8152_pci_dev_base_address(struct pci_bus *bus, unsigned int devfn)
+{
+	unsigned long addr = 0;
+
+	if (bus->number == 0) {
+			if (devfn < PCI_DEVFN(MAX_SLOTS, 0))
+				addr = (devfn << 8);
+	} else
+		addr = (bus->number << 16) | (devfn << 8);
+
+	return addr;
+}
+
+static int
+it8152_pci_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+		    int size, u32 *value)
+{
+	unsigned long addr = it8152_pci_dev_base_address(bus, devfn);
+	u32 v;
+	int shift;
+
+	CARDBUS_FRAME_ON();
+	shift = (where & 3);
+
+	IT8152_PCI_CFG_ADDR = (addr + where);
+	v = (IT8152_PCI_CFG_DATA  >> (8 * (shift)));	
+
+	*value = v;
+
+	CARDBUS_FRAME_OFF();
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int
+it8152_pci_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+		     int size, u32 value)
+{
+	unsigned long addr = it8152_pci_dev_base_address(bus, devfn);
+	u32 v, vtemp, mask=0;
+	int shift;
+
+	CARDBUS_FRAME_ON();
+
+	if(size==1) mask=0xff;
+	if(size==2) mask=0xffff;
+
+	shift = (where & 3);
+
+	IT8152_PCI_CFG_ADDR = addr + where;
+	vtemp = IT8152_PCI_CFG_DATA;
+
+	if(mask) vtemp &= ~(mask << (8 * shift));
+	else vtemp = 0;
+
+	v = (value << (8 * shift));
+	IT8152_PCI_CFG_ADDR = addr + where;
+	IT8152_PCI_CFG_DATA  = (v | vtemp);
+
+	CARDBUS_FRAME_OFF();
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops it8152_ops = {
+	.read = it8152_pci_read_config,
+	.write = it8152_pci_write_config,
+};
+
+static struct resource it8152_io = {
+	.name	= "IT8152 PCI I/O region",
+	.flags	= IORESOURCE_IO,
+};
+
+static struct resource it8152_mem1 = {
+	.name	= "First IT8152 PCI memory region",
+	.start	= 0x10000000,
+	.end	= 0x13e00000,
+	.flags	= IORESOURCE_MEM,
+};
+
+
+int __init it8152_pci_setup(int nr, struct pci_sys_data *sys)
+{
+	it8152_io.start = IT8152_IO_BASE + 0x12000;
+ 	it8152_io.end	= IT8152_IO_BASE + 0x100000;
+
+	if (request_resource(&ioport_resource, &it8152_io)) {
+		printk(KERN_ERR "PCI: unable to allocate IO region\n");
+		return -EBUSY;
+	}
+	if (request_resource(&iomem_resource, &it8152_mem1)) {
+		printk(KERN_ERR "PCI: unable to allocate memory region\n");
+		return -EBUSY;
+	}
+
+	sys->resource[0] = &it8152_io;
+	sys->resource[1] = &it8152_mem1;
+
+	return 1;  
+}
+			  
+
+struct pci_bus * __init it8152_pci_scan_bus(int nr, struct pci_sys_data *sys)
+{
+	return pci_scan_bus(nr, &it8152_ops, sys);
+}
+
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index 964faac..73893f0 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -279,6 +279,33 @@ static void __devinit pci_fixup_cy82c693
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, pci_fixup_cy82c693);
 
+static void __init pci_fixup_it8152(struct pci_dev *dev) 
+{
+	int i;
+	if ((dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) {
+		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+			dev->resource[i].start = 0;
+			dev->resource[i].end   = 0;
+			dev->resource[i].flags = 0;
+		}
+	}
+	if (dev->class == 0x68000) {
+		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+			dev->resource[i].start = 0;
+			dev->resource[i].end   = 0;
+			dev->resource[i].flags = 0;
+		}
+	}
+	if (dev->class == 0x80103) {
+		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+			dev->resource[i].start = 0;
+			dev->resource[i].end   = 0;
+			dev->resource[i].flags = 0;
+		}
+	}
+}	
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_IT8152, pci_fixup_it8152);
+
 void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
 {
 	if (debug_pci)
@@ -292,9 +319,11 @@ void __devinit pcibios_update_irq(struct
  */
 static inline int pdev_bad_for_parity(struct pci_dev *dev)
 {
-	return (dev->vendor == PCI_VENDOR_ID_INTERG &&
-		(dev->device == PCI_DEVICE_ID_INTERG_2000 ||
-		 dev->device == PCI_DEVICE_ID_INTERG_2010));
+	return ((dev->vendor == PCI_VENDOR_ID_INTERG &&
+		 (dev->device == PCI_DEVICE_ID_INTERG_2000 ||
+		  dev->device == PCI_DEVICE_ID_INTERG_2010)) ||
+		(dev->vendor == PCI_VENDOR_ID_ITE &&
+		 dev->device == PCI_DEVICE_ID_ITE_IT8152));
 }
 
 /*
diff --git a/include/asm-arm/hardware/it8152.h b/include/asm-arm/hardware/it8152.h
new file mode 100644
index 0000000..730a98b
--- /dev/null
+++ b/include/asm-arm/hardware/it8152.h
@@ -0,0 +1,88 @@
+/*
+ * linux/include/asm-arm/hardware/it8152.h
+ * PCI functions for IT8152
+ *
+ * Copyright (C) 2002-2006 CompuLab, Ltd.
+ *  Daniel Heifetz <danny@compulab.co.il>
+ *  Mike Rapoport <mike@compulab.co.il>
+ *
+ * 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.
+ */
+
+extern unsigned long it8152_base_address;
+
+#define IT8152_IO_BASE		(it8152_base_address + 0x03e00000)
+#define IT8152_CFGREG_BASE	(it8152_base_address + 0x03f00000)
+
+#define IT8152_SHORT_IO(x)	(*((volatile unsigned short *)(IT8152_CFGREG_BASE+(x))))
+#define IT8152_LONG_IO(x)	(*((volatile unsigned long *)(IT8152_CFGREG_BASE+(x))))
+
+#define IT8152_PCI_MEMBASE	(*((volatile unsigned long *)(it8152_base_address)))
+#define IT8152_PCI_IACK		(*((volatile unsigned long *)(it8152_base_address + 0x3f00808)))
+#define IT8152_PCI_CFG_ADDR	(*((volatile unsigned long *)(it8152_base_address + 0x3f00800)))
+#define IT8152_PCI_CFG_DATA	(*((volatile unsigned long *)(it8152_base_address + 0x3f00804)))
+
+#define IT_BUSNUM_SHF                   16
+#define IT_DEVNUM_SHF                   11
+#define IT_FUNCNUM_SHF                  8
+#define IT_REGNUM_SHF                   2
+
+/* Power management & PLL registers */
+#define IT8152_PMPLL_DSR		IT8152_LONG_IO(0x00)
+#define IT8152_PMPLL_DSSR		IT8152_LONG_IO(0x04)
+#define IT8152_PMPLL_PLLCR		IT8152_LONG_IO(0x20)
+#define IT8152_PMPLL_MFSR		IT8152_LONG_IO(0x24)
+
+/* Memory controller */
+#define IT8152_MC_REG_OFFSET		0x100
+
+#define IT8152_MC_SDCR			IT8152_LONG_IO(IT8152_MC_REG_OFFSET + 0x00)
+#define IT8152_MC_PCICR			IT8152_LONG_IO(IT8152_MC_REG_OFFSET + 0x04)
+
+/* Interrupt related definitions */
+#define IT8152_INTC_REG_OFFSET		0x300
+
+#define IT8152_INTC_LDCNIRR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x00)
+#define IT8152_INTC_LDPNIRR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x04)
+#define IT8152_INTC_LDCNIMR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x08)
+#define IT8152_INTC_LDPNIMR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x0C)
+#define IT8152_INTC_LDNITR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x10)
+#define IT8152_INTC_LDNIAR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x14)
+#define IT8152_INTC_LPCNIRR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x20)
+#define IT8152_INTC_LPPNIRR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x24)
+#define IT8152_INTC_LPCNIMR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x28)
+#define IT8152_INTC_LPPNIMR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x2C)
+#define IT8152_INTC_LPNITR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x30)
+#define IT8152_INTC_LPNIAR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x34)
+#define IT8152_INTC_PDCNIRR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x40)
+#define IT8152_INTC_PDPNIRR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x44)
+#define IT8152_INTC_PDCNIMR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x48)
+#define IT8152_INTC_PDPNIMR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x4C)
+#define IT8152_INTC_PDNITR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x50)
+#define IT8152_INTC_PDNIAR		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0x54)
+#define IT8152_INTC_INTC_TYPER		IT8152_LONG_IO(IT8152_INTC_REG_OFFSET + 0xFC)
+
+#define IT8152_UART_BASE		IT8152_LONG_IO(0x200)
+
+#define IT8152_GPIO_REG_OFFSET		0x500
+
+#define IT8152_GPIO_GPLR		IT8152_LONG_IO(IT8152_GPIO_REG_OFFSET)
+#define IT8152_GPIO_GPCR12		IT8152_LONG_IO(IT8152_GPIO_REG_OFFSET + 0x04)
+#define IT8152_GPIO_GPCR34		IT8152_LONG_IO(IT8152_GPIO_REG_OFFSET + 0x08)
+
+/* Interrupt bit definitions */
+#define PCISERR_BIT	(1<<14)
+#define H2PTADR_BIT	(1<<13)
+#define H2PMAR_BIT	(1<<12)
+#define PCI_INTD_BIT	(1<<11)
+#define PCI_INTC_BIT	(1<<10)
+#define PCI_INTB_BIT	(1<<9)
+#define PCI_INTA_BIT	(1<<8)
+#define CDMA_INT_BIT	(1<<2)
+#define USB_INT_BIT	(1<<1)
+#define AUDIO_INT_BIT	(1<<0)
+
+/* IT8152 UART */
+#define ITESER_BIT	(1<<5)
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 685081c..aa11b5a 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1612,6 +1612,7 @@ #define PCI_DEVICE_ID_EFFICEON		0x0060
 #define PCI_VENDOR_ID_ROCKWELL		0x127A
 
 #define PCI_VENDOR_ID_ITE		0x1283
+#define PCI_DEVICE_ID_ITE_IT8152        0x8152
 #define PCI_DEVICE_ID_ITE_IT8172G	0x8172
 #define PCI_DEVICE_ID_ITE_IT8172G_AUDIO 0x0801
 #define PCI_DEVICE_ID_ITE_8211		0x8211

