dm: x86: pci: Add a PCI driver for driver model

Add a simple x86 PCI driver which uses standard functions provided by the
architecture.

Signed-off-by: Simon Glass <sjg@chromium.org>
diff --git a/arch/x86/cpu/pci.c b/arch/x86/cpu/pci.c
index c6c5267..e23b233 100644
--- a/arch/x86/cpu/pci.c
+++ b/arch/x86/cpu/pci.c
@@ -10,9 +10,11 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <errno.h>
 #include <malloc.h>
 #include <pci.h>
+#include <asm/io.h>
 #include <asm/pci.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -111,3 +113,41 @@
 {
 	pci_hose_write_config_dword(get_hose(), dev, where, value);
 }
+
+int pci_x86_read_config(struct udevice *bus, pci_dev_t bdf, uint offset,
+			ulong *valuep, enum pci_size_t size)
+{
+	outl(bdf | (offset & 0xfc) | PCI_CFG_EN, PCI_REG_ADDR);
+	switch (size) {
+	case PCI_SIZE_8:
+		*valuep = inb(PCI_REG_DATA + (offset & 3));
+		break;
+	case PCI_SIZE_16:
+		*valuep = inw(PCI_REG_DATA + (offset & 2));
+		break;
+	case PCI_SIZE_32:
+		*valuep = inl(PCI_REG_DATA);
+		break;
+	}
+
+	return 0;
+}
+
+int pci_x86_write_config(struct udevice *bus, pci_dev_t bdf, uint offset,
+			 ulong value, enum pci_size_t size)
+{
+	outl(bdf | (offset & 0xfc) | PCI_CFG_EN, PCI_REG_ADDR);
+	switch (size) {
+	case PCI_SIZE_8:
+		outb(value, PCI_REG_DATA + (offset & 3));
+		break;
+	case PCI_SIZE_16:
+		outw(value, PCI_REG_DATA + (offset & 2));
+		break;
+	case PCI_SIZE_32:
+		outl(value, PCI_REG_DATA);
+		break;
+	}
+
+	return 0;
+}
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index b277b3d..a1969ed 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -8,6 +8,8 @@
 #ifndef _PCI_I386_H_
 #define _PCI_I386_H_
 
+#include <pci.h>
+
 /* bus mapping constants (used for PCI core initialization) */
 #define PCI_REG_ADDR	0xcf8
 #define PCI_REG_DATA	0xcfc
@@ -56,6 +58,12 @@
 void x86_pci_write_config16(pci_dev_t dev, unsigned where, unsigned value);
 void x86_pci_write_config32(pci_dev_t dev, unsigned where, unsigned value);
 
+int pci_x86_read_config(struct udevice *bus, pci_dev_t bdf, uint offset,
+			ulong *valuep, enum pci_size_t size);
+
+int pci_x86_write_config(struct udevice *bus, pci_dev_t bdf, uint offset,
+			 ulong value, enum pci_size_t size);
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _PCI_I386_H_ */
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index c17f7f0..67a34d8 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -17,7 +17,9 @@
 obj-y += cmd_mtrr.o
 obj-$(CONFIG_SYS_PCAT_INTERRUPTS) += pcat_interrupts.o
 obj-$(CONFIG_SYS_PCAT_TIMER) += pcat_timer.o
+ifndef CONFIG_DM_PCI
 obj-$(CONFIG_PCI) += pci_type1.o
+endif
 obj-y	+= relocate.o
 obj-y += physmem.o
 obj-$(CONFIG_X86_RAMTEST) += ramtest.o
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index c1c2ae3c..adc238f 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -9,6 +9,7 @@
 obj-$(CONFIG_PCI) += pci-uclass.o pci_compat.o
 obj-$(CONFIG_PCI_SANDBOX) += pci_sandbox.o
 obj-$(CONFIG_SANDBOX) += pci-emul-uclass.o
+obj-$(CONFIG_X86) += pci_x86.o
 else
 obj-$(CONFIG_PCI) += pci.o
 endif
diff --git a/drivers/pci/pci_x86.c b/drivers/pci/pci_x86.c
new file mode 100644
index 0000000..901bdca
--- /dev/null
+++ b/drivers/pci/pci_x86.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <pci.h>
+
+static const struct dm_pci_ops x86_pci_ops = {
+};
+
+static const struct udevice_id x86_pci_ids[] = {
+	{ .compatible = "x86,pci" },
+	{ }
+};
+
+U_BOOT_DRIVER(pci_x86) = {
+	.name	= "pci_x86",
+	.id	= UCLASS_PCI,
+	.of_match = x86_pci_ids,
+	.ops	= &x86_pci_ops,
+};