All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v2 0/22] Add driver model support for PCI
@ 2015-03-05 19:25 Simon Glass
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 01/22] sandbox: Update device tree 'reg' properties for I2C and SPI Simon Glass
                   ` (22 more replies)
  0 siblings, 23 replies; 53+ messages in thread
From: Simon Glass @ 2015-03-05 19:25 UTC (permalink / raw)
  To: u-boot


This series is a collection of changes in core DM, sandbox, x86 and PCI code
to implement a PCI uclass and associated operations. Some basic tests are
provided as well.

As is becoming common with DM conversions, the existing structure (here
struct pci_controller) becomes per-bus uclass data. This allows the concept
of a 'hose' (generally a PCI host controller and a bus) to continue to exist
in the interim, even if it should not be needed in the end. This makes it
much easier to convert over existing code.

PCI buses are not scanned in the bind() method but only later when probe()
is called. This will be automatic if you access a bus, but it does mean that
if PCI is not used it will not be touched, in keeping with U-Boot's lazy-
init philosophy.

The existing 'pciauto' bus configuration code is still used, although it now
uses DM underneath. It works exclusively by reading and writing PCI config
and does not refer to DM data structures. The one change is to drop use of
the hose->current_busno field which is no longer required. The fact that
file works largely as before is an indication that a good level of
compatibility is achieved between DM and legacy PCI.

In order to support testing of PCI I/O and memory space, support has been
added to sandbox to allow mapping of these. This allows commands like 'md'
and 'iod' to display data from mapped PCI devices. Similarly, it is possible
to make changes to this space. This support relies on the existing
map_sysmem() and unmap_sysmem() calls which are now fairly widespread in
U-Boot.

Apart from the driver model tests (run with ./test/dm/test-dm.sh) you can
try out these commands which use the new 'swap_case' test device:

../u-boot -d b/sandbox/u-boot.dtb
....
=> iow.b 20000000 2
=> iod.b 20000000
0000: 02
=> mw.l 10000000 64436241
=> md.l 10000000 1
10000000: 44634261                               aBcD
=>

This shows an I/O access to 20000000, setting the value 2 which means to
swap the case. Then 'AbCd' is written to the memory space at 10000000 and
'aBcD' is read back.

The 'pci' command can be used as before.

Most existing PCI functions (in pci.h) still work, but route through driver
model. The file drivers/pci/pci.c is replaced when driver model is enabled
so not everything is present. A new pci_common.c file holds functions common
to driver model and the old system, and pci_compat.c contains functions I
would like to eventually deprecate.

Two x86 boards (coreboot and chromebook_link) are converted over to use
driver model for PCI.

Core driver model changes include:
- Addition of a new pre_probe() method for the uclass to set up devices just
before the device's probe() method is called
- A change in the ordering of when a device is marked as probed
- A dev_get_uclass_priv() accessor
- A tweak to the 'dm uclass' command to improve sequence number display

Notably missing from this series are functions to access PCI devices using
a 'struct udevice *'. Where there is no device tree entry for a bus device,
a generic PCI device is created in driver model to mirror the device, as
with I2C and SPI. Future work could add more real devices to x86 and create
a demand for these sorts of functions. Also we might store things like the
PCI base address registers (BARs) in data structures if there is a need.
These things are probably best developed as a need arises to avoid creating
infrastructure and overhead that may not be used.

This series is available at u-boot-dm.git branch pci-working.

Changes in v2:
- Update root node #size=cells to 1 in this patch
- Add a new patch with a CPU init function which can use driver model
- Use the new arch_cpu_init_dm() function instead of something x86-specific
- Add -ve sign before ENXIO

Simon Glass (22):
  sandbox: Update device tree 'reg' properties for I2C and SPI
  fdt: Export fdtdec_get_number() for general use
  x86: Add a x86_ prefix to the x86-specific PCI functions
  dm: Add a new CPU init function which can use driver model
  x86: Split up arch_cpu_init()
  Correct map_sysmem() logic in do_mem_mw()
  fdt: Tighten up error handling in fdtdec_get_pci_addr()
  dm: core: Add dev_get_uclass_priv() to access uclass private data
  dm: core: Mark device as active before calling its probe() method
  dm: core: Add a uclass pre_probe() method for devices
  dm: Show both allocated and requested seq numbers in 'dm uclass'
  dm: pci: Move common PCI functions into their own file
  dm: pci: Add a uclass for PCI
  dm: sandbox: pci: Add PCI support for sandbox
  dm: sandbox: Add a simple PCI driver
  dm: sandbox: pci: Add a PCI emulation uclass
  dm: sandbox: Add a emulated PCI device as an example
  dm: sandbox: pci: Enable PCI for sandbox
  dm: x86: pci: Add a PCI driver for driver model
  dm: x86: pci: Convert coreboot to use driver model for pci
  dm: x86: pci: Convert chromebook_link to use driver model for pci
  dm: pci: Add driver model tests for PCI

 arch/sandbox/Kconfig                          |   7 +
 arch/sandbox/cpu/cpu.c                        |  37 +-
 arch/sandbox/dts/sandbox.dts                  |  26 +-
 arch/sandbox/include/asm/io.h                 |  16 +-
 arch/sandbox/include/asm/processor.h          |  12 +
 arch/sandbox/include/asm/test.h               |   7 +-
 arch/sandbox/include/asm/u-boot-sandbox.h     |  48 ++
 arch/sandbox/lib/Makefile                     |   2 +-
 arch/sandbox/lib/pci_io.c                     | 138 ++++++
 arch/x86/cpu/baytrail/early_uart.c            |   5 +-
 arch/x86/cpu/coreboot/pci.c                   |  63 +--
 arch/x86/cpu/ivybridge/bd82x6x.c              |  56 ++-
 arch/x86/cpu/ivybridge/cpu.c                  |  62 +--
 arch/x86/cpu/ivybridge/early_init.c           |  58 +--
 arch/x86/cpu/ivybridge/early_me.c             |  12 +-
 arch/x86/cpu/ivybridge/gma.c                  |   4 +-
 arch/x86/cpu/ivybridge/lpc.c                  |  75 +--
 arch/x86/cpu/ivybridge/northbridge.c          |   6 +-
 arch/x86/cpu/ivybridge/pch.c                  |   4 +-
 arch/x86/cpu/ivybridge/pci.c                  |  85 ++--
 arch/x86/cpu/ivybridge/report_platform.c      |   4 +-
 arch/x86/cpu/ivybridge/sata.c                 |  61 +--
 arch/x86/cpu/ivybridge/sdram.c                |  20 +-
 arch/x86/cpu/ivybridge/usb_ehci.c             |   4 +-
 arch/x86/cpu/ivybridge/usb_xhci.c             |   8 +-
 arch/x86/cpu/pci.c                            |  52 ++-
 arch/x86/cpu/quark/quark.c                    |   4 +-
 arch/x86/cpu/queensbay/tnc.c                  |   4 +-
 arch/x86/dts/chromebook_link.dts              |  10 +-
 arch/x86/include/asm/arch-ivybridge/bd82x6x.h |   1 -
 arch/x86/include/asm/pci.h                    |  20 +-
 arch/x86/lib/Makefile                         |   2 +
 arch/x86/lib/bios_interrupts.c                |  12 +-
 board/google/chromebook_link/link.c           |   9 +
 common/board_f.c                              |   6 +
 common/board_r.c                              |   2 +
 common/cmd_mem.c                              |   7 +-
 common/cmd_pci.c                              |  14 +-
 common/cmd_sf.c                               |   2 +-
 common/cros_ec.c                              |   2 +-
 configs/chromebook_link_defconfig             |   1 +
 configs/chromebox_panther_defconfig           |   1 +
 configs/coreboot-x86_defconfig                |   1 +
 configs/sandbox_defconfig                     |   3 +
 doc/driver-model/pci-info.txt                 |  70 +++
 drivers/core/device.c                         |  19 +-
 drivers/core/uclass.c                         |  10 +-
 drivers/gpio/at91_gpio.c                      |   2 +-
 drivers/gpio/bcm2835_gpio.c                   |   2 +-
 drivers/gpio/gpio-uclass.c                    |  22 +-
 drivers/gpio/intel_ich6_gpio.c                |  18 +-
 drivers/gpio/mxc_gpio.c                       |   2 +-
 drivers/gpio/omap_gpio.c                      |   2 +-
 drivers/gpio/s5p_gpio.c                       |   2 +-
 drivers/gpio/sandbox.c                        |   6 +-
 drivers/gpio/sunxi_gpio.c                     |   2 +-
 drivers/gpio/tegra_gpio.c                     |   2 +-
 drivers/i2c/i2c-uclass.c                      |   6 +-
 drivers/i2c/sandbox_i2c.c                     |   2 +-
 drivers/misc/Makefile                         |   1 +
 drivers/misc/cros_ec.c                        |   6 +-
 drivers/misc/cros_ec_i2c.c                    |   2 +-
 drivers/misc/cros_ec_sandbox.c                |   2 +-
 drivers/misc/cros_ec_spi.c                    |   4 +-
 drivers/misc/swap_case.c                      | 285 ++++++++++++
 drivers/mtd/spi/sf-uclass.c                   |   2 +-
 drivers/mtd/spi/sf_probe.c                    |   8 +-
 drivers/pci/Kconfig                           |  22 +
 drivers/pci/Makefile                          |  11 +-
 drivers/pci/pci-emul-uclass.c                 |  67 +++
 drivers/pci/pci-uclass.c                      | 639 ++++++++++++++++++++++++++
 drivers/pci/pci.c                             | 281 +----------
 drivers/pci/pci_auto.c                        |  16 +-
 drivers/pci/pci_common.c                      | 292 ++++++++++++
 drivers/pci/pci_compat.c                      |  43 ++
 drivers/pci/pci_sandbox.c                     |  79 ++++
 drivers/pci/pci_x86.c                         |  24 +
 drivers/serial/serial-uclass.c                |   4 +-
 drivers/spi/spi-uclass.c                      |   4 +-
 include/common.h                              |  11 +
 include/configs/sandbox.h                     |   4 +
 include/dm/device.h                           |  10 +
 include/dm/test.h                             |   1 +
 include/dm/uclass-id.h                        |   4 +
 include/dm/uclass-internal.h                  |   7 +-
 include/dm/uclass.h                           |   2 +
 include/fdtdec.h                              |  15 +-
 include/i2c.h                                 |   8 +-
 include/pci.h                                 | 411 ++++++++++++++++-
 lib/fdtdec.c                                  |   8 +-
 test/dm/Makefile                              |   1 +
 test/dm/cmd_dm.c                              |   4 +-
 test/dm/core.c                                |   9 +-
 test/dm/pci.c                                 |  59 +++
 test/dm/test-uclass.c                         |  16 +-
 test/dm/test.dts                              |  17 +
 96 files changed, 2842 insertions(+), 677 deletions(-)
 create mode 100644 arch/sandbox/include/asm/processor.h
 create mode 100644 arch/sandbox/lib/pci_io.c
 create mode 100644 doc/driver-model/pci-info.txt
 create mode 100644 drivers/misc/swap_case.c
 create mode 100644 drivers/pci/pci-emul-uclass.c
 create mode 100644 drivers/pci/pci-uclass.c
 create mode 100644 drivers/pci/pci_common.c
 create mode 100644 drivers/pci/pci_compat.c
 create mode 100644 drivers/pci/pci_sandbox.c
 create mode 100644 drivers/pci/pci_x86.c
 create mode 100644 test/dm/pci.c

-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 01/22] sandbox: Update device tree 'reg' properties for I2C and SPI
  2015-03-05 19:25 [U-Boot] [PATCH v2 0/22] Add driver model support for PCI Simon Glass
@ 2015-03-05 19:25 ` Simon Glass
  2015-03-09  8:57   ` Bin Meng
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 02/22] fdt: Export fdtdec_get_number() for general use Simon Glass
                   ` (21 subsequent siblings)
  22 siblings, 1 reply; 53+ messages in thread
From: Simon Glass @ 2015-03-05 19:25 UTC (permalink / raw)
  To: u-boot

We should have a size value for these. Add one in each case. This will
be needed for PCI.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2:
- Update root node #size=cells to 1 in this patch

 arch/sandbox/dts/sandbox.dts | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts
index 9ce31bf..d090ba8 100644
--- a/arch/sandbox/dts/sandbox.dts
+++ b/arch/sandbox/dts/sandbox.dts
@@ -2,7 +2,7 @@
 
 / {
 	#address-cells = <1>;
-	#size-cells = <0>;
+	#size-cells = <1>;
 
 	chosen {
 		stdout-path = "/serial";
@@ -144,7 +144,7 @@
 	i2c at 0 {
 		#address-cells = <1>;
 		#size-cells = <0>;
-		reg = <0>;
+		reg = <0 0>;
 		compatible = "sandbox,i2c";
 		clock-frequency = <400000>;
 		eeprom at 2c {
@@ -161,7 +161,7 @@
 	spi at 0 {
 		#address-cells = <1>;
 		#size-cells = <0>;
-		reg = <0>;
+		reg = <0 0>;
 		compatible = "sandbox,spi";
 		cs-gpios = <0>, <&gpio_a 0>;
 		flash at 0 {
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 02/22] fdt: Export fdtdec_get_number() for general use
  2015-03-05 19:25 [U-Boot] [PATCH v2 0/22] Add driver model support for PCI Simon Glass
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 01/22] sandbox: Update device tree 'reg' properties for I2C and SPI Simon Glass
@ 2015-03-05 19:25 ` Simon Glass
  2015-03-06 15:43   ` Tom Rini
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 03/22] x86: Add a x86_ prefix to the x86-specific PCI functions Simon Glass
                   ` (20 subsequent siblings)
  22 siblings, 1 reply; 53+ messages in thread
From: Simon Glass @ 2015-03-05 19:25 UTC (permalink / raw)
  To: u-boot

This function is missing a prototype but is more widey useful. Add it.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 include/fdtdec.h | 11 +++++++++++
 lib/fdtdec.c     |  2 +-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/include/fdtdec.h b/include/fdtdec.h
index 1233dfb..21bd6bb 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -386,6 +386,17 @@ s32 fdtdec_get_int(const void *blob, int node, const char *prop_name,
 		s32 default_val);
 
 /**
+ * Get a variable-sized number from a property
+ *
+ * This reads a number from one or more cells.
+ *
+ * @param ptr	Pointer to property
+ * @param cells	Number of cells containing the number
+ * @return the value in the cells
+ */
+u64 fdtdec_get_number(const fdt32_t *ptr, unsigned int cells);
+
+/**
  * Look up a 64-bit integer property in a node and return it. The property
  * must have at least 8 bytes of data (2 cells). The first two cells are
  * concatenated to form a 8 bytes value, where the first cell is top half and
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 21933e4..e47fa96 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -918,7 +918,7 @@ int fdtdec_read_fmap_entry(const void *blob, int node, const char *name,
 	return 0;
 }
 
-static u64 fdtdec_get_number(const fdt32_t *ptr, unsigned int cells)
+u64 fdtdec_get_number(const fdt32_t *ptr, unsigned int cells)
 {
 	u64 number = 0;
 
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 03/22] x86: Add a x86_ prefix to the x86-specific PCI functions
  2015-03-05 19:25 [U-Boot] [PATCH v2 0/22] Add driver model support for PCI Simon Glass
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 01/22] sandbox: Update device tree 'reg' properties for I2C and SPI Simon Glass
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 02/22] fdt: Export fdtdec_get_number() for general use Simon Glass
@ 2015-03-05 19:25 ` Simon Glass
  2015-03-20 23:14   ` Simon Glass
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 04/22] dm: Add a new CPU init function which can use driver model Simon Glass
                   ` (19 subsequent siblings)
  22 siblings, 1 reply; 53+ messages in thread
From: Simon Glass @ 2015-03-05 19:25 UTC (permalink / raw)
  To: u-boot

These functions currently use a generic name, but they are for x86 only.
This may introduce confusion and prevents U-Boot from using these names
more widely.

In fact it should be possible to remove these at some point and use
generic functions, but for now, rename them.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v2: None

 arch/x86/cpu/baytrail/early_uart.c       |  5 ++-
 arch/x86/cpu/ivybridge/bd82x6x.c         | 32 +++++++-------
 arch/x86/cpu/ivybridge/cpu.c             | 38 ++++++++--------
 arch/x86/cpu/ivybridge/early_init.c      | 58 +++++++++++++------------
 arch/x86/cpu/ivybridge/early_me.c        | 12 +++---
 arch/x86/cpu/ivybridge/gma.c             |  4 +-
 arch/x86/cpu/ivybridge/lpc.c             | 74 ++++++++++++++++----------------
 arch/x86/cpu/ivybridge/northbridge.c     |  6 +--
 arch/x86/cpu/ivybridge/pch.c             |  4 +-
 arch/x86/cpu/ivybridge/pci.c             |  4 +-
 arch/x86/cpu/ivybridge/report_platform.c |  4 +-
 arch/x86/cpu/ivybridge/sata.c            | 61 +++++++++++++-------------
 arch/x86/cpu/ivybridge/sdram.c           | 20 ++++-----
 arch/x86/cpu/ivybridge/usb_ehci.c        |  4 +-
 arch/x86/cpu/ivybridge/usb_xhci.c        |  8 ++--
 arch/x86/cpu/pci.c                       | 12 +++---
 arch/x86/cpu/quark/quark.c               |  4 +-
 arch/x86/cpu/queensbay/tnc.c             |  4 +-
 arch/x86/include/asm/pci.h               | 12 +++---
 arch/x86/lib/bios_interrupts.c           | 12 +++---
 drivers/gpio/intel_ich6_gpio.c           | 16 +++----
 21 files changed, 199 insertions(+), 195 deletions(-)

diff --git a/arch/x86/cpu/baytrail/early_uart.c b/arch/x86/cpu/baytrail/early_uart.c
index 4199210..b64a3a9 100644
--- a/arch/x86/cpu/baytrail/early_uart.c
+++ b/arch/x86/cpu/baytrail/early_uart.c
@@ -50,7 +50,7 @@ static void score_select_func(int pad, int func)
 	writel(reg, pconf0_addr);
 }
 
-static void pci_write_config32(int dev, unsigned int where, u32 value)
+static void x86_pci_write_config32(int dev, unsigned int where, u32 value)
 {
 	unsigned long addr;
 
@@ -62,7 +62,8 @@ static void pci_write_config32(int dev, unsigned int where, u32 value)
 int setup_early_uart(void)
 {
 	/* Enable the legacy UART hardware. */
-	pci_write_config32(PCI_DEV_CONFIG(0, LPC_DEV, LPC_FUNC), UART_CONT, 1);
+	x86_pci_write_config32(PCI_DEV_CONFIG(0, LPC_DEV, LPC_FUNC), UART_CONT,
+			       1);
 
 	/*
 	 * Set up the pads to the UART function. This allows the signals to
diff --git a/arch/x86/cpu/ivybridge/bd82x6x.c b/arch/x86/cpu/ivybridge/bd82x6x.c
index 65a17d3..56b19e3 100644
--- a/arch/x86/cpu/ivybridge/bd82x6x.c
+++ b/arch/x86/cpu/ivybridge/bd82x6x.c
@@ -22,36 +22,36 @@ void bd82x6x_pci_init(pci_dev_t dev)
 
 	debug("bd82x6x PCI init.\n");
 	/* Enable Bus Master */
-	reg16 = pci_read_config16(dev, PCI_COMMAND);
+	reg16 = x86_pci_read_config16(dev, PCI_COMMAND);
 	reg16 |= PCI_COMMAND_MASTER;
-	pci_write_config16(dev, PCI_COMMAND, reg16);
+	x86_pci_write_config16(dev, PCI_COMMAND, reg16);
 
 	/* This device has no interrupt */
-	pci_write_config8(dev, INTR, 0xff);
+	x86_pci_write_config8(dev, INTR, 0xff);
 
 	/* disable parity error response and SERR */
-	reg16 = pci_read_config16(dev, BCTRL);
+	reg16 = x86_pci_read_config16(dev, BCTRL);
 	reg16 &= ~(1 << 0);
 	reg16 &= ~(1 << 1);
-	pci_write_config16(dev, BCTRL, reg16);
+	x86_pci_write_config16(dev, BCTRL, reg16);
 
 	/* Master Latency Count must be set to 0x04! */
-	reg8 = pci_read_config8(dev, SMLT);
+	reg8 = x86_pci_read_config8(dev, SMLT);
 	reg8 &= 0x07;
 	reg8 |= (0x04 << 3);
-	pci_write_config8(dev, SMLT, reg8);
+	x86_pci_write_config8(dev, SMLT, reg8);
 
 	/* Will this improve throughput of bus masters? */
-	pci_write_config8(dev, PCI_MIN_GNT, 0x06);
+	x86_pci_write_config8(dev, PCI_MIN_GNT, 0x06);
 
 	/* Clear errors in status registers */
-	reg16 = pci_read_config16(dev, PSTS);
+	reg16 = x86_pci_read_config16(dev, PSTS);
 	/* reg16 |= 0xf900; */
-	pci_write_config16(dev, PSTS, reg16);
+	x86_pci_write_config16(dev, PSTS, reg16);
 
-	reg16 = pci_read_config16(dev, SECSTS);
+	reg16 = x86_pci_read_config16(dev, SECSTS);
 	/* reg16 |= 0xf900; */
-	pci_write_config16(dev, SECSTS, reg16);
+	x86_pci_write_config16(dev, SECSTS, reg16);
 }
 
 #define PCI_BRIDGE_UPDATE_COMMAND
@@ -59,7 +59,7 @@ void bd82x6x_pci_dev_enable_resources(pci_dev_t dev)
 {
 	uint16_t command;
 
-	command = pci_read_config16(dev, PCI_COMMAND);
+	command = x86_pci_read_config16(dev, PCI_COMMAND);
 	command |= PCI_COMMAND_IO;
 #ifdef PCI_BRIDGE_UPDATE_COMMAND
 	/*
@@ -67,7 +67,7 @@ void bd82x6x_pci_dev_enable_resources(pci_dev_t dev)
 	 * ROM and APICs to become invisible.
 	 */
 	debug("%x cmd <- %02x\n", dev, command);
-	pci_write_config16(dev, PCI_COMMAND, command);
+	x86_pci_write_config16(dev, PCI_COMMAND, command);
 #else
 	printf("%s cmd <- %02x (NOT WRITTEN!)\n", dev_path(dev), command);
 #endif
@@ -77,11 +77,11 @@ void bd82x6x_pci_bus_enable_resources(pci_dev_t dev)
 {
 	uint16_t ctrl;
 
-	ctrl = pci_read_config16(dev, PCI_BRIDGE_CONTROL);
+	ctrl = x86_pci_read_config16(dev, PCI_BRIDGE_CONTROL);
 	ctrl |= PCI_COMMAND_IO;
 	ctrl |= PCI_BRIDGE_CTL_VGA;
 	debug("%x bridge ctrl <- %04x\n", dev, ctrl);
-	pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl);
+	x86_pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl);
 
 	bd82x6x_pci_dev_enable_resources(dev);
 }
diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c
index e925310..5fd3753 100644
--- a/arch/x86/cpu/ivybridge/cpu.c
+++ b/arch/x86/cpu/ivybridge/cpu.c
@@ -167,21 +167,21 @@ static int enable_smbus(void)
 	dev = PCI_BDF(0x0, 0x1f, 0x3);
 
 	/* Check to make sure we've got the right device. */
-	value = pci_read_config16(dev, 0x0);
+	value = x86_pci_read_config16(dev, 0x0);
 	if (value != 0x8086) {
 		printf("SMBus controller not found\n");
 		return -ENOSYS;
 	}
 
 	/* Set SMBus I/O base. */
-	pci_write_config32(dev, SMB_BASE,
-			   SMBUS_IO_BASE | PCI_BASE_ADDRESS_SPACE_IO);
+	x86_pci_write_config32(dev, SMB_BASE,
+			       SMBUS_IO_BASE | PCI_BASE_ADDRESS_SPACE_IO);
 
 	/* Set SMBus enable. */
-	pci_write_config8(dev, HOSTC, HST_EN);
+	x86_pci_write_config8(dev, HOSTC, HST_EN);
 
 	/* Set SMBus I/O space enable. */
-	pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_IO);
+	x86_pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_IO);
 
 	/* Disable interrupt generation. */
 	outb(0, SMBUS_IO_BASE + SMBHSTCTL);
@@ -214,25 +214,25 @@ static void enable_usb_bar(void)
 	u32 cmd;
 
 	/* USB Controller 1 */
-	pci_write_config32(usb0, PCI_BASE_ADDRESS_0,
-			   PCH_EHCI0_TEMP_BAR0);
-	cmd = pci_read_config32(usb0, PCI_COMMAND);
+	x86_pci_write_config32(usb0, PCI_BASE_ADDRESS_0,
+			       PCH_EHCI0_TEMP_BAR0);
+	cmd = x86_pci_read_config32(usb0, PCI_COMMAND);
 	cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
-	pci_write_config32(usb0, PCI_COMMAND, cmd);
+	x86_pci_write_config32(usb0, PCI_COMMAND, cmd);
 
 	/* USB Controller 1 */
-	pci_write_config32(usb1, PCI_BASE_ADDRESS_0,
-			   PCH_EHCI1_TEMP_BAR0);
-	cmd = pci_read_config32(usb1, PCI_COMMAND);
+	x86_pci_write_config32(usb1, PCI_BASE_ADDRESS_0,
+			       PCH_EHCI1_TEMP_BAR0);
+	cmd = x86_pci_read_config32(usb1, PCI_COMMAND);
 	cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
-	pci_write_config32(usb1, PCI_COMMAND, cmd);
+	x86_pci_write_config32(usb1, PCI_COMMAND, cmd);
 
 	/* USB3 Controller */
-	pci_write_config32(usb3, PCI_BASE_ADDRESS_0,
-			   PCH_XHCI_TEMP_BAR0);
-	cmd = pci_read_config32(usb3, PCI_COMMAND);
+	x86_pci_write_config32(usb3, PCI_BASE_ADDRESS_0,
+			       PCH_XHCI_TEMP_BAR0);
+	cmd = x86_pci_read_config32(usb3, PCI_COMMAND);
 	cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
-	pci_write_config32(usb3, PCI_COMMAND, cmd);
+	x86_pci_write_config32(usb3, PCI_COMMAND, cmd);
 }
 
 static int report_bist_failure(void)
@@ -320,8 +320,8 @@ int print_cpuinfo(void)
 	gd->arch.pei_boot_mode = boot_mode;
 
 	/* TODO: Move this to the board or driver */
-	pci_write_config32(PCH_LPC_DEV, GPIO_BASE, DEFAULT_GPIOBASE | 1);
-	pci_write_config32(PCH_LPC_DEV, GPIO_CNTL, 0x10);
+	x86_pci_write_config32(PCH_LPC_DEV, GPIO_BASE, DEFAULT_GPIOBASE | 1);
+	x86_pci_write_config32(PCH_LPC_DEV, GPIO_CNTL, 0x10);
 
 	/* Print processor name */
 	name = cpu_get_name(processor_name);
diff --git a/arch/x86/cpu/ivybridge/early_init.c b/arch/x86/cpu/ivybridge/early_init.c
index eb8f613..9ca008e 100644
--- a/arch/x86/cpu/ivybridge/early_init.c
+++ b/arch/x86/cpu/ivybridge/early_init.c
@@ -17,10 +17,10 @@ static void sandybridge_setup_bars(pci_dev_t pch_dev, pci_dev_t lpc_dev)
 {
 	/* Setting up Southbridge. In the northbridge code. */
 	debug("Setting up static southbridge registers\n");
-	pci_write_config32(lpc_dev, PCH_RCBA_BASE, DEFAULT_RCBA | 1);
+	x86_pci_write_config32(lpc_dev, PCH_RCBA_BASE, DEFAULT_RCBA | 1);
 
-	pci_write_config32(lpc_dev, PMBASE, DEFAULT_PMBASE | 1);
-	pci_write_config8(lpc_dev, ACPI_CNTL, 0x80); /* Enable ACPI BAR */
+	x86_pci_write_config32(lpc_dev, PMBASE, DEFAULT_PMBASE | 1);
+	x86_pci_write_config8(lpc_dev, ACPI_CNTL, 0x80); /* Enable ACPI BAR */
 
 	debug("Disabling watchdog reboot\n");
 	setbits_le32(RCB_REG(GCS), 1 >> 5);	/* No reset */
@@ -28,25 +28,27 @@ static void sandybridge_setup_bars(pci_dev_t pch_dev, pci_dev_t lpc_dev)
 
 	/* Set up all hardcoded northbridge BARs */
 	debug("Setting up static registers\n");
-	pci_write_config32(pch_dev, EPBAR, DEFAULT_EPBAR | 1);
-	pci_write_config32(pch_dev, EPBAR + 4, (0LL + DEFAULT_EPBAR) >> 32);
-	pci_write_config32(pch_dev, MCHBAR, DEFAULT_MCHBAR | 1);
-	pci_write_config32(pch_dev, MCHBAR + 4, (0LL + DEFAULT_MCHBAR) >> 32);
+	x86_pci_write_config32(pch_dev, EPBAR, DEFAULT_EPBAR | 1);
+	x86_pci_write_config32(pch_dev, EPBAR + 4, (0LL + DEFAULT_EPBAR) >> 32);
+	x86_pci_write_config32(pch_dev, MCHBAR, DEFAULT_MCHBAR | 1);
+	x86_pci_write_config32(pch_dev, MCHBAR + 4,
+			       (0LL + DEFAULT_MCHBAR) >> 32);
 	/* 64MB - busses 0-63 */
-	pci_write_config32(pch_dev, PCIEXBAR, DEFAULT_PCIEXBAR | 5);
-	pci_write_config32(pch_dev, PCIEXBAR + 4,
-			   (0LL + DEFAULT_PCIEXBAR) >> 32);
-	pci_write_config32(pch_dev, DMIBAR, DEFAULT_DMIBAR | 1);
-	pci_write_config32(pch_dev, DMIBAR + 4, (0LL + DEFAULT_DMIBAR) >> 32);
+	x86_pci_write_config32(pch_dev, PCIEXBAR, DEFAULT_PCIEXBAR | 5);
+	x86_pci_write_config32(pch_dev, PCIEXBAR + 4,
+			       (0LL + DEFAULT_PCIEXBAR) >> 32);
+	x86_pci_write_config32(pch_dev, DMIBAR, DEFAULT_DMIBAR | 1);
+	x86_pci_write_config32(pch_dev, DMIBAR + 4,
+			       (0LL + DEFAULT_DMIBAR) >> 32);
 
 	/* Set C0000-FFFFF to access RAM on both reads and writes */
-	pci_write_config8(pch_dev, PAM0, 0x30);
-	pci_write_config8(pch_dev, PAM1, 0x33);
-	pci_write_config8(pch_dev, PAM2, 0x33);
-	pci_write_config8(pch_dev, PAM3, 0x33);
-	pci_write_config8(pch_dev, PAM4, 0x33);
-	pci_write_config8(pch_dev, PAM5, 0x33);
-	pci_write_config8(pch_dev, PAM6, 0x33);
+	x86_pci_write_config8(pch_dev, PAM0, 0x30);
+	x86_pci_write_config8(pch_dev, PAM1, 0x33);
+	x86_pci_write_config8(pch_dev, PAM2, 0x33);
+	x86_pci_write_config8(pch_dev, PAM3, 0x33);
+	x86_pci_write_config8(pch_dev, PAM4, 0x33);
+	x86_pci_write_config8(pch_dev, PAM5, 0x33);
+	x86_pci_write_config8(pch_dev, PAM6, 0x33);
 }
 
 static void sandybridge_setup_graphics(pci_dev_t pch_dev, pci_dev_t video_dev)
@@ -55,7 +57,7 @@ static void sandybridge_setup_graphics(pci_dev_t pch_dev, pci_dev_t video_dev)
 	u16 reg16;
 	u8 reg8;
 
-	reg16 = pci_read_config16(video_dev, PCI_DEVICE_ID);
+	reg16 = x86_pci_read_config16(video_dev, PCI_DEVICE_ID);
 	switch (reg16) {
 	case 0x0102: /* GT1 Desktop */
 	case 0x0106: /* GT1 Mobile */
@@ -75,7 +77,7 @@ static void sandybridge_setup_graphics(pci_dev_t pch_dev, pci_dev_t video_dev)
 	debug("Initialising Graphics\n");
 
 	/* Setup IGD memory by setting GGC[7:3] = 1 for 32MB */
-	reg16 = pci_read_config16(pch_dev, GGC);
+	reg16 = x86_pci_read_config16(pch_dev, GGC);
 	reg16 &= ~0x00f8;
 	reg16 |= 1 << 3;
 	/* Program GTT memory by setting GGC[9:8] = 2MB */
@@ -83,13 +85,13 @@ static void sandybridge_setup_graphics(pci_dev_t pch_dev, pci_dev_t video_dev)
 	reg16 |= 2 << 8;
 	/* Enable VGA decode */
 	reg16 &= ~0x0002;
-	pci_write_config16(pch_dev, GGC, reg16);
+	x86_pci_write_config16(pch_dev, GGC, reg16);
 
 	/* Enable 256MB aperture */
-	reg8 = pci_read_config8(video_dev, MSAC);
+	reg8 = x86_pci_read_config8(video_dev, MSAC);
 	reg8 &= ~0x06;
 	reg8 |= 0x02;
-	pci_write_config8(video_dev, MSAC, reg8);
+	x86_pci_write_config8(video_dev, MSAC, reg8);
 
 	/* Erratum workarounds */
 	reg32 = readl(MCHBAR_REG(0x5f00));
@@ -124,22 +126,22 @@ void sandybridge_early_init(int chipset_type)
 	u8 reg8;
 
 	/* Device ID Override Enable should be done very early */
-	capid0_a = pci_read_config32(pch_dev, 0xe4);
+	capid0_a = x86_pci_read_config32(pch_dev, 0xe4);
 	if (capid0_a & (1 << 10)) {
-		reg8 = pci_read_config8(pch_dev, 0xf3);
+		reg8 = x86_pci_read_config8(pch_dev, 0xf3);
 		reg8 &= ~7; /* Clear 2:0 */
 
 		if (chipset_type == SANDYBRIDGE_MOBILE)
 			reg8 |= 1; /* Set bit 0 */
 
-		pci_write_config8(pch_dev, 0xf3, reg8);
+		x86_pci_write_config8(pch_dev, 0xf3, reg8);
 	}
 
 	/* Setup all BARs required for early PCIe and raminit */
 	sandybridge_setup_bars(pch_dev, lpc_dev);
 
 	/* Device Enable */
-	pci_write_config32(pch_dev, DEVEN, DEVEN_HOST | DEVEN_IGD);
+	x86_pci_write_config32(pch_dev, DEVEN, DEVEN_HOST | DEVEN_IGD);
 
 	sandybridge_setup_graphics(pch_dev, video_dev);
 }
diff --git a/arch/x86/cpu/ivybridge/early_me.c b/arch/x86/cpu/ivybridge/early_me.c
index b24dea1..356bbb4 100644
--- a/arch/x86/cpu/ivybridge/early_me.c
+++ b/arch/x86/cpu/ivybridge/early_me.c
@@ -29,7 +29,7 @@ static inline void pci_read_dword_ptr(void *ptr, int offset)
 {
 	u32 dword;
 
-	dword = pci_read_config32(PCH_ME_DEV, offset);
+	dword = x86_pci_read_config32(PCH_ME_DEV, offset);
 	memcpy(ptr, &dword, sizeof(dword));
 }
 
@@ -37,7 +37,7 @@ static inline void pci_write_dword_ptr(void *ptr, int offset)
 {
 	u32 dword = 0;
 	memcpy(&dword, ptr, sizeof(dword));
-	pci_write_config32(PCH_ME_DEV, offset, dword);
+	x86_pci_write_config32(PCH_ME_DEV, offset, dword);
 }
 
 void intel_early_me_status(void)
@@ -101,7 +101,7 @@ static inline void set_global_reset(int enable)
 {
 	u32 etr3;
 
-	etr3 = pci_read_config32(PCH_LPC_DEV, ETR3);
+	etr3 = x86_pci_read_config32(PCH_LPC_DEV, ETR3);
 
 	/* Clear CF9 Without Resume Well Reset Enable */
 	etr3 &= ~ETR3_CWORWRE;
@@ -112,7 +112,7 @@ static inline void set_global_reset(int enable)
 	else
 		etr3 &= ~ETR3_CF9GR;
 
-	pci_write_config32(PCH_LPC_DEV, ETR3, etr3);
+	x86_pci_write_config32(PCH_LPC_DEV, ETR3, etr3);
 }
 
 int intel_early_me_init_done(u8 status)
@@ -127,8 +127,8 @@ int intel_early_me_init_done(u8 status)
 	};
 
 	/* MEBASE from MESEG_BASE[35:20] */
-	mebase_l = pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_L);
-	mebase_h = pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_H);
+	mebase_l = x86_pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_L);
+	mebase_h = x86_pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_H);
 	mebase_h &= 0xf;
 	did.uma_base = (mebase_l >> 20) | (mebase_h << 12);
 
diff --git a/arch/x86/cpu/ivybridge/gma.c b/arch/x86/cpu/ivybridge/gma.c
index 821ea25..ea169b0 100644
--- a/arch/x86/cpu/ivybridge/gma.c
+++ b/arch/x86/cpu/ivybridge/gma.c
@@ -741,9 +741,9 @@ int gma_func0_init(pci_dev_t dev, struct pci_controller *hose,
 	int ret;
 
 	/* IGD needs to be Bus Master */
-	reg32 = pci_read_config32(dev, PCI_COMMAND);
+	reg32 = x86_pci_read_config32(dev, PCI_COMMAND);
 	reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
-	pci_write_config32(dev, PCI_COMMAND, reg32);
+	x86_pci_write_config32(dev, PCI_COMMAND, reg32);
 
 	/* Use write-combining for the graphics memory, 256MB */
 	base = pci_read_bar32(hose, dev, 2);
diff --git a/arch/x86/cpu/ivybridge/lpc.c b/arch/x86/cpu/ivybridge/lpc.c
index 43fdd31..33b11a1 100644
--- a/arch/x86/cpu/ivybridge/lpc.c
+++ b/arch/x86/cpu/ivybridge/lpc.c
@@ -29,7 +29,7 @@ static int pch_enable_apic(pci_dev_t dev)
 	int i;
 
 	/* Enable ACPI I/O and power management. Set SCI IRQ to IRQ9 */
-	pci_write_config8(dev, ACPI_CNTL, 0x80);
+	x86_pci_write_config8(dev, ACPI_CNTL, 0x80);
 
 	writel(0, IO_APIC_INDEX);
 	writel(1 << 25, IO_APIC_DATA);
@@ -72,9 +72,9 @@ static void pch_enable_serial_irqs(pci_dev_t dev)
 	/* Set packet length and toggle silent mode bit for one frame. */
 	value = (1 << 7) | (1 << 6) | ((21 - 17) << 2) | (0 << 0);
 #ifdef CONFIG_SERIRQ_CONTINUOUS_MODE
-	pci_write_config8(dev, SERIRQ_CNTL, value);
+	x86_pci_write_config8(dev, SERIRQ_CNTL, value);
 #else
-	pci_write_config8(dev, SERIRQ_CNTL, value | (1 << 6));
+	x86_pci_write_config8(dev, SERIRQ_CNTL, value | (1 << 6));
 #endif
 }
 
@@ -86,15 +86,15 @@ static int pch_pirq_init(const void *blob, int node, pci_dev_t dev)
 				  sizeof(route)))
 		return -EINVAL;
 	ptr = route;
-	pci_write_config8(dev, PIRQA_ROUT, *ptr++);
-	pci_write_config8(dev, PIRQB_ROUT, *ptr++);
-	pci_write_config8(dev, PIRQC_ROUT, *ptr++);
-	pci_write_config8(dev, PIRQD_ROUT, *ptr++);
+	x86_pci_write_config8(dev, PIRQA_ROUT, *ptr++);
+	x86_pci_write_config8(dev, PIRQB_ROUT, *ptr++);
+	x86_pci_write_config8(dev, PIRQC_ROUT, *ptr++);
+	x86_pci_write_config8(dev, PIRQD_ROUT, *ptr++);
 
-	pci_write_config8(dev, PIRQE_ROUT, *ptr++);
-	pci_write_config8(dev, PIRQF_ROUT, *ptr++);
-	pci_write_config8(dev, PIRQG_ROUT, *ptr++);
-	pci_write_config8(dev, PIRQH_ROUT, *ptr++);
+	x86_pci_write_config8(dev, PIRQE_ROUT, *ptr++);
+	x86_pci_write_config8(dev, PIRQF_ROUT, *ptr++);
+	x86_pci_write_config8(dev, PIRQG_ROUT, *ptr++);
+	x86_pci_write_config8(dev, PIRQH_ROUT, *ptr++);
 
 	/*
 	 * TODO(sjg@chromium.org): U-Boot does not set up the interrupts
@@ -116,7 +116,7 @@ static int pch_gpi_routing(const void *blob, int node, pci_dev_t dev)
 	for (reg = 0, gpi = 0; gpi < ARRAY_SIZE(route); gpi++)
 		reg |= route[gpi] << (gpi * 2);
 
-	pci_write_config32(dev, 0xb8, reg);
+	x86_pci_write_config32(dev, 0xb8, reg);
 
 	return 0;
 }
@@ -141,7 +141,7 @@ static int pch_power_options(const void *blob, int node, pci_dev_t dev)
 	 */
 	pwr_on = MAINBOARD_POWER_ON;
 
-	reg16 = pci_read_config16(dev, GEN_PMCON_3);
+	reg16 = x86_pci_read_config16(dev, GEN_PMCON_3);
 	reg16 &= 0xfffe;
 	switch (pwr_on) {
 	case MAINBOARD_POWER_OFF:
@@ -168,7 +168,7 @@ static int pch_power_options(const void *blob, int node, pci_dev_t dev)
 
 	reg16 |= (1 << 12);	/* Disable SLP stretch after SUS well */
 
-	pci_write_config16(dev, GEN_PMCON_3, reg16);
+	x86_pci_write_config16(dev, GEN_PMCON_3, reg16);
 	debug("Set power %s after power failure.\n", state);
 
 	/* Set up NMI on errors. */
@@ -192,21 +192,21 @@ static int pch_power_options(const void *blob, int node, pci_dev_t dev)
 	outb(reg8, 0x70);
 
 	/* Enable CPU_SLP# and Intel Speedstep, set SMI# rate down */
-	reg16 = pci_read_config16(dev, GEN_PMCON_1);
+	reg16 = x86_pci_read_config16(dev, GEN_PMCON_1);
 	reg16 &= ~(3 << 0);	/* SMI# rate 1 minute */
 	reg16 &= ~(1 << 10);	/* Disable BIOS_PCI_EXP_EN for native PME */
 #if DEBUG_PERIODIC_SMIS
 	/* Set DEBUG_PERIODIC_SMIS in pch.h to debug using periodic SMIs */
 	reg16 |= (3 << 0);	/* Periodic SMI every 8s */
 #endif
-	pci_write_config16(dev, GEN_PMCON_1, reg16);
+	x86_pci_write_config16(dev, GEN_PMCON_1, reg16);
 
 	/* Set the board's GPI routing. */
 	ret = pch_gpi_routing(blob, node, dev);
 	if (ret)
 		return ret;
 
-	pmbase = pci_read_config16(dev, 0x40) & 0xfffe;
+	pmbase = x86_pci_read_config16(dev, 0x40) & 0xfffe;
 
 	writel(pmbase + GPE0_EN, fdtdec_get_int(blob, node,
 						"intel,gpe0-enable", 0));
@@ -231,11 +231,11 @@ static void pch_rtc_init(pci_dev_t dev)
 	int rtc_failed;
 	u8 reg8;
 
-	reg8 = pci_read_config8(dev, GEN_PMCON_3);
+	reg8 = x86_pci_read_config8(dev, GEN_PMCON_3);
 	rtc_failed = reg8 & RTC_BATTERY_DEAD;
 	if (rtc_failed) {
 		reg8 &= ~RTC_BATTERY_DEAD;
-		pci_write_config8(dev, GEN_PMCON_3, reg8);
+		x86_pci_write_config8(dev, GEN_PMCON_3, reg8);
 	}
 	debug("rtc_failed = 0x%x\n", rtc_failed);
 
@@ -258,7 +258,7 @@ static void pch_rtc_init(pci_dev_t dev)
 static void cpt_pm_init(pci_dev_t dev)
 {
 	debug("CougarPoint PM init\n");
-	pci_write_config8(dev, 0xa9, 0x47);
+	x86_pci_write_config8(dev, 0xa9, 0x47);
 	setbits_le32(RCB_REG(0x2238), (1 << 6) | (1 << 0));
 
 	setbits_le32(RCB_REG(0x228c), 1 << 0);
@@ -302,7 +302,7 @@ static void cpt_pm_init(pci_dev_t dev)
 static void ppt_pm_init(pci_dev_t dev)
 {
 	debug("PantherPoint PM init\n");
-	pci_write_config8(dev, 0xa9, 0x47);
+	x86_pci_write_config8(dev, 0xa9, 0x47);
 	setbits_le32(RCB_REG(0x2238), 1 << 0);
 	setbits_le32(RCB_REG(0x228c), 1 << 0);
 	setbits_le16(RCB_REG(0x1100), (1 << 13) | (1 << 14));
@@ -356,9 +356,9 @@ static void enable_clock_gating(pci_dev_t dev)
 
 	setbits_le32(RCB_REG(0x2234), 0xf);
 
-	reg16 = pci_read_config16(dev, GEN_PMCON_1);
+	reg16 = x86_pci_read_config16(dev, GEN_PMCON_1);
 	reg16 |= (1 << 2) | (1 << 11);
-	pci_write_config16(dev, GEN_PMCON_1, reg16);
+	x86_pci_write_config16(dev, GEN_PMCON_1, reg16);
 
 	pch_iobp_update(0xEB007F07, ~0UL, (1 << 31));
 	pch_iobp_update(0xEB004000, ~0UL, (1 << 7));
@@ -412,15 +412,15 @@ static void pch_lock_smm(pci_dev_t dev)
 #if TEST_SMM_FLASH_LOCKDOWN
 	/* Now try this: */
 	debug("Locking BIOS to RO... ");
-	reg8 = pci_read_config8(dev, 0xdc);	/* BIOS_CNTL */
+	reg8 = x86_pci_read_config8(dev, 0xdc);	/* BIOS_CNTL */
 	debug(" BLE: %s; BWE: %s\n", (reg8 & 2) ? "on" : "off",
 	      (reg8 & 1) ? "rw" : "ro");
 	reg8 &= ~(1 << 0);			/* clear BIOSWE */
-	pci_write_config8(dev, 0xdc, reg8);
+	x86_pci_write_config8(dev, 0xdc, reg8);
 	reg8 |= (1 << 1);			/* set BLE */
-	pci_write_config8(dev, 0xdc, reg8);
+	x86_pci_write_config8(dev, 0xdc, reg8);
 	debug("ok.\n");
-	reg8 = pci_read_config8(dev, 0xdc);	/* BIOS_CNTL */
+	reg8 = x86_pci_read_config8(dev, 0xdc);	/* BIOS_CNTL */
 	debug(" BLE: %s; BWE: %s\n", (reg8 & 2) ? "on" : "off",
 	      (reg8 & 1) ? "rw" : "ro");
 
@@ -428,9 +428,9 @@ static void pch_lock_smm(pci_dev_t dev)
 	writeb(0, 0xfff00000);
 	debug("Testing:\n");
 	reg8 |= (1 << 0);			/* set BIOSWE */
-	pci_write_config8(dev, 0xdc, reg8);
+	x86_pci_write_config8(dev, 0xdc, reg8);
 
-	reg8 = pci_read_config8(dev, 0xdc);	/* BIOS_CNTL */
+	reg8 = x86_pci_read_config8(dev, 0xdc);	/* BIOS_CNTL */
 	debug(" BLE: %s; BWE: %s\n", (reg8 & 2) ? "on" : "off",
 	      (reg8 & 1) ? "rw" : "ro");
 	debug("Done.\n");
@@ -443,9 +443,9 @@ static void pch_disable_smm_only_flashing(pci_dev_t dev)
 	u8 reg8;
 
 	debug("Enabling BIOS updates outside of SMM... ");
-	reg8 = pci_read_config8(dev, 0xdc);	/* BIOS_CNTL */
+	reg8 = x86_pci_read_config8(dev, 0xdc);	/* BIOS_CNTL */
 	reg8 &= ~(1 << 5);
-	pci_write_config8(dev, 0xdc, reg8);
+	x86_pci_write_config8(dev, 0xdc, reg8);
 }
 
 static void pch_fixups(pci_dev_t dev)
@@ -453,9 +453,9 @@ static void pch_fixups(pci_dev_t dev)
 	u8 gen_pmcon_2;
 
 	/* Indicate DRAM init done for MRC S3 to know it can resume */
-	gen_pmcon_2 = pci_read_config8(dev, GEN_PMCON_2);
+	gen_pmcon_2 = x86_pci_read_config8(dev, GEN_PMCON_2);
 	gen_pmcon_2 |= (1 << 7);
-	pci_write_config8(dev, GEN_PMCON_2, gen_pmcon_2);
+	x86_pci_write_config8(dev, GEN_PMCON_2, gen_pmcon_2);
 
 	/* Enable DMI ASPM in the PCH */
 	clrbits_le32(RCB_REG(0x2304), 1 << 10);
@@ -478,10 +478,10 @@ int lpc_early_init(const void *blob, int node, pci_dev_t dev)
 		return -EINVAL;
 
 	/* Set COM1/COM2 decode range */
-	pci_write_config16(dev, LPC_IO_DEC, 0x0010);
+	x86_pci_write_config16(dev, LPC_IO_DEC, 0x0010);
 
 	/* Enable PS/2 Keyboard/Mouse, EC areas and COM1 */
-	pci_write_config16(dev, LPC_EN, KBC_LPC_EN | MC_LPC_EN |
+	x86_pci_write_config16(dev, LPC_EN, KBC_LPC_EN | MC_LPC_EN |
 			   GAMEL_LPC_EN | COMA_LPC_EN);
 
 	/* Write all registers but use 0 if we run out of data */
@@ -491,7 +491,7 @@ int lpc_early_init(const void *blob, int node, pci_dev_t dev)
 
 		if (i < count)
 			reg = ptr->base | PCI_COMMAND_IO | (ptr->size << 16);
-		pci_write_config32(dev, LPC_GENX_DEC(i), reg);
+		x86_pci_write_config32(dev, LPC_GENX_DEC(i), reg);
 	}
 
 	return 0;
@@ -514,7 +514,7 @@ int lpc_init(struct pci_controller *hose, pci_dev_t dev)
 		return -ENOENT;
 
 	/* Set the value for PCI command register. */
-	pci_write_config16(dev, PCI_COMMAND, 0x000f);
+	x86_pci_write_config16(dev, PCI_COMMAND, 0x000f);
 
 	/* IO APIC initialization. */
 	pch_enable_apic(dev);
diff --git a/arch/x86/cpu/ivybridge/northbridge.c b/arch/x86/cpu/ivybridge/northbridge.c
index c50b5de..e95e60e 100644
--- a/arch/x86/cpu/ivybridge/northbridge.c
+++ b/arch/x86/cpu/ivybridge/northbridge.c
@@ -30,7 +30,7 @@ int bridge_silicon_revision(void)
 		result = cpuid(1);
 		stepping = result.eax & 0xf;
 		dev = PCI_BDF(0, 0, 0);
-		bridge_id = pci_read_config16(dev, PCI_DEVICE_ID) & 0xf0;
+		bridge_id = x86_pci_read_config16(dev, PCI_DEVICE_ID) & 0xf0;
 		bridge_revision_id = bridge_id | stepping;
 	}
 
@@ -55,7 +55,7 @@ static int get_pcie_bar(u32 *base, u32 *len)
 	*base = 0;
 	*len = 0;
 
-	pciexbar_reg = pci_read_config32(dev, PCIEXBAR);
+	pciexbar_reg = x86_pci_read_config32(dev, PCIEXBAR);
 
 	if (!(pciexbar_reg & (1 << 0)))
 		return 0;
@@ -170,7 +170,7 @@ void northbridge_init(pci_dev_t dev)
 void northbridge_enable(pci_dev_t dev)
 {
 #if CONFIG_HAVE_ACPI_RESUME
-	switch (pci_read_config32(dev, SKPAD)) {
+	switch (x86_pci_read_config32(dev, SKPAD)) {
 	case 0xcafebabe:
 		debug("Normal boot.\n");
 		apci_set_slp_type(0);
diff --git a/arch/x86/cpu/ivybridge/pch.c b/arch/x86/cpu/ivybridge/pch.c
index fa04d48..bbab646 100644
--- a/arch/x86/cpu/ivybridge/pch.c
+++ b/arch/x86/cpu/ivybridge/pch.c
@@ -21,7 +21,7 @@ int pch_silicon_revision(void)
 	dev = PCH_LPC_DEV;
 
 	if (pch_revision_id < 0)
-		pch_revision_id = pci_read_config8(dev, PCI_REVISION_ID);
+		pch_revision_id = x86_pci_read_config8(dev, PCI_REVISION_ID);
 	return pch_revision_id;
 }
 
@@ -32,7 +32,7 @@ int pch_silicon_type(void)
 	dev = PCH_LPC_DEV;
 
 	if (pch_type < 0)
-		pch_type = pci_read_config8(dev, PCI_DEVICE_ID + 1);
+		pch_type = x86_pci_read_config8(dev, PCI_DEVICE_ID + 1);
 	return pch_type;
 }
 
diff --git a/arch/x86/cpu/ivybridge/pci.c b/arch/x86/cpu/ivybridge/pci.c
index 452d1c3..7f62a86 100644
--- a/arch/x86/cpu/ivybridge/pci.c
+++ b/arch/x86/cpu/ivybridge/pci.c
@@ -70,9 +70,9 @@ int board_pci_pre_scan(struct pci_controller *hose)
 
 	reg16 = 0xff;
 	dev = PCH_DEV;
-	reg16 = pci_read_config16(dev, PCI_COMMAND);
+	reg16 = x86_pci_read_config16(dev, PCI_COMMAND);
 	reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
-	pci_write_config16(dev, PCI_COMMAND, reg16);
+	x86_pci_write_config16(dev, PCI_COMMAND, reg16);
 
 	/*
 	* Clear non-reserved bits in status register.
diff --git a/arch/x86/cpu/ivybridge/report_platform.c b/arch/x86/cpu/ivybridge/report_platform.c
index 69e31b3..4493870 100644
--- a/arch/x86/cpu/ivybridge/report_platform.c
+++ b/arch/x86/cpu/ivybridge/report_platform.c
@@ -70,14 +70,14 @@ static void report_pch_info(void)
 	u16 dev_id;
 	uint8_t rev_id;
 
-	dev_id = pci_read_config16(PCH_LPC_DEV, 2);
+	dev_id = x86_pci_read_config16(PCH_LPC_DEV, 2);
 	for (i = 0; i < ARRAY_SIZE(pch_table); i++) {
 		if (pch_table[i].dev_id == dev_id) {
 			pch_type = pch_table[i].dev_name;
 			break;
 		}
 	}
-	rev_id = pci_read_config8(PCH_LPC_DEV, 8);
+	rev_id = x86_pci_read_config8(PCH_LPC_DEV, 8);
 	debug("PCH type: %s, device id: %x, rev id %x\n", pch_type, dev_id,
 	      rev_id);
 }
diff --git a/arch/x86/cpu/ivybridge/sata.c b/arch/x86/cpu/ivybridge/sata.c
index bbcd47d..e7bf03c 100644
--- a/arch/x86/cpu/ivybridge/sata.c
+++ b/arch/x86/cpu/ivybridge/sata.c
@@ -14,14 +14,14 @@
 
 static inline u32 sir_read(pci_dev_t dev, int idx)
 {
-	pci_write_config32(dev, SATA_SIRI, idx);
-	return pci_read_config32(dev, SATA_SIRD);
+	x86_pci_write_config32(dev, SATA_SIRI, idx);
+	return x86_pci_read_config32(dev, SATA_SIRD);
 }
 
 static inline void sir_write(pci_dev_t dev, int idx, u32 value)
 {
-	pci_write_config32(dev, SATA_SIRI, idx);
-	pci_write_config32(dev, SATA_SIRD, value);
+	x86_pci_write_config32(dev, SATA_SIRI, idx);
+	x86_pci_write_config32(dev, SATA_SIRD, value);
 }
 
 static void common_sata_init(pci_dev_t dev, unsigned int port_map)
@@ -31,17 +31,17 @@ static void common_sata_init(pci_dev_t dev, unsigned int port_map)
 
 	/* Set IDE I/O Configuration */
 	reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0;
-	pci_write_config32(dev, IDE_CONFIG, reg32);
+	x86_pci_write_config32(dev, IDE_CONFIG, reg32);
 
 	/* Port enable */
-	reg16 = pci_read_config16(dev, 0x92);
+	reg16 = x86_pci_read_config16(dev, 0x92);
 	reg16 &= ~0x3f;
 	reg16 |= port_map;
-	pci_write_config16(dev, 0x92, reg16);
+	x86_pci_write_config16(dev, 0x92, reg16);
 
 	/* SATA Initialization register */
 	port_map &= 0xff;
-	pci_write_config32(dev, 0x94, ((port_map ^ 0x3f) << 24) | 0x183);
+	x86_pci_write_config32(dev, 0x94, ((port_map ^ 0x3f) << 24) | 0x183);
 }
 
 void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node)
@@ -60,7 +60,7 @@ void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node)
 				       "sata_interface_speed_support", 0);
 
 	/* Enable BARs */
-	pci_write_config16(dev, PCI_COMMAND, 0x0007);
+	x86_pci_write_config16(dev, PCI_COMMAND, 0x0007);
 
 	mode = fdt_getprop(blob, node, "intel,sata-mode", NULL);
 	if (!mode || !strcmp(mode, "ahci")) {
@@ -69,18 +69,18 @@ void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node)
 		debug("SATA: Controller in AHCI mode\n");
 
 		/* Set Interrupt Line, Interrupt Pin is set by D31IP.PIP */
-		pci_write_config8(dev, INTR_LN, 0x0a);
+		x86_pci_write_config8(dev, INTR_LN, 0x0a);
 
 		/* Set timings */
-		pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
+		x86_pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
 				IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
 				IDE_PPE0 | IDE_IE0 | IDE_TIME0);
-		pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
+		x86_pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
 				IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS);
 
 		/* Sync DMA */
-		pci_write_config16(dev, IDE_SDMA_CNT, IDE_PSDE0);
-		pci_write_config16(dev, IDE_SDMA_TIM, 0x0001);
+		x86_pci_write_config16(dev, IDE_SDMA_CNT, IDE_PSDE0);
+		x86_pci_write_config16(dev, IDE_SDMA_TIM, 0x0001);
 
 		common_sata_init(dev, 0x8000 | port_map);
 
@@ -115,22 +115,22 @@ void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node)
 		/* No AHCI: clear AHCI base */
 		pci_write_bar32(hose, dev, 5, 0x00000000);
 		/* And without AHCI BAR no memory decoding */
-		reg16 = pci_read_config16(dev, PCI_COMMAND);
+		reg16 = x86_pci_read_config16(dev, PCI_COMMAND);
 		reg16 &= ~PCI_COMMAND_MEMORY;
-		pci_write_config16(dev, PCI_COMMAND, reg16);
+		x86_pci_write_config16(dev, PCI_COMMAND, reg16);
 
-		pci_write_config8(dev, 0x09, 0x80);
+		x86_pci_write_config8(dev, 0x09, 0x80);
 
 		/* Set timings */
-		pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
+		x86_pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
 				IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS);
-		pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
+		x86_pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
 				IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
 				IDE_PPE0 | IDE_IE0 | IDE_TIME0);
 
 		/* Sync DMA */
-		pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0);
-		pci_write_config16(dev, IDE_SDMA_TIM, 0x0200);
+		x86_pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0);
+		x86_pci_write_config16(dev, IDE_SDMA_TIM, 0x0200);
 
 		common_sata_init(dev, port_map);
 	} else {
@@ -140,31 +140,32 @@ void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node)
 		pci_write_bar32(hose, dev, 5, 0x00000000);
 
 		/* And without AHCI BAR no memory decoding */
-		reg16 = pci_read_config16(dev, PCI_COMMAND);
+		reg16 = x86_pci_read_config16(dev, PCI_COMMAND);
 		reg16 &= ~PCI_COMMAND_MEMORY;
-		pci_write_config16(dev, PCI_COMMAND, reg16);
+		x86_pci_write_config16(dev, PCI_COMMAND, reg16);
 
 		/*
 		 * Native mode capable on both primary and secondary (0xa)
 		 * OR'ed with enabled (0x50) = 0xf
 		 */
-		pci_write_config8(dev, 0x09, 0x8f);
+		x86_pci_write_config8(dev, 0x09, 0x8f);
 
 		/* Set Interrupt Line */
 		/* Interrupt Pin is set by D31IP.PIP */
-		pci_write_config8(dev, INTR_LN, 0xff);
+		x86_pci_write_config8(dev, INTR_LN, 0xff);
 
 		/* Set timings */
-		pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
+		x86_pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
 				IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
 				IDE_PPE0 | IDE_IE0 | IDE_TIME0);
-		pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
+		x86_pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
 				IDE_SITRE | IDE_ISP_3_CLOCKS |
 				IDE_RCT_1_CLOCKS | IDE_IE0 | IDE_TIME0);
 
 		/* Sync DMA */
-		pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0 | IDE_PSDE0);
-		pci_write_config16(dev, IDE_SDMA_TIM, 0x0201);
+		x86_pci_write_config16(dev, IDE_SDMA_CNT,
+				       IDE_SSDE0 | IDE_PSDE0);
+		x86_pci_write_config16(dev, IDE_SDMA_TIM, 0x0201);
 
 		common_sata_init(dev, port_map);
 	}
@@ -221,5 +222,5 @@ void bd82x6x_sata_enable(pci_dev_t dev, const void *blob, int node)
 	port_map = fdtdec_get_int(blob, node, "intel,sata-port-map", 0);
 
 	map |= (port_map ^ 0x3f) << 8;
-	pci_write_config16(dev, 0x90, map);
+	x86_pci_write_config16(dev, 0x90, map);
 }
diff --git a/arch/x86/cpu/ivybridge/sdram.c b/arch/x86/cpu/ivybridge/sdram.c
index 766b385..672d069 100644
--- a/arch/x86/cpu/ivybridge/sdram.c
+++ b/arch/x86/cpu/ivybridge/sdram.c
@@ -444,7 +444,7 @@ int sdram_initialise(struct pei_data *pei_data)
 	 * Send ME init done for SandyBridge here.  This is done inside the
 	 * SystemAgent binary on IvyBridge
 	 */
-	done = pci_read_config32(PCH_DEV, PCI_DEVICE_ID);
+	done = x86_pci_read_config32(PCH_DEV, PCI_DEVICE_ID);
 	done &= BASE_REV_MASK;
 	if (BASE_REV_SNB == done)
 		intel_early_me_init_done(ME_INIT_STATUS_SUCCESS);
@@ -615,24 +615,24 @@ static int sdram_find(pci_dev_t dev)
 	 */
 
 	/* Top of Upper Usable DRAM, including remap */
-	touud = pci_read_config32(dev, TOUUD+4);
+	touud = x86_pci_read_config32(dev, TOUUD+4);
 	touud <<= 32;
-	touud |= pci_read_config32(dev, TOUUD);
+	touud |= x86_pci_read_config32(dev, TOUUD);
 
 	/* Top of Lower Usable DRAM */
-	tolud = pci_read_config32(dev, TOLUD);
+	tolud = x86_pci_read_config32(dev, TOLUD);
 
 	/* Top of Memory - does not account for any UMA */
-	tom = pci_read_config32(dev, 0xa4);
+	tom = x86_pci_read_config32(dev, 0xa4);
 	tom <<= 32;
-	tom |= pci_read_config32(dev, 0xa0);
+	tom |= x86_pci_read_config32(dev, 0xa0);
 
 	debug("TOUUD %llx TOLUD %08x TOM %llx\n", touud, tolud, tom);
 
 	/* ME UMA needs excluding if total memory <4GB */
-	me_base = pci_read_config32(dev, 0x74);
+	me_base = x86_pci_read_config32(dev, 0x74);
 	me_base <<= 32;
-	me_base |= pci_read_config32(dev, 0x70);
+	me_base |= x86_pci_read_config32(dev, 0x70);
 
 	debug("MEBASE %llx\n", me_base);
 
@@ -650,7 +650,7 @@ static int sdram_find(pci_dev_t dev)
 	}
 
 	/* Graphics memory comes next */
-	ggc = pci_read_config16(dev, GGC);
+	ggc = x86_pci_read_config16(dev, GGC);
 	if (!(ggc & 2)) {
 		debug("IGD decoded, subtracting ");
 
@@ -670,7 +670,7 @@ static int sdram_find(pci_dev_t dev)
 	}
 
 	/* Calculate TSEG size from its base which must be below GTT */
-	tseg_base = pci_read_config32(dev, 0xb8);
+	tseg_base = x86_pci_read_config32(dev, 0xb8);
 	uma_size = (uma_memory_base - tseg_base) >> 10;
 	tomk -= uma_size;
 	uma_memory_base = tomk * 1024ULL;
diff --git a/arch/x86/cpu/ivybridge/usb_ehci.c b/arch/x86/cpu/ivybridge/usb_ehci.c
index 291c971..da11aee 100644
--- a/arch/x86/cpu/ivybridge/usb_ehci.c
+++ b/arch/x86/cpu/ivybridge/usb_ehci.c
@@ -20,10 +20,10 @@ void bd82x6x_usb_ehci_init(pci_dev_t dev)
 	writel(reg32, RCB_REG(0x35b0));
 
 	debug("EHCI: Setting up controller.. ");
-	reg32 = pci_read_config32(dev, PCI_COMMAND);
+	reg32 = x86_pci_read_config32(dev, PCI_COMMAND);
 	reg32 |= PCI_COMMAND_MASTER;
 	/* reg32 |= PCI_COMMAND_SERR; */
-	pci_write_config32(dev, PCI_COMMAND, reg32);
+	x86_pci_write_config32(dev, PCI_COMMAND, reg32);
 
 	debug("done.\n");
 }
diff --git a/arch/x86/cpu/ivybridge/usb_xhci.c b/arch/x86/cpu/ivybridge/usb_xhci.c
index 4a32a7e..f77b804 100644
--- a/arch/x86/cpu/ivybridge/usb_xhci.c
+++ b/arch/x86/cpu/ivybridge/usb_xhci.c
@@ -16,17 +16,17 @@ void bd82x6x_usb_xhci_init(pci_dev_t dev)
 	debug("XHCI: Setting up controller.. ");
 
 	/* lock overcurrent map */
-	reg32 = pci_read_config32(dev, 0x44);
+	reg32 = x86_pci_read_config32(dev, 0x44);
 	reg32 |= 1;
-	pci_write_config32(dev, 0x44, reg32);
+	x86_pci_write_config32(dev, 0x44, reg32);
 
 	/* Enable clock gating */
-	reg32 = pci_read_config32(dev, 0x40);
+	reg32 = x86_pci_read_config32(dev, 0x40);
 	reg32 &= ~((1 << 20) | (1 << 21));
 	reg32 |= (1 << 19) | (1 << 18) | (1 << 17);
 	reg32 |= (1 << 10) | (1 << 9) | (1 << 8);
 	reg32 |= (1 << 31); /* lock */
-	pci_write_config32(dev, 0x40, reg32);
+	x86_pci_write_config32(dev, 0x40, reg32);
 
 	debug("done.\n");
 }
diff --git a/arch/x86/cpu/pci.c b/arch/x86/cpu/pci.c
index ab1aaaa..c6c5267 100644
--- a/arch/x86/cpu/pci.c
+++ b/arch/x86/cpu/pci.c
@@ -70,7 +70,7 @@ static struct pci_controller *get_hose(void)
 	return pci_bus_to_hose(0);
 }
 
-unsigned int pci_read_config8(pci_dev_t dev, unsigned where)
+unsigned int x86_pci_read_config8(pci_dev_t dev, unsigned where)
 {
 	uint8_t value;
 
@@ -79,7 +79,7 @@ unsigned int pci_read_config8(pci_dev_t dev, unsigned where)
 	return value;
 }
 
-unsigned int pci_read_config16(pci_dev_t dev, unsigned where)
+unsigned int x86_pci_read_config16(pci_dev_t dev, unsigned where)
 {
 	uint16_t value;
 
@@ -88,7 +88,7 @@ unsigned int pci_read_config16(pci_dev_t dev, unsigned where)
 	return value;
 }
 
-unsigned int pci_read_config32(pci_dev_t dev, unsigned where)
+unsigned int x86_pci_read_config32(pci_dev_t dev, unsigned where)
 {
 	uint32_t value;
 
@@ -97,17 +97,17 @@ unsigned int pci_read_config32(pci_dev_t dev, unsigned where)
 	return value;
 }
 
-void pci_write_config8(pci_dev_t dev, unsigned where, unsigned value)
+void x86_pci_write_config8(pci_dev_t dev, unsigned where, unsigned value)
 {
 	pci_hose_write_config_byte(get_hose(), dev, where, value);
 }
 
-void pci_write_config16(pci_dev_t dev, unsigned where, unsigned value)
+void x86_pci_write_config16(pci_dev_t dev, unsigned where, unsigned value)
 {
 	pci_hose_write_config_word(get_hose(), dev, where, value);
 }
 
-void pci_write_config32(pci_dev_t dev, unsigned where, unsigned value)
+void x86_pci_write_config32(pci_dev_t dev, unsigned where, unsigned value)
 {
 	pci_hose_write_config_dword(get_hose(), dev, where, value);
 }
diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c
index dccf7ac..ca40d0e 100644
--- a/arch/x86/cpu/quark/quark.c
+++ b/arch/x86/cpu/quark/quark.c
@@ -28,9 +28,9 @@ static void unprotect_spi_flash(void)
 {
 	u32 bc;
 
-	bc = pci_read_config32(QUARK_LEGACY_BRIDGE, 0xd8);
+	bc = x86_pci_read_config32(QUARK_LEGACY_BRIDGE, 0xd8);
 	bc |= 0x1;	/* unprotect the flash */
-	pci_write_config32(QUARK_LEGACY_BRIDGE, 0xd8, bc);
+	x86_pci_write_config32(QUARK_LEGACY_BRIDGE, 0xd8, bc);
 }
 
 static void quark_setup_bars(void)
diff --git a/arch/x86/cpu/queensbay/tnc.c b/arch/x86/cpu/queensbay/tnc.c
index 30ab725..b7236e7 100644
--- a/arch/x86/cpu/queensbay/tnc.c
+++ b/arch/x86/cpu/queensbay/tnc.c
@@ -16,9 +16,9 @@ static void unprotect_spi_flash(void)
 {
 	u32 bc;
 
-	bc = pci_read_config32(PCH_LPC_DEV, 0xd8);
+	bc = x86_pci_read_config32(PCH_LPC_DEV, 0xd8);
 	bc |= 0x1;	/* unprotect the flash */
-	pci_write_config32(PCH_LPC_DEV, 0xd8, bc);
+	x86_pci_write_config32(PCH_LPC_DEV, 0xd8, bc);
 }
 
 int arch_cpu_init(void)
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index a153dd1..b277b3d 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -48,13 +48,13 @@ int board_pci_post_scan(struct pci_controller *hose);
  * Simple PCI access routines - these work from either the early PCI hose
  * or the 'real' one, created after U-Boot has memory available
  */
-unsigned int pci_read_config8(pci_dev_t dev, unsigned where);
-unsigned int pci_read_config16(pci_dev_t dev, unsigned where);
-unsigned int pci_read_config32(pci_dev_t dev, unsigned where);
+unsigned int x86_pci_read_config8(pci_dev_t dev, unsigned where);
+unsigned int x86_pci_read_config16(pci_dev_t dev, unsigned where);
+unsigned int x86_pci_read_config32(pci_dev_t dev, unsigned where);
 
-void pci_write_config8(pci_dev_t dev, unsigned where, unsigned value);
-void pci_write_config16(pci_dev_t dev, unsigned where, unsigned value);
-void pci_write_config32(pci_dev_t dev, unsigned where, unsigned value);
+void x86_pci_write_config8(pci_dev_t dev, unsigned where, unsigned value);
+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);
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/x86/lib/bios_interrupts.c b/arch/x86/lib/bios_interrupts.c
index b0e2ecb..290990a 100644
--- a/arch/x86/lib/bios_interrupts.c
+++ b/arch/x86/lib/bios_interrupts.c
@@ -172,28 +172,28 @@ int int1a_handler(void)
 		}
 		switch (func) {
 		case 0xb108: /* Read Config Byte */
-			byte = pci_read_config8(dev, reg);
+			byte = x86_pci_read_config8(dev, reg);
 			M.x86.R_ECX = byte;
 			break;
 		case 0xb109: /* Read Config Word */
-			word = pci_read_config16(dev, reg);
+			word = x86_pci_read_config16(dev, reg);
 			M.x86.R_ECX = word;
 			break;
 		case 0xb10a: /* Read Config Dword */
-			dword = pci_read_config32(dev, reg);
+			dword = x86_pci_read_config32(dev, reg);
 			M.x86.R_ECX = dword;
 			break;
 		case 0xb10b: /* Write Config Byte */
 			byte = M.x86.R_ECX;
-			pci_write_config8(dev, reg, byte);
+			x86_pci_write_config8(dev, reg, byte);
 			break;
 		case 0xb10c: /* Write Config Word */
 			word = M.x86.R_ECX;
-			pci_write_config16(dev, reg, word);
+			x86_pci_write_config16(dev, reg, word);
 			break;
 		case 0xb10d: /* Write Config Dword */
 			dword = M.x86.R_ECX;
-			pci_write_config32(dev, reg, dword);
+			x86_pci_write_config32(dev, reg, dword);
 			break;
 		}
 
diff --git a/drivers/gpio/intel_ich6_gpio.c b/drivers/gpio/intel_ich6_gpio.c
index 7720cc3..06530d7 100644
--- a/drivers/gpio/intel_ich6_gpio.c
+++ b/drivers/gpio/intel_ich6_gpio.c
@@ -64,13 +64,13 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)
 	pci_dev = PCI_BDF(0, 0x1f, 0);
 
 	/* Is the device present? */
-	tmpword = pci_read_config16(pci_dev, PCI_VENDOR_ID);
+	tmpword = x86_pci_read_config16(pci_dev, PCI_VENDOR_ID);
 	if (tmpword != PCI_VENDOR_ID_INTEL) {
 		debug("%s: wrong VendorID\n", __func__);
 		return -ENODEV;
 	}
 
-	tmpword = pci_read_config16(pci_dev, PCI_DEVICE_ID);
+	tmpword = x86_pci_read_config16(pci_dev, PCI_DEVICE_ID);
 	debug("Found %04x:%04x\n", PCI_VENDOR_ID_INTEL, tmpword);
 	/*
 	 * We'd like to validate the Device ID too, but pretty much any
@@ -80,34 +80,34 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)
 	 */
 
 	/* I/O should already be enabled (it's a RO bit). */
-	tmpword = pci_read_config16(pci_dev, PCI_COMMAND);
+	tmpword = x86_pci_read_config16(pci_dev, PCI_COMMAND);
 	if (!(tmpword & PCI_COMMAND_IO)) {
 		debug("%s: device IO not enabled\n", __func__);
 		return -ENODEV;
 	}
 
 	/* Header Type must be normal (bits 6-0 only; see spec.) */
-	tmpbyte = pci_read_config8(pci_dev, PCI_HEADER_TYPE);
+	tmpbyte = x86_pci_read_config8(pci_dev, PCI_HEADER_TYPE);
 	if ((tmpbyte & 0x7f) != PCI_HEADER_TYPE_NORMAL) {
 		debug("%s: invalid Header type\n", __func__);
 		return -ENODEV;
 	}
 
 	/* Base Class must be a bridge device */
-	tmpbyte = pci_read_config8(pci_dev, PCI_CLASS_CODE);
+	tmpbyte = x86_pci_read_config8(pci_dev, PCI_CLASS_CODE);
 	if (tmpbyte != PCI_CLASS_CODE_BRIDGE) {
 		debug("%s: invalid class\n", __func__);
 		return -ENODEV;
 	}
 	/* Sub Class must be ISA */
-	tmpbyte = pci_read_config8(pci_dev, PCI_CLASS_SUB_CODE);
+	tmpbyte = x86_pci_read_config8(pci_dev, PCI_CLASS_SUB_CODE);
 	if (tmpbyte != PCI_CLASS_SUB_CODE_BRIDGE_ISA) {
 		debug("%s: invalid subclass\n", __func__);
 		return -ENODEV;
 	}
 
 	/* Programming Interface must be 0x00 (no others exist) */
-	tmpbyte = pci_read_config8(pci_dev, PCI_CLASS_PROG);
+	tmpbyte = x86_pci_read_config8(pci_dev, PCI_CLASS_PROG);
 	if (tmpbyte != 0x00) {
 		debug("%s: invalid interface type\n", __func__);
 		return -ENODEV;
@@ -123,7 +123,7 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)
 	 * while on the Ivybridge the bit0 is used to indicate it is an
 	 * I/O space.
 	 */
-	tmplong = pci_read_config32(pci_dev, PCI_CFG_GPIOBASE);
+	tmplong = x86_pci_read_config32(pci_dev, PCI_CFG_GPIOBASE);
 	if (tmplong == 0x00000000 || tmplong == 0xffffffff) {
 		debug("%s: unexpected GPIOBASE value\n", __func__);
 		return -ENODEV;
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 04/22] dm: Add a new CPU init function which can use driver model
  2015-03-05 19:25 [U-Boot] [PATCH v2 0/22] Add driver model support for PCI Simon Glass
                   ` (2 preceding siblings ...)
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 03/22] x86: Add a x86_ prefix to the x86-specific PCI functions Simon Glass
@ 2015-03-05 19:25 ` Simon Glass
  2015-03-09  9:02   ` Bin Meng
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 05/22] x86: Split up arch_cpu_init() Simon Glass
                   ` (18 subsequent siblings)
  22 siblings, 1 reply; 53+ messages in thread
From: Simon Glass @ 2015-03-05 19:25 UTC (permalink / raw)
  To: u-boot

Since driver model is set up after arch_cpu_init(), that function cannot
use drivers. Add a new arch_cpu_init_dm() function which is called
immediately after driver model is ready, and can reference devices.

This can be used to probe essential devices for the CPU.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2:
- Add a new patch with a CPU init function which can use driver model

 common/board_f.c |  6 ++++++
 include/common.h | 11 +++++++++++
 2 files changed, 17 insertions(+)

diff --git a/common/board_f.c b/common/board_f.c
index 4d8b8a6..8bbece2 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -787,6 +787,11 @@ __weak int reserve_arch(void)
 	return 0;
 }
 
+__weak int arch_cpu_init_dm(void)
+{
+	return 0;
+}
+
 static init_fnc_t init_sequence_f[] = {
 #ifdef CONFIG_SANDBOX
 	setup_ram_buf,
@@ -807,6 +812,7 @@ static init_fnc_t init_sequence_f[] = {
 	fdtdec_check_fdt,
 #endif
 	initf_dm,
+	arch_cpu_init_dm,
 #if defined(CONFIG_BOARD_EARLY_INIT_F)
 	board_early_init_f,
 #endif
diff --git a/include/common.h b/include/common.h
index 77c55c6..f9aaaa5 100644
--- a/include/common.h
+++ b/include/common.h
@@ -253,6 +253,17 @@ int update_flash_size(int flash_size);
 int arch_early_init_r(void);
 
 /**
+ * arch_cpu_init_dm() - init CPU after driver model is available
+ *
+ * This is called immediately after driver model is available before
+ * relocation. This is similar to arch_cpu_init() but is able to reference
+ * devices
+ *
+ * @return 0 if OK, -ve on error
+ */
+int arch_cpu_init_dm(void);
+
+/**
  * Reserve all necessary stacks
  *
  * This is used in generic board init sequence in common/board_f.c. Each
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 05/22] x86: Split up arch_cpu_init()
  2015-03-05 19:25 [U-Boot] [PATCH v2 0/22] Add driver model support for PCI Simon Glass
                   ` (3 preceding siblings ...)
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 04/22] dm: Add a new CPU init function which can use driver model Simon Glass
@ 2015-03-05 19:25 ` Simon Glass
  2015-03-09  9:06   ` Bin Meng
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 06/22] Correct map_sysmem() logic in do_mem_mw() Simon Glass
                   ` (17 subsequent siblings)
  22 siblings, 1 reply; 53+ messages in thread
From: Simon Glass @ 2015-03-05 19:25 UTC (permalink / raw)
  To: u-boot

At present we do more in this function than we should. Split out the
post-driver-model part into a separate function.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2:
- Use the new arch_cpu_init_dm() function instead of something x86-specific

 arch/x86/cpu/ivybridge/cpu.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c
index 5fd3753..e6ef481 100644
--- a/arch/x86/cpu/ivybridge/cpu.c
+++ b/arch/x86/cpu/ivybridge/cpu.c
@@ -116,6 +116,14 @@ static void set_spi_speed(void)
 
 int arch_cpu_init(void)
 {
+	post_code(POST_CPU_INIT);
+	timer_set_base(rdtsc());
+
+	return x86_cpu_init_f();
+}
+
+int arch_cpu_init_dm(void)
+{
 	const void *blob = gd->fdt_blob;
 	struct pci_controller *hose;
 	int node;
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 06/22] Correct map_sysmem() logic in do_mem_mw()
  2015-03-05 19:25 [U-Boot] [PATCH v2 0/22] Add driver model support for PCI Simon Glass
                   ` (4 preceding siblings ...)
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 05/22] x86: Split up arch_cpu_init() Simon Glass
@ 2015-03-05 19:25 ` Simon Glass
  2015-03-09  9:06   ` Bin Meng
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 07/22] fdt: Tighten up error handling in fdtdec_get_pci_addr() Simon Glass
                   ` (16 subsequent siblings)
  22 siblings, 1 reply; 53+ messages in thread
From: Simon Glass @ 2015-03-05 19:25 UTC (permalink / raw)
  To: u-boot

This function does not unmap what it maps. Correct it.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 common/cmd_mem.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/common/cmd_mem.c b/common/cmd_mem.c
index bcb3ee3..855aa57 100644
--- a/common/cmd_mem.c
+++ b/common/cmd_mem.c
@@ -165,7 +165,7 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 #endif
 	ulong	addr, count;
 	int	size;
-	void *buf;
+	void *buf, *start;
 	ulong bytes;
 
 	if ((argc < 3) || (argc > 4))
@@ -197,7 +197,8 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	}
 
 	bytes = size * count;
-	buf = map_sysmem(addr, bytes);
+	start = map_sysmem(addr, bytes);
+	buf = start;
 	while (count-- > 0) {
 		if (size == 4)
 			*((u32 *)buf) = (u32)writeval;
@@ -211,7 +212,7 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 			*((u8 *)buf) = (u8)writeval;
 		buf += size;
 	}
-	unmap_sysmem(buf);
+	unmap_sysmem(start);
 	return 0;
 }
 
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 07/22] fdt: Tighten up error handling in fdtdec_get_pci_addr()
  2015-03-05 19:25 [U-Boot] [PATCH v2 0/22] Add driver model support for PCI Simon Glass
                   ` (5 preceding siblings ...)
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 06/22] Correct map_sysmem() logic in do_mem_mw() Simon Glass
@ 2015-03-05 19:25 ` Simon Glass
  2015-03-06 15:43   ` Tom Rini
  2015-03-09  9:09   ` Bin Meng
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 08/22] dm: core: Add dev_get_uclass_priv() to access uclass private data Simon Glass
                   ` (15 subsequent siblings)
  22 siblings, 2 replies; 53+ messages in thread
From: Simon Glass @ 2015-03-05 19:25 UTC (permalink / raw)
  To: u-boot

This function returns -ENOENT when the property is missing (which the caller
might forgive) and also when the property is present but incorrectly
formatted (which many callers would like to report).

Update the error return value to allow these different situations to be
distinguished.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2:
- Add -ve sign before ENXIO

 include/fdtdec.h | 4 +++-
 lib/fdtdec.c     | 4 +++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/include/fdtdec.h b/include/fdtdec.h
index 21bd6bb..6944048 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -327,7 +327,9 @@ fdt_addr_t fdtdec_get_addr_size(const void *blob, int node,
  * @param type		pci address type (FDT_PCI_SPACE_xxx)
  * @param prop_name	name of property to find
  * @param addr		returns pci address in the form of fdt_pci_addr
- * @return 0 if ok, negative on error
+ * @return 0 if ok, -ENOENT if the property did not exist, -EINVAL if the
+ *		format of the property was invalid, -ENXIO if the requested
+ *		address type was not found
  */
 int fdtdec_get_pci_addr(const void *blob, int node, enum fdt_pci_space type,
 		const char *prop_name, struct fdt_pci_addr *addr);
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index e47fa96..9212f03 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -160,8 +160,10 @@ int fdtdec_get_pci_addr(const void *blob, int node, enum fdt_pci_space type,
 			}
 		}
 
-		if (i == num)
+		if (i == num) {
+			ret = -ENXIO;
 			goto fail;
+		}
 
 		return 0;
 	} else {
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 08/22] dm: core: Add dev_get_uclass_priv() to access uclass private data
  2015-03-05 19:25 [U-Boot] [PATCH v2 0/22] Add driver model support for PCI Simon Glass
                   ` (6 preceding siblings ...)
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 07/22] fdt: Tighten up error handling in fdtdec_get_pci_addr() Simon Glass
@ 2015-03-05 19:25 ` Simon Glass
  2015-03-20 23:15   ` Simon Glass
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 09/22] dm: core: Mark device as active before calling its probe() method Simon Glass
                   ` (14 subsequent siblings)
  22 siblings, 1 reply; 53+ messages in thread
From: Simon Glass @ 2015-03-05 19:25 UTC (permalink / raw)
  To: u-boot

Add a convenience function to access the private data that a uclass stores
for each of its devices. Convert over most existing uses for consistency
and to provide an example for others.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 common/cmd_sf.c                |  2 +-
 common/cros_ec.c               |  2 +-
 drivers/core/device.c          | 10 ++++++++++
 drivers/gpio/at91_gpio.c       |  2 +-
 drivers/gpio/bcm2835_gpio.c    |  2 +-
 drivers/gpio/gpio-uclass.c     | 22 +++++++++++-----------
 drivers/gpio/intel_ich6_gpio.c |  2 +-
 drivers/gpio/mxc_gpio.c        |  2 +-
 drivers/gpio/omap_gpio.c       |  2 +-
 drivers/gpio/s5p_gpio.c        |  2 +-
 drivers/gpio/sandbox.c         |  6 +++---
 drivers/gpio/sunxi_gpio.c      |  2 +-
 drivers/gpio/tegra_gpio.c      |  2 +-
 drivers/i2c/i2c-uclass.c       |  6 +++---
 drivers/i2c/sandbox_i2c.c      |  2 +-
 drivers/misc/cros_ec.c         |  6 +++---
 drivers/misc/cros_ec_i2c.c     |  2 +-
 drivers/misc/cros_ec_sandbox.c |  2 +-
 drivers/misc/cros_ec_spi.c     |  4 ++--
 drivers/mtd/spi/sf-uclass.c    |  2 +-
 drivers/mtd/spi/sf_probe.c     |  8 ++++----
 drivers/serial/serial-uclass.c |  4 ++--
 drivers/spi/spi-uclass.c       |  4 ++--
 include/dm/device.h            | 10 ++++++++++
 include/i2c.h                  |  8 ++++----
 test/dm/core.c                 |  2 +-
 test/dm/test-uclass.c          |  4 ++--
 27 files changed, 71 insertions(+), 51 deletions(-)

diff --git a/common/cmd_sf.c b/common/cmd_sf.c
index 5c788e9..20f14d3 100644
--- a/common/cmd_sf.c
+++ b/common/cmd_sf.c
@@ -130,7 +130,7 @@ static int do_spi_flash_probe(int argc, char * const argv[])
 		return 1;
 	}
 
-	flash = new->uclass_priv;
+	flash = dev_get_uclass_priv(new);
 #else
 	new = spi_flash_probe(bus, cs, speed, mode);
 	if (!new) {
diff --git a/common/cros_ec.c b/common/cros_ec.c
index bb299bc..64b4679 100644
--- a/common/cros_ec.c
+++ b/common/cros_ec.c
@@ -35,7 +35,7 @@ struct cros_ec_dev *board_get_cros_ec_dev(void)
 		debug("%s: Error %d\n", __func__, ret);
 		return NULL;
 	}
-	return dev->uclass_priv;
+	return dev_get_uclass_priv(dev);
 #else
 	return local.cros_ec_dev;
 #endif
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 73c3e07..92e8a57 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -305,6 +305,16 @@ void *dev_get_priv(struct udevice *dev)
 	return dev->priv;
 }
 
+void *dev_get_uclass_priv(struct udevice *dev)
+{
+	if (!dev) {
+		dm_warn("%s: null device\n", __func__);
+		return NULL;
+	}
+
+	return dev->uclass_priv;
+}
+
 void *dev_get_parentdata(struct udevice *dev)
 {
 	if (!dev) {
diff --git a/drivers/gpio/at91_gpio.c b/drivers/gpio/at91_gpio.c
index 22fbd63..75a32ee 100644
--- a/drivers/gpio/at91_gpio.c
+++ b/drivers/gpio/at91_gpio.c
@@ -511,7 +511,7 @@ static int at91_gpio_probe(struct udevice *dev)
 {
 	struct at91_port_priv *port = dev_get_priv(dev);
 	struct at91_port_platdata *plat = dev_get_platdata(dev);
-	struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 
 	uc_priv->bank_name = plat->bank_name;
 	uc_priv->gpio_count = GPIO_PER_BANK;
diff --git a/drivers/gpio/bcm2835_gpio.c b/drivers/gpio/bcm2835_gpio.c
index 0244c01..fbc641d 100644
--- a/drivers/gpio/bcm2835_gpio.c
+++ b/drivers/gpio/bcm2835_gpio.c
@@ -105,7 +105,7 @@ static int bcm2835_gpio_probe(struct udevice *dev)
 {
 	struct bcm2835_gpios *gpios = dev_get_priv(dev);
 	struct bcm2835_gpio_platdata *plat = dev_get_platdata(dev);
-	struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 
 	uc_priv->bank_name = "GPIO";
 	uc_priv->gpio_count = BCM2835_GPIO_COUNT;
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index a69bbd2..b6e1058 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -34,7 +34,7 @@ static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc)
 	for (ret = uclass_first_device(UCLASS_GPIO, &dev);
 	     dev;
 	     ret = uclass_next_device(&dev)) {
-		uc_priv = dev->uclass_priv;
+		uc_priv = dev_get_uclass_priv(dev);
 		if (gpio >= uc_priv->gpio_base &&
 		    gpio < uc_priv->gpio_base + uc_priv->gpio_count) {
 			desc->dev = dev;
@@ -65,7 +65,7 @@ int gpio_lookup_name(const char *name, struct udevice **devp,
 	     ret = uclass_next_device(&dev)) {
 		int len;
 
-		uc_priv = dev->uclass_priv;
+		uc_priv = dev_get_uclass_priv(dev);
 		if (numeric != -1) {
 			offset = numeric - uc_priv->gpio_base;
 			/* Allow GPIOs to be numbered from 0 */
@@ -116,7 +116,7 @@ static int dm_gpio_request(struct gpio_desc *desc, const char *label)
 	char *str;
 	int ret;
 
-	uc_priv = dev->uclass_priv;
+	uc_priv = dev_get_uclass_priv(dev);
 	if (uc_priv->name[desc->offset])
 		return -EBUSY;
 	str = strdup(label);
@@ -195,7 +195,7 @@ int _dm_gpio_free(struct udevice *dev, uint offset)
 	struct gpio_dev_priv *uc_priv;
 	int ret;
 
-	uc_priv = dev->uclass_priv;
+	uc_priv = dev_get_uclass_priv(dev);
 	if (!uc_priv->name[offset])
 		return -ENXIO;
 	if (gpio_get_ops(dev)->free) {
@@ -232,7 +232,7 @@ int gpio_free(unsigned gpio)
 
 static int check_reserved(struct gpio_desc *desc, const char *func)
 {
-	struct gpio_dev_priv *uc_priv = desc->dev->uclass_priv;
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(desc->dev);
 
 	if (!uc_priv->name[desc->offset]) {
 		printf("%s: %s: error: gpio %s%d not reserved\n",
@@ -402,7 +402,7 @@ const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
 	struct gpio_dev_priv *priv;
 
 	/* Must be called on an active device */
-	priv = dev->uclass_priv;
+	priv = dev_get_uclass_priv(dev);
 	assert(priv);
 
 	*bit_count = priv->gpio_count;
@@ -420,7 +420,7 @@ static const char * const gpio_function[GPIOF_COUNT] = {
 int get_function(struct udevice *dev, int offset, bool skip_unused,
 		 const char **namep)
 {
-	struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 	struct dm_gpio_ops *ops = gpio_get_ops(dev);
 
 	BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
@@ -468,7 +468,7 @@ int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
 	BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
 
 	*buf = 0;
-	priv = dev->uclass_priv;
+	priv = dev_get_uclass_priv(dev);
 	ret = gpio_get_raw_function(dev, offset, NULL);
 	if (ret < 0)
 		return ret;
@@ -680,7 +680,7 @@ static int gpio_renumber(struct udevice *removed_dev)
 	base = 0;
 	uclass_foreach_dev(dev, uc) {
 		if (device_active(dev) && dev != removed_dev) {
-			uc_priv = dev->uclass_priv;
+			uc_priv = dev_get_uclass_priv(dev);
 			uc_priv->gpio_base = base;
 			base += uc_priv->gpio_count;
 		}
@@ -691,7 +691,7 @@ static int gpio_renumber(struct udevice *removed_dev)
 
 static int gpio_post_probe(struct udevice *dev)
 {
-	struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 
 	uc_priv->name = calloc(uc_priv->gpio_count, sizeof(char *));
 	if (!uc_priv->name)
@@ -702,7 +702,7 @@ static int gpio_post_probe(struct udevice *dev)
 
 static int gpio_pre_remove(struct udevice *dev)
 {
-	struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 	int i;
 
 	for (i = 0; i < uc_priv->gpio_count; i++) {
diff --git a/drivers/gpio/intel_ich6_gpio.c b/drivers/gpio/intel_ich6_gpio.c
index 06530d7..7e679a0 100644
--- a/drivers/gpio/intel_ich6_gpio.c
+++ b/drivers/gpio/intel_ich6_gpio.c
@@ -151,7 +151,7 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)
 static int ich6_gpio_probe(struct udevice *dev)
 {
 	struct ich6_bank_platdata *plat = dev_get_platdata(dev);
-	struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 	struct ich6_bank_priv *bank = dev_get_priv(dev);
 
 	if (gd->arch.gpio_map) {
diff --git a/drivers/gpio/mxc_gpio.c b/drivers/gpio/mxc_gpio.c
index 815407b..2012f99 100644
--- a/drivers/gpio/mxc_gpio.c
+++ b/drivers/gpio/mxc_gpio.c
@@ -266,7 +266,7 @@ static int mxc_gpio_probe(struct udevice *dev)
 {
 	struct mxc_bank_info *bank = dev_get_priv(dev);
 	struct mxc_gpio_plat *plat = dev_get_platdata(dev);
-	struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 	int banknum;
 	char name[18], *str;
 
diff --git a/drivers/gpio/omap_gpio.c b/drivers/gpio/omap_gpio.c
index 19fc451..0a1e124 100644
--- a/drivers/gpio/omap_gpio.c
+++ b/drivers/gpio/omap_gpio.c
@@ -309,7 +309,7 @@ static int omap_gpio_probe(struct udevice *dev)
 {
 	struct gpio_bank *bank = dev_get_priv(dev);
 	struct omap_gpio_platdata *plat = dev_get_platdata(dev);
-	struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 	char name[18], *str;
 
 	sprintf(name, "GPIO%d_", plat->bank_index);
diff --git a/drivers/gpio/s5p_gpio.c b/drivers/gpio/s5p_gpio.c
index 0a245ba..49b1054 100644
--- a/drivers/gpio/s5p_gpio.c
+++ b/drivers/gpio/s5p_gpio.c
@@ -296,7 +296,7 @@ static const struct dm_gpio_ops gpio_exynos_ops = {
 
 static int gpio_exynos_probe(struct udevice *dev)
 {
-	struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 	struct exynos_bank_info *priv = dev->priv;
 	struct exynos_gpio_platdata *plat = dev->platdata;
 
diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c
index d564c25..a9b1efc 100644
--- a/drivers/gpio/sandbox.c
+++ b/drivers/gpio/sandbox.c
@@ -24,7 +24,7 @@ struct gpio_state {
 /* Access routines for GPIO state */
 static u8 *get_gpio_flags(struct udevice *dev, unsigned offset)
 {
-	struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 	struct gpio_state *state = dev_get_priv(dev);
 
 	if (offset >= uc_priv->gpio_count) {
@@ -160,7 +160,7 @@ static const struct dm_gpio_ops gpio_sandbox_ops = {
 
 static int sandbox_gpio_ofdata_to_platdata(struct udevice *dev)
 {
-	struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 
 	uc_priv->gpio_count = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
 					     "num-gpios", 0);
@@ -172,7 +172,7 @@ static int sandbox_gpio_ofdata_to_platdata(struct udevice *dev)
 
 static int gpio_sandbox_probe(struct udevice *dev)
 {
-	struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 
 	if (dev->of_offset == -1) {
 		/* Tell the uclass how many GPIOs we have */
diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
index 6296092..b3a5728 100644
--- a/drivers/gpio/sunxi_gpio.c
+++ b/drivers/gpio/sunxi_gpio.c
@@ -238,7 +238,7 @@ static char *gpio_bank_name(int bank)
 static int gpio_sunxi_probe(struct udevice *dev)
 {
 	struct sunxi_gpio_platdata *plat = dev_get_platdata(dev);
-	struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 
 	/* Tell the uclass how many GPIOs we have */
 	if (plat) {
diff --git a/drivers/gpio/tegra_gpio.c b/drivers/gpio/tegra_gpio.c
index f870cdb..8017e35 100644
--- a/drivers/gpio/tegra_gpio.c
+++ b/drivers/gpio/tegra_gpio.c
@@ -295,7 +295,7 @@ static const struct udevice_id tegra_gpio_ids[] = {
 
 static int gpio_tegra_probe(struct udevice *dev)
 {
-	struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 	struct tegra_port_info *priv = dev->priv;
 	struct tegra_gpio_platdata *plat = dev->platdata;
 
diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c
index b890806..f2e95c0 100644
--- a/drivers/i2c/i2c-uclass.c
+++ b/drivers/i2c/i2c-uclass.c
@@ -330,7 +330,7 @@ int dm_i2c_probe(struct udevice *bus, uint chip_addr, uint chip_flags,
 int dm_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
 {
 	struct dm_i2c_ops *ops = i2c_get_ops(bus);
-	struct dm_i2c_bus *i2c = bus->uclass_priv;
+	struct dm_i2c_bus *i2c = dev_get_uclass_priv(bus);
 	int ret;
 
 	/*
@@ -351,7 +351,7 @@ int dm_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
 int dm_i2c_get_bus_speed(struct udevice *bus)
 {
 	struct dm_i2c_ops *ops = i2c_get_ops(bus);
-	struct dm_i2c_bus *i2c = bus->uclass_priv;
+	struct dm_i2c_bus *i2c = dev_get_uclass_priv(bus);
 
 	if (!ops->get_bus_speed)
 		return i2c->speed_hz;
@@ -432,7 +432,7 @@ int i2c_chip_ofdata_to_platdata(const void *blob, int node,
 
 static int i2c_post_probe(struct udevice *dev)
 {
-	struct dm_i2c_bus *i2c = dev->uclass_priv;
+	struct dm_i2c_bus *i2c = dev_get_uclass_priv(dev);
 
 	i2c->speed_hz = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
 				     "clock-frequency", 100000);
diff --git a/drivers/i2c/sandbox_i2c.c b/drivers/i2c/sandbox_i2c.c
index a943aa6..d6adc0f 100644
--- a/drivers/i2c/sandbox_i2c.c
+++ b/drivers/i2c/sandbox_i2c.c
@@ -50,7 +50,7 @@ static int get_emul(struct udevice *dev, struct udevice **devp,
 static int sandbox_i2c_xfer(struct udevice *bus, struct i2c_msg *msg,
 			    int nmsgs)
 {
-	struct dm_i2c_bus *i2c = bus->uclass_priv;
+	struct dm_i2c_bus *i2c = dev_get_uclass_priv(bus);
 	struct dm_i2c_ops *ops;
 	struct udevice *emul, *dev;
 	bool is_read;
diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c
index 5846e76..1c29ba8 100644
--- a/drivers/misc/cros_ec.c
+++ b/drivers/misc/cros_ec.c
@@ -1087,7 +1087,7 @@ static int cros_ec_decode_fdt(const void *blob, int node,
 #ifdef CONFIG_DM_CROS_EC
 int cros_ec_register(struct udevice *dev)
 {
-	struct cros_ec_dev *cdev = dev->uclass_priv;
+	struct cros_ec_dev *cdev = dev_get_uclass_priv(dev);
 	const void *blob = gd->fdt_blob;
 	int node = dev->of_offset;
 	char id[MSG_BYTES];
@@ -1128,7 +1128,7 @@ int cros_ec_init(const void *blob, struct cros_ec_dev **cros_ecp)
 	ret = uclass_get_device(UCLASS_CROS_EC, 0, &udev);
 	if (ret)
 		return ret;
-	dev = udev->uclass_priv;
+	dev = dev_get_uclass_priv(udev);
 	return 0;
 #else
 	int node = 0;
@@ -1610,7 +1610,7 @@ static int do_cros_ec(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 		printf("Cannot get cros-ec device (err=%d)\n", ret);
 		return 1;
 	}
-	dev = udev->uclass_priv;
+	dev = dev_get_uclass_priv(udev);
 #else
 	/* Just use the last allocated device; there should be only one */
 	if (!last_dev) {
diff --git a/drivers/misc/cros_ec_i2c.c b/drivers/misc/cros_ec_i2c.c
index f9bc975..cee9a0f 100644
--- a/drivers/misc/cros_ec_i2c.c
+++ b/drivers/misc/cros_ec_i2c.c
@@ -28,7 +28,7 @@ static int cros_ec_i2c_command(struct udevice *udev, uint8_t cmd,
 			       int cmd_version, const uint8_t *dout,
 			       int dout_len, uint8_t **dinp, int din_len)
 {
-	struct cros_ec_dev *dev = udev->uclass_priv;
+	struct cros_ec_dev *dev = dev_get_uclass_priv(udev);
 	/* version8, cmd8, arglen8, out8[dout_len], csum8 */
 	int out_bytes = dout_len + 4;
 	/* response8, arglen8, in8[din_len], checksum8 */
diff --git a/drivers/misc/cros_ec_sandbox.c b/drivers/misc/cros_ec_sandbox.c
index 99cc529..282d8d8 100644
--- a/drivers/misc/cros_ec_sandbox.c
+++ b/drivers/misc/cros_ec_sandbox.c
@@ -470,7 +470,7 @@ static int process_cmd(struct ec_state *ec,
 #ifdef CONFIG_DM_CROS_EC
 int cros_ec_sandbox_packet(struct udevice *udev, int out_bytes, int in_bytes)
 {
-	struct cros_ec_dev *dev = udev->uclass_priv;
+	struct cros_ec_dev *dev = dev_get_uclass_priv(udev);
 	struct ec_state *ec = dev_get_priv(dev->dev);
 #else
 int cros_ec_sandbox_packet(struct cros_ec_dev *dev, int out_bytes,
diff --git a/drivers/misc/cros_ec_spi.c b/drivers/misc/cros_ec_spi.c
index 9359c56..98e8f60 100644
--- a/drivers/misc/cros_ec_spi.c
+++ b/drivers/misc/cros_ec_spi.c
@@ -23,7 +23,7 @@ DECLARE_GLOBAL_DATA_PTR;
 
 int cros_ec_spi_packet(struct udevice *udev, int out_bytes, int in_bytes)
 {
-	struct cros_ec_dev *dev = udev->uclass_priv;
+	struct cros_ec_dev *dev = dev_get_uclass_priv(udev);
 	struct spi_slave *slave = dev_get_parentdata(dev->dev);
 	int rv;
 
@@ -66,7 +66,7 @@ int cros_ec_spi_command(struct udevice *udev, uint8_t cmd, int cmd_version,
 		     const uint8_t *dout, int dout_len,
 		     uint8_t **dinp, int din_len)
 {
-	struct cros_ec_dev *dev = udev->uclass_priv;
+	struct cros_ec_dev *dev = dev_get_uclass_priv(udev);
 	struct spi_slave *slave = dev_get_parentdata(dev->dev);
 	int in_bytes = din_len + 4;	/* status, length, checksum, trailer */
 	uint8_t *out;
diff --git a/drivers/mtd/spi/sf-uclass.c b/drivers/mtd/spi/sf-uclass.c
index 376d815..fcf67e0 100644
--- a/drivers/mtd/spi/sf-uclass.c
+++ b/drivers/mtd/spi/sf-uclass.c
@@ -23,7 +23,7 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
 	if (spi_flash_probe_bus_cs(bus, cs, max_hz, spi_mode, &dev))
 		return NULL;
 
-	return dev->uclass_priv;
+	return dev_get_uclass_priv(dev);
 }
 
 void spi_flash_free(struct spi_flash *flash)
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
index 4103723..c2dac66 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -458,7 +458,7 @@ void spi_flash_free(struct spi_flash *flash)
 static int spi_flash_std_read(struct udevice *dev, u32 offset, size_t len,
 			      void *buf)
 {
-	struct spi_flash *flash = dev->uclass_priv;
+	struct spi_flash *flash = dev_get_uclass_priv(dev);
 
 	return spi_flash_cmd_read_ops(flash, offset, len, buf);
 }
@@ -466,14 +466,14 @@ static int spi_flash_std_read(struct udevice *dev, u32 offset, size_t len,
 int spi_flash_std_write(struct udevice *dev, u32 offset, size_t len,
 			const void *buf)
 {
-	struct spi_flash *flash = dev->uclass_priv;
+	struct spi_flash *flash = dev_get_uclass_priv(dev);
 
 	return spi_flash_cmd_write_ops(flash, offset, len, buf);
 }
 
 int spi_flash_std_erase(struct udevice *dev, u32 offset, size_t len)
 {
-	struct spi_flash *flash = dev->uclass_priv;
+	struct spi_flash *flash = dev_get_uclass_priv(dev);
 
 	return spi_flash_cmd_erase_ops(flash, offset, len);
 }
@@ -484,7 +484,7 @@ int spi_flash_std_probe(struct udevice *dev)
 	struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
 	struct spi_flash *flash;
 
-	flash = dev->uclass_priv;
+	flash = dev_get_uclass_priv(dev);
 	flash->dev = dev;
 	debug("%s: slave=%p, cs=%d\n", __func__, slave, plat->cs);
 	return spi_flash_probe_slave(slave, flash);
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index 3fc7104..9ab86e2 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -253,7 +253,7 @@ static int serial_post_probe(struct udevice *dev)
 {
 	struct dm_serial_ops *ops = serial_get_ops(dev);
 #ifdef CONFIG_DM_STDIO
-	struct serial_dev_priv *upriv = dev->uclass_priv;
+	struct serial_dev_priv *upriv = dev_get_uclass_priv(dev);
 	struct stdio_dev sdev;
 #endif
 	int ret;
@@ -301,7 +301,7 @@ static int serial_post_probe(struct udevice *dev)
 static int serial_pre_remove(struct udevice *dev)
 {
 #ifdef CONFIG_SYS_STDIO_DEREGISTER
-	struct serial_dev_priv *upriv = dev->uclass_priv;
+	struct serial_dev_priv *upriv = dev_get_uclass_priv(dev);
 
 	if (stdio_deregister_dev(upriv->sdev, 0))
 		return -EPERM;
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index 63a6217..866c48f 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -50,7 +50,7 @@ int spi_claim_bus(struct spi_slave *slave)
 	struct udevice *dev = slave->dev;
 	struct udevice *bus = dev->parent;
 	struct dm_spi_ops *ops = spi_get_ops(bus);
-	struct dm_spi_bus *spi = bus->uclass_priv;
+	struct dm_spi_bus *spi = dev_get_uclass_priv(bus);
 	int speed;
 	int ret;
 
@@ -110,7 +110,7 @@ int spi_child_post_bind(struct udevice *dev)
 
 int spi_post_probe(struct udevice *bus)
 {
-	struct dm_spi_bus *spi = bus->uclass_priv;
+	struct dm_spi_bus *spi = dev_get_uclass_priv(bus);
 
 	spi->max_hz = fdtdec_get_int(gd->fdt_blob, bus->of_offset,
 				     "spi-max-frequency", 0);
diff --git a/include/dm/device.h b/include/dm/device.h
index 7a48eb8..6980954 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -238,6 +238,16 @@ void *dev_get_priv(struct udevice *dev);
 struct udevice *dev_get_parent(struct udevice *child);
 
 /**
+ * dev_get_uclass_priv() - Get the private uclass data for a device
+ *
+ * This checks that dev is not NULL, but no other checks for now
+ *
+ * @dev		Device to check
+ * @return private uclass data for this device, or NULL if none
+ */
+void *dev_get_uclass_priv(struct udevice *dev);
+
+/**
  * dev_get_of_data() - get the device tree data used to bind a device
  *
  * When a device is bound using a device tree node, it matches a
diff --git a/include/i2c.h b/include/i2c.h
index 31b0389..6fd73fa 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -64,8 +64,8 @@ struct dm_i2c_chip {
  * bus can operate at different speeds (measured in Hz, typically 100KHz
  * or 400KHz).
  *
- * To obtain this structure, use bus->uclass_priv where bus is the I2C
- * bus udevice.
+ * To obtain this structure, use dev_get_uclass_priv(bus) where bus is the
+ * I2C bus udevice.
  *
  * @speed_hz: Bus speed in hertz (typically 100000)
  */
@@ -340,7 +340,7 @@ struct dm_i2c_ops {
 	 * The bus speed value will be updated by the uclass if this function
 	 * does not return an error. This method is optional - if it is not
 	 * provided then the driver can read the speed from
-	 * bus->uclass_priv->speed_hz
+	 * dev_get_uclass_priv(bus)->speed_hz
 	 *
 	 * @bus:	Bus to adjust
 	 * @speed:	Requested speed in Hz
@@ -354,7 +354,7 @@ struct dm_i2c_ops {
 	 * Normally this can be provided by the uclass, but if you want your
 	 * driver to check the bus speed by looking at the hardware, you can
 	 * implement that here. This method is optional. This method would
-	 * normally be expected to return bus->uclass_priv->speed_hz.
+	 * normally be expected to return dev_get_uclass_priv(bus)->speed_hz.
 	 *
 	 * @bus:	Bus to check
 	 * @return speed of selected I2C bus in Hz, -ve on error
diff --git a/test/dm/core.c b/test/dm/core.c
index eccda09..7be28e4 100644
--- a/test/dm/core.c
+++ b/test/dm/core.c
@@ -179,7 +179,7 @@ static int dm_test_autoprobe(struct dm_test_state *dms)
 		ut_assertok(uclass_find_device(UCLASS_TEST, i, &dev));
 		ut_assert(dev);
 
-		priv = dev->uclass_priv;
+		priv = dev_get_uclass_priv(dev);
 		ut_assert(priv);
 		ut_asserteq(expected_base_add, priv->base_add);
 
diff --git a/test/dm/test-uclass.c b/test/dm/test-uclass.c
index 017e097..1b9a3fd 100644
--- a/test/dm/test-uclass.c
+++ b/test/dm/test-uclass.c
@@ -47,7 +47,7 @@ static int test_post_probe(struct udevice *dev)
 	struct udevice *prev = list_entry(dev->uclass_node.prev,
 					    struct udevice, uclass_node);
 
-	struct dm_test_uclass_perdev_priv *priv = dev->uclass_priv;
+	struct dm_test_uclass_perdev_priv *priv = dev_get_uclass_priv(dev);
 	struct uclass *uc = dev->uclass;
 
 	dm_testdrv_op_count[DM_TEST_OP_POST_PROBE]++;
@@ -58,7 +58,7 @@ static int test_post_probe(struct udevice *dev)
 		return 0;
 	if (&prev->uclass_node != &uc->dev_head) {
 		struct dm_test_uclass_perdev_priv *prev_uc_priv
-				= prev->uclass_priv;
+				= dev_get_uclass_priv(prev);
 		struct dm_test_pdata *pdata = prev->platdata;
 
 		ut_assert(pdata);
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 09/22] dm: core: Mark device as active before calling its probe() method
  2015-03-05 19:25 [U-Boot] [PATCH v2 0/22] Add driver model support for PCI Simon Glass
                   ` (7 preceding siblings ...)
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 08/22] dm: core: Add dev_get_uclass_priv() to access uclass private data Simon Glass
@ 2015-03-05 19:25 ` Simon Glass
  2015-03-20 23:15   ` Simon Glass
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 10/22] dm: core: Add a uclass pre_probe() method for devices Simon Glass
                   ` (13 subsequent siblings)
  22 siblings, 1 reply; 53+ messages in thread
From: Simon Glass @ 2015-03-05 19:25 UTC (permalink / raw)
  To: u-boot

At present the device is not active when the probe() method is called. But
some probe() methods want to set up the device and this can involve
accessing it through normal methods. For example a PCI bus may wish to
set up its PCI parameters using calls to pci_hose_write_config_dword() and
similar.

At present this does not work because every such call within the probe()
method sees that the device is not active and attempts to probe it.

Already we mark the device as probed before calling the uclass post_probe()
method. This is a subtle change but I believe the new approach is better.
Since the scope of the change is only the probe() method and all its callees
it should still be within the control of the board author.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/core/device.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index 92e8a57..6bd4b26 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -243,14 +243,15 @@ int device_probe_child(struct udevice *dev, void *parent_priv)
 			goto fail;
 	}
 
+	dev->flags |= DM_FLAG_ACTIVATED;
 	if (drv->probe) {
 		ret = drv->probe(dev);
-		if (ret)
+		if (ret) {
+			dev->flags &= ~DM_FLAG_ACTIVATED;
 			goto fail;
+		}
 	}
 
-	dev->flags |= DM_FLAG_ACTIVATED;
-
 	ret = uclass_post_probe_device(dev);
 	if (ret) {
 		dev->flags &= ~DM_FLAG_ACTIVATED;
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 10/22] dm: core: Add a uclass pre_probe() method for devices
  2015-03-05 19:25 [U-Boot] [PATCH v2 0/22] Add driver model support for PCI Simon Glass
                   ` (8 preceding siblings ...)
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 09/22] dm: core: Mark device as active before calling its probe() method Simon Glass
@ 2015-03-05 19:25 ` Simon Glass
  2015-03-20 23:15   ` Simon Glass
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 11/22] dm: Show both allocated and requested seq numbers in 'dm uclass' Simon Glass
                   ` (12 subsequent siblings)
  22 siblings, 1 reply; 53+ messages in thread
From: Simon Glass @ 2015-03-05 19:25 UTC (permalink / raw)
  To: u-boot

Some uclasses want to set up a device before it is probed. Add a method
for this.

An example is with PCI, where a PCI uclass wants to set up its private
data for later use. This allows the device's uclass() method to make calls
whcih use that data (for example, read PCI memory regions from device
tree, set up bus numbers).

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/core/device.c        |  2 +-
 drivers/core/uclass.c        | 10 +++++++++-
 include/dm/test.h            |  1 +
 include/dm/uclass-internal.h |  7 ++++---
 include/dm/uclass.h          |  2 ++
 test/dm/core.c               |  7 ++++++-
 test/dm/test-uclass.c        | 12 ++++++++++++
 7 files changed, 35 insertions(+), 6 deletions(-)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index 6bd4b26..7483405 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -227,7 +227,7 @@ int device_probe_child(struct udevice *dev, void *parent_priv)
 	}
 	dev->seq = seq;
 
-	ret = uclass_pre_probe_child(dev);
+	ret = uclass_pre_probe_device(dev);
 	if (ret)
 		goto fail;
 
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index 289a5d2..98c15e5 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -391,9 +391,17 @@ int uclass_resolve_seq(struct udevice *dev)
 	return seq;
 }
 
-int uclass_pre_probe_child(struct udevice *dev)
+int uclass_pre_probe_device(struct udevice *dev)
 {
 	struct uclass_driver *uc_drv;
+	int ret;
+
+	uc_drv = dev->uclass->uc_drv;
+	if (uc_drv->pre_probe) {
+		ret = uc_drv->pre_probe(dev);
+		if (ret)
+			return ret;
+	}
 
 	if (!dev->parent)
 		return 0;
diff --git a/include/dm/test.h b/include/dm/test.h
index 707c69e..b310e5f 100644
--- a/include/dm/test.h
+++ b/include/dm/test.h
@@ -44,6 +44,7 @@ enum {
 	/* For uclass */
 	DM_TEST_OP_POST_BIND,
 	DM_TEST_OP_PRE_UNBIND,
+	DM_TEST_OP_PRE_PROBE,
 	DM_TEST_OP_POST_PROBE,
 	DM_TEST_OP_PRE_REMOVE,
 	DM_TEST_OP_INIT,
diff --git a/include/dm/uclass-internal.h b/include/dm/uclass-internal.h
index f2f254a..ae2a93d 100644
--- a/include/dm/uclass-internal.h
+++ b/include/dm/uclass-internal.h
@@ -44,15 +44,16 @@ int uclass_bind_device(struct udevice *dev);
 int uclass_unbind_device(struct udevice *dev);
 
 /**
- * uclass_pre_probe_child() - Deal with a child that is about to be probed
+ * uclass_pre_probe_device() - Deal with a device that is about to be probed
  *
  * Perform any pre-processing that is needed by the uclass before it can be
- * probed.
+ * probed. This includes the uclass' pre-probe() method and the parent
+ * uclass' child_pre_probe() method.
  *
  * @dev:	Pointer to the device
  * #return 0 on success, -ve on error
  */
-int uclass_pre_probe_child(struct udevice *dev);
+int uclass_pre_probe_device(struct udevice *dev);
 
 /**
  * uclass_post_probe_device() - Deal with a device that has just been probed
diff --git a/include/dm/uclass.h b/include/dm/uclass.h
index d6c40c6..d57d804 100644
--- a/include/dm/uclass.h
+++ b/include/dm/uclass.h
@@ -53,6 +53,7 @@ struct udevice;
  * @id: ID number of this uclass
  * @post_bind: Called after a new device is bound to this uclass
  * @pre_unbind: Called before a device is unbound from this uclass
+ * @pre_probe: Called before a new device is probed
  * @post_probe: Called after a new device is probed
  * @pre_remove: Called before a device is removed
  * @child_post_bind: Called after a child is bound to a device in this uclass
@@ -80,6 +81,7 @@ struct uclass_driver {
 	enum uclass_id id;
 	int (*post_bind)(struct udevice *dev);
 	int (*pre_unbind)(struct udevice *dev);
+	int (*pre_probe)(struct udevice *dev);
 	int (*post_probe)(struct udevice *dev);
 	int (*pre_remove)(struct udevice *dev);
 	int (*child_post_bind)(struct udevice *dev);
diff --git a/test/dm/core.c b/test/dm/core.c
index 7be28e4..990d390 100644
--- a/test/dm/core.c
+++ b/test/dm/core.c
@@ -141,6 +141,7 @@ static int dm_test_autoprobe(struct dm_test_state *dms)
 	ut_assert(uc);
 
 	ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_INIT]);
+	ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]);
 	ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_POST_PROBE]);
 
 	/* The root device should not be activated until needed */
@@ -167,8 +168,12 @@ static int dm_test_autoprobe(struct dm_test_state *dms)
 			ut_assert(dms->root->flags & DM_FLAG_ACTIVATED);
 	}
 
-	/* Our 3 dm_test_infox children should be passed to post_probe */
+	/*
+	 * Our 3 dm_test_info children should be passed to pre_probe and
+	 * post_probe
+	 */
 	ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_POST_PROBE]);
+	ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]);
 
 	/* Also we can check the per-device data */
 	expected_base_add = 0;
diff --git a/test/dm/test-uclass.c b/test/dm/test-uclass.c
index 1b9a3fd..be91657 100644
--- a/test/dm/test-uclass.c
+++ b/test/dm/test-uclass.c
@@ -42,6 +42,17 @@ static int test_pre_unbind(struct udevice *dev)
 	return 0;
 }
 
+static int test_pre_probe(struct udevice *dev)
+{
+	struct dm_test_uclass_perdev_priv *priv = dev_get_uclass_priv(dev);
+
+	dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]++;
+	ut_assert(priv);
+	ut_assert(!device_active(dev));
+
+	return 0;
+}
+
 static int test_post_probe(struct udevice *dev)
 {
 	struct udevice *prev = list_entry(dev->uclass_node.prev,
@@ -96,6 +107,7 @@ UCLASS_DRIVER(test) = {
 	.id		= UCLASS_TEST,
 	.post_bind	= test_post_bind,
 	.pre_unbind	= test_pre_unbind,
+	.pre_probe	= test_pre_probe,
 	.post_probe	= test_post_probe,
 	.pre_remove	= test_pre_remove,
 	.init		= test_init,
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 11/22] dm: Show both allocated and requested seq numbers in 'dm uclass'
  2015-03-05 19:25 [U-Boot] [PATCH v2 0/22] Add driver model support for PCI Simon Glass
                   ` (9 preceding siblings ...)
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 10/22] dm: core: Add a uclass pre_probe() method for devices Simon Glass
@ 2015-03-05 19:25 ` Simon Glass
  2015-03-20 23:16   ` Simon Glass
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 12/22] dm: pci: Move common PCI functions into their own file Simon Glass
                   ` (11 subsequent siblings)
  22 siblings, 1 reply; 53+ messages in thread
From: Simon Glass @ 2015-03-05 19:25 UTC (permalink / raw)
  To: u-boot

Both of these values are useful for understanding what is going on, so show
them both.

The requested number comes from a device tree alias. The allocated one is
set up when the device is activated, and is unique throughout the uclass.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 test/dm/cmd_dm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/test/dm/cmd_dm.c b/test/dm/cmd_dm.c
index 79a674e..507f260 100644
--- a/test/dm/cmd_dm.c
+++ b/test/dm/cmd_dm.c
@@ -77,8 +77,8 @@ static void dm_display_line(struct udevice *dev)
 	printf("- %c %s @ %08lx",
 	       dev->flags & DM_FLAG_ACTIVATED ? '*' : ' ',
 	       dev->name, (ulong)map_to_sysmem(dev));
-	if (dev->req_seq != -1)
-		printf(", %d", dev->req_seq);
+	if (dev->seq != -1 || dev->req_seq != -1)
+		printf(", seq-%d, (req=%d)", dev->seq, dev->req_seq);
 	puts("\n");
 }
 
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 12/22] dm: pci: Move common PCI functions into their own file
  2015-03-05 19:25 [U-Boot] [PATCH v2 0/22] Add driver model support for PCI Simon Glass
                   ` (10 preceding siblings ...)
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 11/22] dm: Show both allocated and requested seq numbers in 'dm uclass' Simon Glass
@ 2015-03-05 19:25 ` Simon Glass
  2015-03-20 23:16   ` Simon Glass
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 13/22] dm: pci: Add a uclass for PCI Simon Glass
                   ` (10 subsequent siblings)
  22 siblings, 1 reply; 53+ messages in thread
From: Simon Glass @ 2015-03-05 19:25 UTC (permalink / raw)
  To: u-boot

Driver model will share many functions with the existing PCI implementation.
Move these into their own file to avoid duplication and confusion.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/pci/Makefile     |   2 +-
 drivers/pci/pci.c        | 281 +--------------------------------------------
 drivers/pci/pci_common.c | 292 +++++++++++++++++++++++++++++++++++++++++++++++
 include/pci.h            |  14 +++
 4 files changed, 313 insertions(+), 276 deletions(-)
 create mode 100644 drivers/pci/pci_common.c

diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 50b7be5..856a5f5 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -6,7 +6,7 @@
 #
 
 obj-$(CONFIG_FSL_PCI_INIT) += fsl_pci_init.o
-obj-$(CONFIG_PCI) += pci.o pci_auto.o pci_rom.o
+obj-$(CONFIG_PCI) += pci.o  pci_common.o pci_auto.o pci_rom.o
 obj-$(CONFIG_PCI_INDIRECT_BRIDGE) += pci_indirect.o
 obj-$(CONFIG_PCI_GT64120) += pci_gt64120.o
 obj-$(CONFIG_PCI_MSC01) += pci_msc01.o
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index e1296ca..3babd94 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -101,25 +101,6 @@ PCI_READ_VIA_DWORD_OP(word, u16 *, 0x02)
 PCI_WRITE_VIA_DWORD_OP(byte, u8, 0x03, 0x000000ff)
 PCI_WRITE_VIA_DWORD_OP(word, u16, 0x02, 0x0000ffff)
 
-/* Get a virtual address associated with a BAR region */
-void *pci_map_bar(pci_dev_t pdev, int bar, int flags)
-{
-	pci_addr_t pci_bus_addr;
-	u32 bar_response;
-
-	/* read BAR address */
-	pci_read_config_dword(pdev, bar, &bar_response);
-	pci_bus_addr = (pci_addr_t)(bar_response & ~0xf);
-
-	/*
-	 * Pass "0" as the length argument to pci_bus_to_virt.  The arg
-	 * isn't actualy used on any platform because u-boot assumes a static
-	 * linear mapping.  In the future, this could read the BAR size
-	 * and pass that as the size if needed.
-	 */
-	return pci_bus_to_virt(pdev, pci_bus_addr, flags, 0, MAP_NOCACHE);
-}
-
 /*
  *
  */
@@ -187,106 +168,22 @@ int pci_last_busno(void)
 pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
 {
 	struct pci_controller * hose;
-	u16 vendor, device;
-	u8 header_type;
 	pci_dev_t bdf;
-	int i, bus, found_multi = 0;
+	int bus;
 
 	for (hose = pci_get_hose_head(); hose; hose = hose->next) {
 #ifdef CONFIG_SYS_SCSI_SCAN_BUS_REVERSE
-		for (bus = hose->last_busno; bus >= hose->first_busno; bus--)
+		for (bus = hose->last_busno; bus >= hose->first_busno; bus--) {
 #else
-		for (bus = hose->first_busno; bus <= hose->last_busno; bus++)
+		for (bus = hose->first_busno; bus <= hose->last_busno; bus++) {
 #endif
-			for (bdf = PCI_BDF(bus, 0, 0);
-			     bdf < PCI_BDF(bus + 1, 0, 0);
-			     bdf += PCI_BDF(0, 0, 1)) {
-				if (pci_skip_dev(hose, bdf))
-					continue;
-
-				if (!PCI_FUNC(bdf)) {
-					pci_read_config_byte(bdf,
-							     PCI_HEADER_TYPE,
-							     &header_type);
-
-					found_multi = header_type & 0x80;
-				} else {
-					if (!found_multi)
-						continue;
-				}
-
-				pci_read_config_word(bdf,
-						     PCI_VENDOR_ID,
-						     &vendor);
-				pci_read_config_word(bdf,
-						     PCI_DEVICE_ID,
-						     &device);
-
-				for (i = 0; ids[i].vendor != 0; i++) {
-					if (vendor == ids[i].vendor &&
-					    device == ids[i].device) {
-						if (index <= 0)
-							return bdf;
-
-						index--;
-					}
-				}
-			}
-	}
-
-	return -1;
-}
-
-pci_dev_t pci_find_class(uint find_class, int index)
-{
-	int bus;
-	int devnum;
-	pci_dev_t bdf;
-	uint32_t class;
-
-	for (bus = 0; bus <= pci_last_busno(); bus++) {
-		for (devnum = 0; devnum < PCI_MAX_PCI_DEVICES - 1; devnum++) {
-			pci_read_config_dword(PCI_BDF(bus, devnum, 0),
-					      PCI_CLASS_REVISION, &class);
-			if (class >> 16 == 0xffff)
-				continue;
-
-			for (bdf = PCI_BDF(bus, devnum, 0);
-					bdf <= PCI_BDF(bus, devnum,
-						PCI_MAX_PCI_FUNCTIONS - 1);
-					bdf += PCI_BDF(0, 0, 1)) {
-				pci_read_config_dword(bdf, PCI_CLASS_REVISION,
-						      &class);
-				class >>= 8;
-
-				if (class != find_class)
-					continue;
-				/*
-				 * Decrement the index. We want to return the
-				 * correct device, so index is 0 for the first
-				 * matching device, 1 for the second, etc.
-				 */
-				if (index) {
-					index--;
-					continue;
-				}
-				/* Return index'th controller. */
+			bdf = pci_hose_find_devices(hose, bus, ids, &index);
+			if (bdf != -1)
 				return bdf;
-			}
 		}
 	}
 
-	return -ENODEV;
-}
-
-pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index)
-{
-	struct pci_device_id ids[2] = { {}, {0, 0} };
-
-	ids[0].vendor = vendor;
-	ids[0].device = device;
-
-	return pci_find_devices(ids, index);
+	return -1;
 }
 
 /*
@@ -355,87 +252,6 @@ pci_addr_t pci_hose_phys_to_bus (struct pci_controller *hose,
 	return bus_addr;
 }
 
-int __pci_hose_bus_to_phys(struct pci_controller *hose,
-				pci_addr_t bus_addr,
-				unsigned long flags,
-				unsigned long skip_mask,
-				phys_addr_t *pa)
-{
-	struct pci_region *res;
-	int i;
-
-	for (i = 0; i < hose->region_count; i++) {
-		res = &hose->regions[i];
-
-		if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
-			continue;
-
-		if (res->flags & skip_mask)
-			continue;
-
-		if (bus_addr >= res->bus_start &&
-			(bus_addr - res->bus_start) < res->size) {
-			*pa = (bus_addr - res->bus_start + res->phys_start);
-			return 0;
-		}
-	}
-
-	return 1;
-}
-
-phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose,
-				 pci_addr_t bus_addr,
-				 unsigned long flags)
-{
-	phys_addr_t phys_addr = 0;
-	int ret;
-
-	if (!hose) {
-		puts("pci_hose_bus_to_phys: invalid hose\n");
-		return phys_addr;
-	}
-
-	/*
-	 * if PCI_REGION_MEM is set we do a two pass search with preference
-	 * on matches that don't have PCI_REGION_SYS_MEMORY set
-	 */
-	if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) {
-		ret = __pci_hose_bus_to_phys(hose, bus_addr,
-				flags, PCI_REGION_SYS_MEMORY, &phys_addr);
-		if (!ret)
-			return phys_addr;
-	}
-
-	ret = __pci_hose_bus_to_phys(hose, bus_addr, flags, 0, &phys_addr);
-
-	if (ret)
-		puts("pci_hose_bus_to_phys: invalid physical address\n");
-
-	return phys_addr;
-}
-
-void pci_write_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum,
-		     u32 addr_and_ctrl)
-{
-	int bar;
-
-	bar = PCI_BASE_ADDRESS_0 + barnum * 4;
-	pci_hose_write_config_dword(hose, dev, bar, addr_and_ctrl);
-}
-
-u32 pci_read_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum)
-{
-	u32 addr;
-	int bar;
-
-	bar = PCI_BASE_ADDRESS_0 + barnum * 4;
-	pci_hose_read_config_dword(hose, dev, bar, &addr);
-	if (addr & PCI_BASE_ADDRESS_SPACE_IO)
-		return addr & PCI_BASE_ADDRESS_IO_MASK;
-	else
-		return addr & PCI_BASE_ADDRESS_MEM_MASK;
-}
-
 int pci_hose_config_device(struct pci_controller *hose,
 			   pci_dev_t dev,
 			   unsigned long io,
@@ -576,91 +392,6 @@ void pci_cfgfunc_do_nothing(struct pci_controller *hose,
  */
 extern int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);
 
-#if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI_SCAN_SHOW)
-const char * pci_class_str(u8 class)
-{
-	switch (class) {
-	case PCI_CLASS_NOT_DEFINED:
-		return "Build before PCI Rev2.0";
-		break;
-	case PCI_BASE_CLASS_STORAGE:
-		return "Mass storage controller";
-		break;
-	case PCI_BASE_CLASS_NETWORK:
-		return "Network controller";
-		break;
-	case PCI_BASE_CLASS_DISPLAY:
-		return "Display controller";
-		break;
-	case PCI_BASE_CLASS_MULTIMEDIA:
-		return "Multimedia device";
-		break;
-	case PCI_BASE_CLASS_MEMORY:
-		return "Memory controller";
-		break;
-	case PCI_BASE_CLASS_BRIDGE:
-		return "Bridge device";
-		break;
-	case PCI_BASE_CLASS_COMMUNICATION:
-		return "Simple comm. controller";
-		break;
-	case PCI_BASE_CLASS_SYSTEM:
-		return "Base system peripheral";
-		break;
-	case PCI_BASE_CLASS_INPUT:
-		return "Input device";
-		break;
-	case PCI_BASE_CLASS_DOCKING:
-		return "Docking station";
-		break;
-	case PCI_BASE_CLASS_PROCESSOR:
-		return "Processor";
-		break;
-	case PCI_BASE_CLASS_SERIAL:
-		return "Serial bus controller";
-		break;
-	case PCI_BASE_CLASS_INTELLIGENT:
-		return "Intelligent controller";
-		break;
-	case PCI_BASE_CLASS_SATELLITE:
-		return "Satellite controller";
-		break;
-	case PCI_BASE_CLASS_CRYPT:
-		return "Cryptographic device";
-		break;
-	case PCI_BASE_CLASS_SIGNAL_PROCESSING:
-		return "DSP";
-		break;
-	case PCI_CLASS_OTHERS:
-		return "Does not fit any class";
-		break;
-	default:
-	return  "???";
-		break;
-	};
-}
-#endif /* CONFIG_CMD_PCI || CONFIG_PCI_SCAN_SHOW */
-
-__weak int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
-{
-	/*
-	 * Check if pci device should be skipped in configuration
-	 */
-	if (dev == PCI_BDF(hose->first_busno, 0, 0)) {
-#if defined(CONFIG_PCI_CONFIG_HOST_BRIDGE) /* don't skip host bridge */
-		/*
-		 * Only skip configuration if "pciconfighost" is not set
-		 */
-		if (getenv("pciconfighost") == NULL)
-			return 1;
-#else
-		return 1;
-#endif
-	}
-
-	return 0;
-}
-
 #ifdef CONFIG_PCI_SCAN_SHOW
 __weak int pci_print_dev(struct pci_controller *hose, pci_dev_t dev)
 {
diff --git a/drivers/pci/pci_common.c b/drivers/pci/pci_common.c
new file mode 100644
index 0000000..24c66bb
--- /dev/null
+++ b/drivers/pci/pci_common.c
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.de>
+ *
+ * (C) Copyright 2002, 2003
+ * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <pci.h>
+#include <asm/io.h>
+
+const char *pci_class_str(u8 class)
+{
+	switch (class) {
+	case PCI_CLASS_NOT_DEFINED:
+		return "Build before PCI Rev2.0";
+		break;
+	case PCI_BASE_CLASS_STORAGE:
+		return "Mass storage controller";
+		break;
+	case PCI_BASE_CLASS_NETWORK:
+		return "Network controller";
+		break;
+	case PCI_BASE_CLASS_DISPLAY:
+		return "Display controller";
+		break;
+	case PCI_BASE_CLASS_MULTIMEDIA:
+		return "Multimedia device";
+		break;
+	case PCI_BASE_CLASS_MEMORY:
+		return "Memory controller";
+		break;
+	case PCI_BASE_CLASS_BRIDGE:
+		return "Bridge device";
+		break;
+	case PCI_BASE_CLASS_COMMUNICATION:
+		return "Simple comm. controller";
+		break;
+	case PCI_BASE_CLASS_SYSTEM:
+		return "Base system peripheral";
+		break;
+	case PCI_BASE_CLASS_INPUT:
+		return "Input device";
+		break;
+	case PCI_BASE_CLASS_DOCKING:
+		return "Docking station";
+		break;
+	case PCI_BASE_CLASS_PROCESSOR:
+		return "Processor";
+		break;
+	case PCI_BASE_CLASS_SERIAL:
+		return "Serial bus controller";
+		break;
+	case PCI_BASE_CLASS_INTELLIGENT:
+		return "Intelligent controller";
+		break;
+	case PCI_BASE_CLASS_SATELLITE:
+		return "Satellite controller";
+		break;
+	case PCI_BASE_CLASS_CRYPT:
+		return "Cryptographic device";
+		break;
+	case PCI_BASE_CLASS_SIGNAL_PROCESSING:
+		return "DSP";
+		break;
+	case PCI_CLASS_OTHERS:
+		return "Does not fit any class";
+		break;
+	default:
+	return  "???";
+		break;
+	};
+}
+
+pci_dev_t pci_find_class(uint find_class, int index)
+{
+	int bus;
+	int devnum;
+	pci_dev_t bdf;
+	uint32_t class;
+
+	for (bus = 0; bus <= pci_last_busno(); bus++) {
+		for (devnum = 0; devnum < PCI_MAX_PCI_DEVICES - 1; devnum++) {
+			pci_read_config_dword(PCI_BDF(bus, devnum, 0),
+					      PCI_CLASS_REVISION, &class);
+			if (class >> 16 == 0xffff)
+				continue;
+
+			for (bdf = PCI_BDF(bus, devnum, 0);
+					bdf <= PCI_BDF(bus, devnum,
+						PCI_MAX_PCI_FUNCTIONS - 1);
+					bdf += PCI_BDF(0, 0, 1)) {
+				pci_read_config_dword(bdf, PCI_CLASS_REVISION,
+						      &class);
+				class >>= 8;
+
+				if (class != find_class)
+					continue;
+				/*
+				 * Decrement the index. We want to return the
+				 * correct device, so index is 0 for the first
+				 * matching device, 1 for the second, etc.
+				 */
+				if (index) {
+					index--;
+					continue;
+				}
+				/* Return index'th controller. */
+				return bdf;
+			}
+		}
+	}
+
+	return -ENODEV;
+}
+
+__weak int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
+{
+	/*
+	 * Check if pci device should be skipped in configuration
+	 */
+	if (dev == PCI_BDF(hose->first_busno, 0, 0)) {
+#if defined(CONFIG_PCI_CONFIG_HOST_BRIDGE) /* don't skip host bridge */
+		/*
+		 * Only skip configuration if "pciconfighost" is not set
+		 */
+		if (getenv("pciconfighost") == NULL)
+			return 1;
+#else
+		return 1;
+#endif
+	}
+
+	return 0;
+}
+
+/* Get a virtual address associated with a BAR region */
+void *pci_map_bar(pci_dev_t pdev, int bar, int flags)
+{
+	pci_addr_t pci_bus_addr;
+	u32 bar_response;
+
+	/* read BAR address */
+	pci_read_config_dword(pdev, bar, &bar_response);
+	pci_bus_addr = (pci_addr_t)(bar_response & ~0xf);
+
+	/*
+	 * Pass "0" as the length argument to pci_bus_to_virt.  The arg
+	 * isn't actualy used on any platform because u-boot assumes a static
+	 * linear mapping.  In the future, this could read the BAR size
+	 * and pass that as the size if needed.
+	 */
+	return pci_bus_to_virt(pdev, pci_bus_addr, flags, 0, MAP_NOCACHE);
+}
+
+void pci_write_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum,
+		     u32 addr_and_ctrl)
+{
+	int bar;
+
+	bar = PCI_BASE_ADDRESS_0 + barnum * 4;
+	pci_hose_write_config_dword(hose, dev, bar, addr_and_ctrl);
+}
+
+u32 pci_read_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum)
+{
+	u32 addr;
+	int bar;
+
+	bar = PCI_BASE_ADDRESS_0 + barnum * 4;
+	pci_hose_read_config_dword(hose, dev, bar, &addr);
+	if (addr & PCI_BASE_ADDRESS_SPACE_IO)
+		return addr & PCI_BASE_ADDRESS_IO_MASK;
+	else
+		return addr & PCI_BASE_ADDRESS_MEM_MASK;
+}
+
+int __pci_hose_bus_to_phys(struct pci_controller *hose,
+				pci_addr_t bus_addr,
+				unsigned long flags,
+				unsigned long skip_mask,
+				phys_addr_t *pa)
+{
+	struct pci_region *res;
+	int i;
+
+	for (i = 0; i < hose->region_count; i++) {
+		res = &hose->regions[i];
+
+		if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
+			continue;
+
+		if (res->flags & skip_mask)
+			continue;
+
+		if (bus_addr >= res->bus_start &&
+		    (bus_addr - res->bus_start) < res->size) {
+			*pa = (bus_addr - res->bus_start + res->phys_start);
+			return 0;
+		}
+	}
+
+	return 1;
+}
+
+phys_addr_t pci_hose_bus_to_phys(struct pci_controller *hose,
+				 pci_addr_t bus_addr,
+				 unsigned long flags)
+{
+	phys_addr_t phys_addr = 0;
+	int ret;
+
+	if (!hose) {
+		puts("pci_hose_bus_to_phys: invalid hose\n");
+		return phys_addr;
+	}
+
+	/*
+	 * if PCI_REGION_MEM is set we do a two pass search with preference
+	 * on matches that don't have PCI_REGION_SYS_MEMORY set
+	 */
+	if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) {
+		ret = __pci_hose_bus_to_phys(hose, bus_addr,
+				flags, PCI_REGION_SYS_MEMORY, &phys_addr);
+		if (!ret)
+			return phys_addr;
+	}
+
+	ret = __pci_hose_bus_to_phys(hose, bus_addr, flags, 0, &phys_addr);
+
+	if (ret)
+		puts("pci_hose_bus_to_phys: invalid physical address\n");
+
+	return phys_addr;
+}
+
+pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index)
+{
+	struct pci_device_id ids[2] = { {}, {0, 0} };
+
+	ids[0].vendor = vendor;
+	ids[0].device = device;
+
+	return pci_find_devices(ids, index);
+}
+
+pci_dev_t pci_hose_find_devices(struct pci_controller *hose, int busnum,
+				struct pci_device_id *ids, int *indexp)
+{
+	int found_multi = 0;
+	u16 vendor, device;
+	u8 header_type;
+	pci_dev_t bdf;
+	int i;
+
+	for (bdf = PCI_BDF(busnum, 0, 0);
+	     bdf < PCI_BDF(busnum + 1, 0, 0);
+	     bdf += PCI_BDF(0, 0, 1)) {
+		if (pci_skip_dev(hose, bdf))
+			continue;
+
+		if (!PCI_FUNC(bdf)) {
+			pci_read_config_byte(bdf, PCI_HEADER_TYPE,
+					     &header_type);
+			found_multi = header_type & 0x80;
+		} else {
+			if (!found_multi)
+				continue;
+		}
+
+		pci_read_config_word(bdf, PCI_VENDOR_ID, &vendor);
+		pci_read_config_word(bdf, PCI_DEVICE_ID, &device);
+
+		for (i = 0; ids[i].vendor != 0; i++) {
+			if (vendor == ids[i].vendor &&
+			    device == ids[i].device) {
+				if ((*indexp) <= 0)
+					return bdf;
+
+				(*indexp)--;
+			}
+		}
+	}
+
+	return -1;
+}
diff --git a/include/pci.h b/include/pci.h
index 004a048..4e8826a 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -705,5 +705,19 @@ u32 pci_read_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum);
  */
 int pciauto_setup_rom(struct pci_controller *hose, pci_dev_t dev);
 
+/**
+ * pci_hose_find_devices() - Find devices by vendor/device ID
+ *
+ * @hose:	PCI hose to search
+ * @busnum:	Bus number to search
+ * @ids:	PCI vendor/device IDs to look for, terminated by 0, 0 record
+ * @indexp:	Pointer to device index to find. To find the first matching
+ *		device, pass 0; to find the second, pass 1, etc. This
+ *		parameter is decremented for each non-matching device so
+ *		can be called repeatedly.
+ */
+pci_dev_t pci_hose_find_devices(struct pci_controller *hose, int busnum,
+				struct pci_device_id *ids, int *indexp);
+
 #endif /* __ASSEMBLY__ */
 #endif /* _PCI_H */
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 13/22] dm: pci: Add a uclass for PCI
  2015-03-05 19:25 [U-Boot] [PATCH v2 0/22] Add driver model support for PCI Simon Glass
                   ` (11 preceding siblings ...)
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 12/22] dm: pci: Move common PCI functions into their own file Simon Glass
@ 2015-03-05 19:25 ` Simon Glass
  2015-03-20 23:16   ` Simon Glass
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 14/22] dm: sandbox: pci: Add PCI support for sandbox Simon Glass
                   ` (9 subsequent siblings)
  22 siblings, 1 reply; 53+ messages in thread
From: Simon Glass @ 2015-03-05 19:25 UTC (permalink / raw)
  To: u-boot

Add a uclass for PCI controllers and a generic one for PCI devices. Adjust
the 'pci' command and the existing PCI support to work with this new uclass.
Keep most of the compatibility code in a separate file so that it can be
removed one day.

TODO: Add more header file comments to the new parts of pci.h

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 common/board_r.c              |   2 +
 common/cmd_pci.c              |  14 +-
 doc/driver-model/pci-info.txt |  70 +++++
 drivers/pci/Kconfig           |  12 +
 drivers/pci/Makefile          |   8 +-
 drivers/pci/pci-uclass.c      | 639 ++++++++++++++++++++++++++++++++++++++++++
 drivers/pci/pci_auto.c        |  16 +-
 drivers/pci/pci_compat.c      |  43 +++
 include/dm/uclass-id.h        |   2 +
 include/pci.h                 | 289 ++++++++++++++++++-
 10 files changed, 1081 insertions(+), 14 deletions(-)
 create mode 100644 doc/driver-model/pci-info.txt
 create mode 100644 drivers/pci/pci-uclass.c
 create mode 100644 drivers/pci/pci_compat.c

diff --git a/common/board_r.c b/common/board_r.c
index 4fcd4f6..82fbc1d 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -227,7 +227,9 @@ static int initr_unlock_ram_in_cache(void)
 #ifdef CONFIG_PCI
 static int initr_pci(void)
 {
+#ifndef CONFIG_DM_PCI
 	pci_init();
+#endif
 
 	return 0;
 }
diff --git a/common/cmd_pci.c b/common/cmd_pci.c
index e3a77e3..dcecef8 100644
--- a/common/cmd_pci.c
+++ b/common/cmd_pci.c
@@ -48,6 +48,7 @@ void pciinfo(int BusNum, int ShortPCIListing)
 	unsigned char HeaderType;
 	unsigned short VendorID;
 	pci_dev_t dev;
+	int ret;
 
 	if (!hose)
 		return;
@@ -74,7 +75,10 @@ void pciinfo(int BusNum, int ShortPCIListing)
 			if (pci_skip_dev(hose, dev))
 				continue;
 
-			pci_read_config_word(dev, PCI_VENDOR_ID, &VendorID);
+			ret = pci_read_config_word(dev, PCI_VENDOR_ID,
+						   &VendorID);
+			if (ret)
+				goto error;
 			if ((VendorID == 0xFFFF) || (VendorID == 0x0000))
 				continue;
 
@@ -91,8 +95,12 @@ void pciinfo(int BusNum, int ShortPCIListing)
 				       BusNum, Device, Function);
 				pci_header_show(dev);
 			}
-	    }
-    }
+		}
+	}
+
+	return;
+error:
+	printf("Cannot read bus configuration: %d\n", ret);
 }
 
 
diff --git a/doc/driver-model/pci-info.txt b/doc/driver-model/pci-info.txt
new file mode 100644
index 0000000..63efcb7
--- /dev/null
+++ b/doc/driver-model/pci-info.txt
@@ -0,0 +1,70 @@
+PCI with Driver Model
+=====================
+
+How busses are scanned
+----------------------
+
+Any config read will end up at pci_read_config(). This uses
+uclass_get_device_by_seq() to get the PCI bus for a particular bus number.
+Bus number 0 will need to  be requested first, and the alias in the device
+tree file will point to the correct device:
+
+
+	aliases {
+		pci0 = &pci;
+	};
+
+	pci: pci-controller {
+		compatible = "sandbox,pci";
+		...
+	};
+
+
+If there is no alias the devices will be numbered sequentially in the device
+tree.
+
+The call to uclass_get_device by seq() will cause the PCI bus to be probed.
+This does a scan of the bus to locate available devices. These devices are
+bound to their appropriate driver if available. If there is no driver, then
+they are bound to a generic PCI driver which does nothing.
+
+After probing a bus, the available devices will appear in the device tree
+under that bus.
+
+Note that this is all done on a lazy basis, as needed, so until something is
+touched on PCI it will not be probed.
+
+PCI devices can appear in the device tree. If they do this serves to specify
+the driver to use for the device. In this case they will be bound at
+start-up.
+
+
+Sandbox
+-------
+
+With sandbox we need a device emulator for each device on the bus since there
+is no real PCI bus. This works by looking in the device tree node for a
+driver. For example:
+
+
+	pci at 1f,0 {
+		compatible = "pci-generic";
+		reg = <0xf800 0 0 0 0>;
+		emul at 1f,0 {
+			compatible = "sandbox,swap-case";
+		};
+	};
+
+This means that there is a 'sandbox,swap-case' driver at that bus position.
+Note that the first cell in the 'reg' value is the bus/device/function. See
+PCI_BDF() for the encoding (it is also specified in the IEEE Std 1275-1994
+PCI bus binding document, v2.1)
+
+When this bus is scanned we will end up with something like this:
+
+`- * pci-controller @ 05c660c8, 0
+ `-   pci at 1f,0 @ 05c661c8, 63488
+  `-   emul at 1f,0 @ 05c662c8
+
+When accesses go to the pci at 1f,0 device they are forwarded to its child, the
+emulator.
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index e69de29..8b7e2ee 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -0,0 +1,12 @@
+menu "PCI"
+
+config DM_PCI
+	bool "Enable driver mode for PCI"
+	depends on DM
+	help
+	  Use driver model for PCI. Driver model is the new method for
+	  orgnising devices in U-Boot. For PCI, driver model keeps track of
+	  available PCI devices, allows scanning of PCI buses and provides
+	  device configuration support.
+
+endmenu
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 856a5f5..db82786 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -5,8 +5,14 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
+ifneq ($(CONFIG_DM_PCI),)
+obj-$(CONFIG_PCI) += pci-uclass.o pci_compat.o
+else
+obj-$(CONFIG_PCI) += pci.o
+endif
+obj-$(CONFIG_PCI) += pci_common.o pci_auto.o pci_rom.o
+
 obj-$(CONFIG_FSL_PCI_INIT) += fsl_pci_init.o
-obj-$(CONFIG_PCI) += pci.o  pci_common.o pci_auto.o pci_rom.o
 obj-$(CONFIG_PCI_INDIRECT_BRIDGE) += pci_indirect.o
 obj-$(CONFIG_PCI_GT64120) += pci_gt64120.o
 obj-$(CONFIG_PCI_MSC01) += pci_msc01.o
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
new file mode 100644
index 0000000..d48d865
--- /dev/null
+++ b/drivers/pci/pci-uclass.c
@@ -0,0 +1,639 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <inttypes.h>
+#include <pci.h>
+#include <dm/lists.h>
+#include <dm/root.h>
+#include <dm/device-internal.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct pci_controller *pci_bus_to_hose(int busnum)
+{
+	struct udevice *bus;
+	int ret;
+
+	ret = uclass_get_device_by_seq(UCLASS_PCI, busnum, &bus);
+	if (ret) {
+		debug("%s: Cannot get bus %d: ret=%d\n", __func__, busnum, ret);
+		return NULL;
+	}
+	return dev_get_uclass_priv(bus);
+}
+
+/**
+ * pci_get_bus_max() - returns the bus number of the last active bus
+ *
+ * @return last bus number, or -1 if no active buses
+ */
+static int pci_get_bus_max(void)
+{
+	struct udevice *bus;
+	struct uclass *uc;
+	int ret = -1;
+
+	ret = uclass_get(UCLASS_PCI, &uc);
+	uclass_foreach_dev(bus, uc) {
+		if (bus->seq > ret)
+			ret = bus->seq;
+	}
+
+	debug("%s: ret=%d\n", __func__, ret);
+
+	return ret;
+}
+
+int pci_last_busno(void)
+{
+	struct pci_controller *hose;
+	struct udevice *bus;
+	struct uclass *uc;
+	int ret;
+
+	debug("pci_last_busno\n");
+	ret = uclass_get(UCLASS_PCI, &uc);
+	if (ret || list_empty(&uc->dev_head))
+		return -1;
+
+	/* Probe the last bus */
+	bus = list_entry(uc->dev_head.prev, struct udevice, uclass_node);
+	debug("bus = %p, %s\n", bus, bus->name);
+	assert(bus);
+	ret = device_probe(bus);
+	if (ret)
+		return ret;
+
+	/* If that bus has bridges, we may have new buses now. Get the last */
+	bus = list_entry(uc->dev_head.prev, struct udevice, uclass_node);
+	hose = dev_get_uclass_priv(bus);
+	debug("bus = %s, hose = %p\n", bus->name, hose);
+
+	return hose->last_busno;
+}
+
+int pci_get_ff(enum pci_size_t size)
+{
+	switch (size) {
+	case PCI_SIZE_8:
+		return 0xff;
+	case PCI_SIZE_16:
+		return 0xffff;
+	default:
+		return 0xffffffff;
+	}
+}
+
+int pci_bus_find_devfn(struct udevice *bus, pci_dev_t find_devfn,
+		       struct udevice **devp)
+{
+	struct udevice *dev;
+
+	for (device_find_first_child(bus, &dev);
+	     dev;
+	     device_find_next_child(&dev)) {
+		struct pci_child_platdata *pplat;
+
+		pplat = dev_get_parent_platdata(dev);
+		if (pplat && pplat->devfn == find_devfn) {
+			*devp = dev;
+			return 0;
+		}
+	}
+
+	return -ENODEV;
+}
+
+int pci_bus_find_bdf(pci_dev_t bdf, struct udevice **devp)
+{
+	struct udevice *bus;
+	int ret;
+
+	ret = uclass_get_device_by_seq(UCLASS_PCI, PCI_BUS(bdf), &bus);
+	if (ret)
+		return ret;
+	return pci_bus_find_devfn(bus, PCI_MASK_BUS(bdf), devp);
+}
+
+static int pci_device_matches_ids(struct udevice *dev,
+				  struct pci_device_id *ids)
+{
+	struct pci_child_platdata *pplat;
+	int i;
+
+	pplat = dev_get_parent_platdata(dev);
+	if (!pplat)
+		return -EINVAL;
+	for (i = 0; ids[i].vendor != 0; i++) {
+		if (pplat->vendor == ids[i].vendor &&
+		    pplat->device == ids[i].device)
+			return i;
+	}
+
+	return -EINVAL;
+}
+
+int pci_bus_find_devices(struct udevice *bus, struct pci_device_id *ids,
+			 int *indexp, struct udevice **devp)
+{
+	struct udevice *dev;
+
+	/* Scan all devices on this bus */
+	for (device_find_first_child(bus, &dev);
+	     dev;
+	     device_find_next_child(&dev)) {
+		if (pci_device_matches_ids(dev, ids) >= 0) {
+			if ((*indexp)-- <= 0) {
+				*devp = dev;
+				return 0;
+			}
+		}
+	}
+
+	return -ENODEV;
+}
+
+int pci_find_device_id(struct pci_device_id *ids, int index,
+		       struct udevice **devp)
+{
+	struct udevice *bus;
+
+	/* Scan all known buses */
+	for (uclass_first_device(UCLASS_PCI, &bus);
+	     bus;
+	     uclass_next_device(&bus)) {
+		if (!pci_bus_find_devices(bus, ids, &index, devp))
+			return 0;
+	}
+	*devp = NULL;
+
+	return -ENODEV;
+}
+
+int pci_bus_write_config(struct udevice *bus, pci_dev_t bdf, int offset,
+			 unsigned long value, enum pci_size_t size)
+{
+	struct dm_pci_ops *ops;
+
+	ops = pci_get_ops(bus);
+	if (!ops->write_config)
+		return -ENOSYS;
+	return ops->write_config(bus, bdf, offset, value, size);
+}
+
+int pci_write_config(pci_dev_t bdf, int offset, unsigned long value,
+		     enum pci_size_t size)
+{
+	struct udevice *bus;
+	int ret;
+
+	ret = uclass_get_device_by_seq(UCLASS_PCI, PCI_BUS(bdf), &bus);
+	if (ret)
+		return ret;
+
+	return pci_bus_write_config(bus, PCI_MASK_BUS(bdf), offset, value,
+				    size);
+}
+
+int pci_write_config32(pci_dev_t bdf, int offset, u32 value)
+{
+	return pci_write_config(bdf, offset, value, PCI_SIZE_32);
+}
+
+int pci_write_config16(pci_dev_t bdf, int offset, u16 value)
+{
+	return pci_write_config(bdf, offset, value, PCI_SIZE_16);
+}
+
+int pci_write_config8(pci_dev_t bdf, int offset, u8 value)
+{
+	return pci_write_config(bdf, offset, value, PCI_SIZE_8);
+}
+
+int pci_bus_read_config(struct udevice *bus, pci_dev_t bdf, int offset,
+			unsigned long *valuep, enum pci_size_t size)
+{
+	struct dm_pci_ops *ops;
+
+	ops = pci_get_ops(bus);
+	if (!ops->read_config)
+		return -ENOSYS;
+	return ops->read_config(bus, bdf, offset, valuep, size);
+}
+
+int pci_read_config(pci_dev_t bdf, int offset, unsigned long *valuep,
+		    enum pci_size_t size)
+{
+	struct udevice *bus;
+	int ret;
+
+	ret = uclass_get_device_by_seq(UCLASS_PCI, PCI_BUS(bdf), &bus);
+	if (ret)
+		return ret;
+
+	return pci_bus_read_config(bus, PCI_MASK_BUS(bdf), offset, valuep,
+				   size);
+}
+
+int pci_read_config32(pci_dev_t bdf, int offset, u32 *valuep)
+{
+	unsigned long value;
+	int ret;
+
+	ret = pci_read_config(bdf, offset, &value, PCI_SIZE_32);
+	if (ret)
+		return ret;
+	*valuep = value;
+
+	return 0;
+}
+
+int pci_read_config16(pci_dev_t bdf, int offset, u16 *valuep)
+{
+	unsigned long value;
+	int ret;
+
+	ret = pci_read_config(bdf, offset, &value, PCI_SIZE_16);
+	if (ret)
+		return ret;
+	*valuep = value;
+
+	return 0;
+}
+
+int pci_read_config8(pci_dev_t bdf, int offset, u8 *valuep)
+{
+	unsigned long value;
+	int ret;
+
+	ret = pci_read_config(bdf, offset, &value, PCI_SIZE_8);
+	if (ret)
+		return ret;
+	*valuep = value;
+
+	return 0;
+}
+
+int pci_auto_config_devices(struct udevice *bus)
+{
+	struct pci_controller *hose = bus->uclass_priv;
+	unsigned int sub_bus;
+	struct udevice *dev;
+	int ret;
+
+	sub_bus = bus->seq;
+	debug("%s: start\n", __func__);
+	pciauto_config_init(hose);
+	for (ret = device_find_first_child(bus, &dev);
+	     !ret && dev;
+	     ret = device_find_next_child(&dev)) {
+		struct pci_child_platdata *pplat;
+
+		pplat = dev_get_parent_platdata(dev);
+		unsigned int max_bus;
+		pci_dev_t bdf;
+
+		bdf = PCI_ADD_BUS(bus->seq, pplat->devfn);
+		debug("%s: device %s\n", __func__, dev->name);
+		max_bus = pciauto_config_device(hose, bdf);
+		sub_bus = max(sub_bus, max_bus);
+	}
+	debug("%s: done\n", __func__);
+
+	return sub_bus;
+}
+
+int dm_pci_hose_probe_bus(struct pci_controller *hose, pci_dev_t bdf)
+{
+	struct udevice *parent, *bus;
+	int sub_bus;
+	int ret;
+
+	debug("%s\n", __func__);
+	parent = hose->bus;
+
+	/* Find the bus within the parent */
+	ret = pci_bus_find_devfn(parent, bdf, &bus);
+	if (ret) {
+		debug("%s: Cannot find device %x on bus %s: %d\n", __func__,
+		      bdf, parent->name, ret);
+		return ret;
+	}
+
+	sub_bus = pci_get_bus_max() + 1;
+	debug("%s: bus = %d/%s\n", __func__, sub_bus, bus->name);
+	pciauto_prescan_setup_bridge(hose, bdf, bus->seq);
+
+	ret = device_probe(bus);
+	if (ret) {
+		debug("%s: Cannot probe bus bus %s: %d\n", __func__, bus->name,
+		      ret);
+		return ret;
+	}
+	if (sub_bus != bus->seq) {
+		printf("%s: Internal error, bus '%s' got seq %d, expected %d\n",
+		       __func__, bus->name, bus->seq, sub_bus);
+		return -EPIPE;
+	}
+	sub_bus = pci_get_bus_max();
+	pciauto_postscan_setup_bridge(hose, bdf, sub_bus);
+
+	return sub_bus;
+}
+
+int pci_bind_bus_devices(struct udevice *bus)
+{
+	ulong vendor, device;
+	ulong header_type;
+	pci_dev_t devfn, end;
+	bool found_multi;
+	int ret;
+
+	found_multi = false;
+	end = PCI_DEVFN(PCI_MAX_PCI_DEVICES - 1, PCI_MAX_PCI_FUNCTIONS - 1);
+	for (devfn = PCI_DEVFN(0, 0); devfn < end; devfn += PCI_DEVFN(0, 1)) {
+		struct pci_child_platdata *pplat;
+		struct udevice *dev;
+		ulong class;
+
+		if (PCI_FUNC(devfn) && !found_multi)
+			continue;
+		/* Check only the first access, we don't expect problems */
+		ret = pci_bus_read_config(bus, devfn, PCI_HEADER_TYPE,
+					  &header_type, PCI_SIZE_8);
+		if (ret)
+			goto error;
+		pci_bus_read_config(bus, devfn, PCI_VENDOR_ID, &vendor,
+				    PCI_SIZE_16);
+		if (vendor == 0xffff || vendor == 0x0000)
+			continue;
+
+		if (!PCI_FUNC(devfn))
+			found_multi = header_type & 0x80;
+
+		debug("%s: bus %d/%s: found device %x, function %d\n", __func__,
+		      bus->seq, bus->name, PCI_DEV(devfn), PCI_FUNC(devfn));
+		pci_bus_read_config(bus, devfn, PCI_DEVICE_ID, &device,
+				    PCI_SIZE_16);
+		pci_bus_read_config(bus, devfn, PCI_CLASS_DEVICE, &class,
+				    PCI_SIZE_16);
+
+		/* Find this device in the device tree */
+		ret = pci_bus_find_devfn(bus, devfn, &dev);
+
+		/* If nothing in the device tree, bind a generic device */
+		if (ret == -ENODEV) {
+			char name[30], *str;
+			const char *drv;
+
+			sprintf(name, "pci_%x:%x.%x", bus->seq,
+				PCI_DEV(devfn), PCI_FUNC(devfn));
+			str = strdup(name);
+			if (!str)
+				return -ENOMEM;
+			drv = class == PCI_CLASS_BRIDGE_PCI ?
+				"pci_bridge_drv" : "pci_generic_drv";
+			ret = device_bind_driver(bus, drv, str, &dev);
+		}
+		if (ret)
+			return ret;
+
+		/* Update the platform data */
+		pplat = dev_get_parent_platdata(dev);
+		pplat->devfn = devfn;
+		pplat->vendor = vendor;
+		pplat->device = device;
+		pplat->class = class;
+	}
+
+	return 0;
+error:
+	printf("Cannot read bus configuration: %d\n", ret);
+
+	return ret;
+}
+
+static int pci_uclass_post_bind(struct udevice *bus)
+{
+	/*
+	 * Scan the device tree for devices. This does not probe the PCI bus,
+	 * as this is not permitted while binding. It just finds devices
+	 * mentioned in the device tree.
+	 *
+	 * Before relocation, only bind devices marked for pre-relocation
+	 * use.
+	 */
+	return dm_scan_fdt_node(bus, gd->fdt_blob, bus->of_offset,
+				gd->flags & GD_FLG_RELOC ? false : true);
+}
+
+static int decode_regions(struct pci_controller *hose, const void *blob,
+			  int parent_node, int node)
+{
+	int pci_addr_cells, addr_cells, size_cells;
+	int cells_per_record;
+	const u32 *prop;
+	int len;
+	int i;
+
+	prop = fdt_getprop(blob, node, "ranges", &len);
+	if (!prop)
+		return -EINVAL;
+	pci_addr_cells = fdt_address_cells(blob, node);
+	addr_cells = fdt_address_cells(blob, parent_node);
+	size_cells = fdt_size_cells(blob, node);
+
+	/* PCI addresses are always 3-cells */
+	len /= sizeof(u32);
+	cells_per_record = pci_addr_cells + addr_cells + size_cells;
+	hose->region_count = 0;
+	debug("%s: len=%d, cells_per_record=%d\n", __func__, len,
+	      cells_per_record);
+	for (i = 0; i < MAX_PCI_REGIONS; i++, len -= cells_per_record) {
+		u64 pci_addr, addr, size;
+		int space_code;
+		u32 flags;
+		int type;
+
+		if (len < cells_per_record)
+			break;
+		flags = fdt32_to_cpu(prop[0]);
+		space_code = (flags >> 24) & 3;
+		pci_addr = fdtdec_get_number(prop + 1, 2);
+		prop += pci_addr_cells;
+		addr = fdtdec_get_number(prop, addr_cells);
+		prop += addr_cells;
+		size = fdtdec_get_number(prop, size_cells);
+		prop += size_cells;
+		debug("%s: region %d, pci_addr=%" PRIx64 ", addr=%" PRIx64
+		      ", size=%" PRIx64 ", space_code=%d\n", __func__,
+		      hose->region_count, pci_addr, addr, size, space_code);
+		if (space_code & 2) {
+			type = flags & (1U << 30) ? PCI_REGION_PREFETCH :
+					PCI_REGION_MEM;
+		} else if (space_code & 1) {
+			type = PCI_REGION_IO;
+		} else {
+			continue;
+		}
+		debug(" - type=%d\n", type);
+		pci_set_region(hose->regions + hose->region_count++, pci_addr,
+			       addr, size, type);
+	}
+
+	/* Add a region for our local memory */
+	pci_set_region(hose->regions + hose->region_count++, 0, 0,
+		       gd->ram_size, PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
+
+	return 0;
+}
+
+static int pci_uclass_pre_probe(struct udevice *bus)
+{
+	struct pci_controller *hose;
+	int ret;
+
+	debug("%s, bus=%d/%s, parent=%s\n", __func__, bus->seq, bus->name,
+	      bus->parent->name);
+	hose = bus->uclass_priv;
+
+	/* For bridges, use the top-level PCI controller */
+	if (device_get_uclass_id(bus->parent) == UCLASS_ROOT) {
+		hose->ctlr = bus;
+		ret = decode_regions(hose, gd->fdt_blob, bus->parent->of_offset,
+				bus->of_offset);
+		if (ret) {
+			debug("%s: Cannot decode regions\n", __func__);
+			return ret;
+		}
+	} else {
+		struct pci_controller *parent_hose;
+
+		parent_hose = dev_get_uclass_priv(bus->parent);
+		hose->ctlr = parent_hose->bus;
+	}
+	hose->bus = bus;
+	hose->first_busno = bus->seq;
+	hose->last_busno = bus->seq;
+
+	return 0;
+}
+
+static int pci_uclass_post_probe(struct udevice *bus)
+{
+	int ret;
+
+	/* Don't scan buses before relocation */
+	if (!(gd->flags & GD_FLG_RELOC))
+		return 0;
+
+	debug("%s: probing bus %d\n", __func__, bus->seq);
+	ret = pci_bind_bus_devices(bus);
+	if (ret)
+		return ret;
+
+#ifdef CONFIG_PCI_PNP
+	ret = pci_auto_config_devices(bus);
+#endif
+
+	return ret < 0 ? ret : 0;
+}
+
+static int pci_uclass_child_post_bind(struct udevice *dev)
+{
+	struct pci_child_platdata *pplat;
+	struct fdt_pci_addr addr;
+	int ret;
+
+	if (dev->of_offset == -1)
+		return 0;
+
+	/*
+	 * We could read vendor, device, class if available. But for now we
+	 * just check the address.
+	 */
+	pplat = dev_get_parent_platdata(dev);
+	ret = fdtdec_get_pci_addr(gd->fdt_blob, dev->of_offset,
+				  FDT_PCI_SPACE_CONFIG, "reg", &addr);
+
+	if (ret) {
+		if (ret != -ENOENT)
+			return -EINVAL;
+	} else {
+		/* extract the bdf from fdt_pci_addr */
+		pplat->devfn = addr.phys_hi & 0xffff00;
+	}
+
+	return 0;
+}
+
+int pci_bridge_read_config(struct udevice *bus, pci_dev_t devfn, uint offset,
+			   ulong *valuep, enum pci_size_t size)
+{
+	struct pci_controller *hose = bus->uclass_priv;
+	pci_dev_t bdf = PCI_ADD_BUS(bus->seq, devfn);
+
+	return pci_bus_read_config(hose->ctlr, bdf, offset, valuep, size);
+}
+
+int pci_bridge_write_config(struct udevice *bus, pci_dev_t devfn, uint offset,
+			    ulong value, enum pci_size_t size)
+{
+	struct pci_controller *hose = bus->uclass_priv;
+	pci_dev_t bdf = PCI_ADD_BUS(bus->seq, devfn);
+
+	return pci_bus_write_config(hose->ctlr, bdf, offset, value, size);
+}
+
+UCLASS_DRIVER(pci) = {
+	.id		= UCLASS_PCI,
+	.name		= "pci",
+	.post_bind	= pci_uclass_post_bind,
+	.pre_probe	= pci_uclass_pre_probe,
+	.post_probe	= pci_uclass_post_probe,
+	.child_post_bind = pci_uclass_child_post_bind,
+	.per_device_auto_alloc_size = sizeof(struct pci_controller),
+	.per_child_platdata_auto_alloc_size =
+			sizeof(struct pci_child_platdata),
+};
+
+static const struct dm_pci_ops pci_bridge_ops = {
+	.read_config	= pci_bridge_read_config,
+	.write_config	= pci_bridge_write_config,
+};
+
+static const struct udevice_id pci_bridge_ids[] = {
+	{ .compatible = "pci-bridge" },
+	{ }
+};
+
+U_BOOT_DRIVER(pci_bridge_drv) = {
+	.name		= "pci_bridge_drv",
+	.id		= UCLASS_PCI,
+	.of_match	= pci_bridge_ids,
+	.ops		= &pci_bridge_ops,
+};
+
+UCLASS_DRIVER(pci_generic) = {
+	.id		= UCLASS_PCI_GENERIC,
+	.name		= "pci_generic",
+};
+
+static const struct udevice_id pci_generic_ids[] = {
+	{ .compatible = "pci-generic" },
+	{ }
+};
+
+U_BOOT_DRIVER(pci_generic_drv) = {
+	.name		= "pci_generic_drv",
+	.id		= UCLASS_PCI_GENERIC,
+	.of_match	= pci_generic_ids,
+};
diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c
index 378efbf..e8da977 100644
--- a/drivers/pci/pci_auto.c
+++ b/drivers/pci/pci_auto.c
@@ -432,13 +432,20 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
 
 	switch (class) {
 	case PCI_CLASS_BRIDGE_PCI:
-		hose->current_busno++;
+		DEBUGF("PCI Autoconfig: Found P2P bridge, device %d\n",
+		       PCI_DEV(dev));
+
 		pciauto_setup_device(hose, dev, 2, hose->pci_mem,
 			hose->pci_prefetch, hose->pci_io);
 
-		DEBUGF("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_DEV(dev));
-
+#ifdef CONFIG_DM_PCI
+		n = dm_pci_hose_probe_bus(hose, dev);
+		if (n < 0)
+			return n;
+		sub_bus = (unsigned int)n;
+#else
 		/* Passing in current_busno allows for sibling P2P bridges */
+		hose->current_busno++;
 		pciauto_prescan_setup_bridge(hose, dev, hose->current_busno);
 		/*
 		 * need to figure out if this is a subordinate bridge on the bus
@@ -451,6 +458,7 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
 		pciauto_postscan_setup_bridge(hose, dev, sub_bus);
 
 		sub_bus = hose->current_busno;
+#endif
 		break;
 
 	case PCI_CLASS_STORAGE_IDE:
@@ -475,7 +483,9 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
 		DEBUGF("PCI Autoconfig: Found P2CardBus bridge, device %d\n",
 			PCI_DEV(dev));
 
+#ifndef CONFIG_DM_PCI
 		hose->current_busno++;
+#endif
 		break;
 
 #if defined(CONFIG_PCIAUTO_SKIP_HOST_BRIDGE)
diff --git a/drivers/pci/pci_compat.c b/drivers/pci/pci_compat.c
new file mode 100644
index 0000000..d6938c1
--- /dev/null
+++ b/drivers/pci/pci_compat.c
@@ -0,0 +1,43 @@
+/*
+ * Compatibility functions for pre-driver-model code
+ *
+ * Copyright (C) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#define DEBUG
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <malloc.h>
+#include <pci.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+
+#define PCI_HOSE_OP(rw, name, size, type)				\
+int pci_hose_##rw##_config_##name(struct pci_controller *hose,		\
+				  pci_dev_t dev,			\
+				  int offset, type value)		\
+{									\
+	return pci_##rw##_config##size(dev, offset, value);		\
+}
+
+PCI_HOSE_OP(read, byte, 8, u8 *)
+PCI_HOSE_OP(read, word, 16, u16 *)
+PCI_HOSE_OP(read, dword, 32, u32 *)
+PCI_HOSE_OP(write, byte, 8, u8)
+PCI_HOSE_OP(write, word, 16, u16)
+PCI_HOSE_OP(write, dword, 32, u32)
+
+pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
+{
+	struct pci_child_platdata *pplat;
+	struct udevice *bus, *dev;
+
+	if (pci_find_device_id(ids, index, &dev))
+		return -1;
+	bus = dev->parent;
+	pplat = dev_get_parent_platdata(dev);
+
+	return PCI_ADD_BUS(bus->seq, pplat->devfn);
+}
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 91bb90d..b984407 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -34,6 +34,8 @@ enum uclass_id {
 	UCLASS_I2C_GENERIC,	/* Generic I2C device */
 	UCLASS_I2C_EEPROM,	/* I2C EEPROM device */
 	UCLASS_MOD_EXP,		/* RSA Mod Exp device */
+	UCLASS_PCI,		/* PCI bus */
+	UCLASS_PCI_GENERIC,	/* Generic PCI bus device */
 
 	UCLASS_COUNT,
 	UCLASS_INVALID = -1,
diff --git a/include/pci.h b/include/pci.h
index 4e8826a..07345fd 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -457,12 +457,15 @@ static inline void pci_set_region(struct pci_region *reg,
 
 typedef int pci_dev_t;
 
-#define PCI_BUS(d)	(((d) >> 16) & 0xff)
-#define PCI_DEV(d)	(((d) >> 11) & 0x1f)
-#define PCI_FUNC(d)	(((d) >> 8) & 0x7)
-#define PCI_BDF(b,d,f)	((b) << 16 | (d) << 11 | (f) << 8)
-
-#define PCI_ANY_ID (~0)
+#define PCI_BUS(d)		(((d) >> 16) & 0xff)
+#define PCI_DEV(d)		(((d) >> 11) & 0x1f)
+#define PCI_FUNC(d)		(((d) >> 8) & 0x7)
+#define PCI_DEVFN(d, f)		((d) << 11 | (f) << 8)
+#define PCI_MASK_BUS(bdf)	((bdf) & 0xffff)
+#define PCI_ADD_BUS(bus, devfn)	(((bus) << 16) | (devfn))
+#define PCI_BDF(b, d, f)	((b) << 16 | PCI_DEVFN(d, f))
+#define PCI_VENDEV(v, d)	(((v) << 16) | (d))
+#define PCI_ANY_ID		(~0)
 
 struct pci_device_id {
 	unsigned int vendor, device;		/* Vendor and device ID or PCI_ANY_ID */
@@ -495,7 +498,12 @@ extern void pci_cfgfunc_config_device(struct pci_controller* hose, pci_dev_t dev
  * Structure of a PCI controller (host bridge)
  */
 struct pci_controller {
+#ifdef CONFIG_DM_PCI
+	struct udevice *bus;
+	struct udevice *ctlr;
+#else
 	struct pci_controller *next;
+#endif
 
 	int first_busno;
 	int last_busno;
@@ -511,7 +519,7 @@ struct pci_controller {
 	struct pci_config_table *config_table;
 
 	void (*fixup_irq)(struct pci_controller *, pci_dev_t);
-
+#ifndef CONFIG_DM_PCI
 	/* Low-level architecture-dependent routines */
 	int (*read_byte)(struct pci_controller*, pci_dev_t, int where, u8 *);
 	int (*read_word)(struct pci_controller*, pci_dev_t, int where, u16 *);
@@ -519,17 +527,21 @@ struct pci_controller {
 	int (*write_byte)(struct pci_controller*, pci_dev_t, int where, u8);
 	int (*write_word)(struct pci_controller*, pci_dev_t, int where, u16);
 	int (*write_dword)(struct pci_controller*, pci_dev_t, int where, u32);
+#endif
 
 	/* Used by auto config */
 	struct pci_region *pci_mem, *pci_io, *pci_prefetch;
 
 	/* Used by ppc405 autoconfig*/
 	struct pci_region *pci_fb;
+#ifndef CONFIG_DM_PCI
 	int current_busno;
 
 	void *priv_data;
+#endif
 };
 
+#ifndef CONFIG_DM_PCI
 static inline void pci_set_ops(struct pci_controller *hose,
 				   int (*read_byte)(struct pci_controller*,
 						    pci_dev_t, int where, u8 *),
@@ -550,6 +562,7 @@ static inline void pci_set_ops(struct pci_controller *hose,
 	hose->write_word  = write_word;
 	hose->write_dword = write_dword;
 }
+#endif
 
 #ifdef CONFIG_PCI_INDIRECT_BRIDGE
 extern void pci_setup_indirect(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data);
@@ -602,12 +615,14 @@ extern int pci_hose_write_config_word(struct pci_controller *hose,
 extern int pci_hose_write_config_dword(struct pci_controller *hose,
 				       pci_dev_t dev, int where, u32 val);
 
+#ifndef CONFIG_DM_PCI
 extern int pci_read_config_byte(pci_dev_t dev, int where, u8 *val);
 extern int pci_read_config_word(pci_dev_t dev, int where, u16 *val);
 extern int pci_read_config_dword(pci_dev_t dev, int where, u32 *val);
 extern int pci_write_config_byte(pci_dev_t dev, int where, u8 val);
 extern int pci_write_config_word(pci_dev_t dev, int where, u16 val);
 extern int pci_write_config_dword(pci_dev_t dev, int where, u32 val);
+#endif
 
 extern int pci_hose_read_config_byte_via_dword(struct pci_controller *hose,
 					       pci_dev_t dev, int where, u8 *val);
@@ -719,5 +734,265 @@ int pciauto_setup_rom(struct pci_controller *hose, pci_dev_t dev);
 pci_dev_t pci_hose_find_devices(struct pci_controller *hose, int busnum,
 				struct pci_device_id *ids, int *indexp);
 
+/* Access sizes for PCI reads and writes */
+enum pci_size_t {
+	PCI_SIZE_8,
+	PCI_SIZE_16,
+	PCI_SIZE_32,
+};
+
+struct udevice;
+
+#ifdef CONFIG_DM_PCI
+/**
+ * struct pci_child_platdata - information stored about each PCI device
+ *
+ * Every device on a PCI bus has this per-child data.
+ *
+ * It can be accessed using dev_get_parentdata(dev) if dev->parent is a
+ * PCI bus (i.e. UCLASS_PCI)
+ *
+ * @devfn:	Encoded device and function index - see PCI_DEVFN()
+ * @vendor:	PCI vendor ID (see pci_ids.h)
+ * @device:	PCI device ID (see pci_ids.h)
+ * @class:	PCI class, 3 bytes: (base, sub, prog-if)
+ */
+struct pci_child_platdata {
+	int devfn;
+	unsigned short vendor;
+	unsigned short device;
+	unsigned int class;
+};
+
+/* PCI bus operations */
+struct dm_pci_ops {
+	/**
+	 * read_config() - Read a PCI configuration value
+	 *
+	 * PCI buses must support reading and writing configuration values
+	 * so that the bus can be scanned and its devices configured.
+	 *
+	 * Normally PCI_BUS(@bdf) is the same as @bus->seq, but not always.
+	 * If bridges exist it is possible to use the top-level bus to
+	 * access a sub-bus. In that case @bus will be the top-level bus
+	 * and PCI_BUS(bdf) will be a different (higher) value
+	 *
+	 * @bus:	Bus to read from
+	 * @bdf:	Bus, device and function to read
+	 * @offset:	Byte offset within the device's configuration space
+	 * @valuep:	Place to put the returned value
+	 * @size:	Access size
+	 * @return 0 if OK, -ve on error
+	 */
+	int (*read_config)(struct udevice *bus, pci_dev_t bdf, uint offset,
+			   ulong *valuep, enum pci_size_t size);
+	/**
+	 * write_config() - Write a PCI configuration value
+	 *
+	 * @bus:	Bus to write to
+	 * @bdf:	Bus, device and function to write
+	 * @offset:	Byte offset within the device's configuration space
+	 * @value:	Value to write
+	 * @size:	Access size
+	 * @return 0 if OK, -ve on error
+	 */
+	int (*write_config)(struct udevice *bus, pci_dev_t bdf, uint offset,
+			    ulong value, enum pci_size_t size);
+};
+
+/* Get access to a PCI bus' operations */
+#define pci_get_ops(dev)	((struct dm_pci_ops *)(dev)->driver->ops)
+
+/**
+ * pci_bind_bus_devices() - scan a PCI bus and bind devices
+ *
+ * Scan a PCI bus looking for devices. Bind each one that is found. If
+ * devices are already bound that match the scanned devices, just update the
+ * child data so that the device can be used correctly (this happens when
+ * the device tree describes devices we expect to see on the bus).
+ *
+ * Devices that are bound in this way will use a generic PCI driver which
+ * does nothing. The device can still be accessed but will not provide any
+ * driver interface.
+ *
+ * @bus:	Bus containing devices to bind
+ * @return 0 if OK, -ve on error
+ */
+int pci_bind_bus_devices(struct udevice *bus);
+
+/**
+ * pci_auto_config_devices() - configure bus devices ready for use
+ *
+ * This works through all devices on a bus by scanning the driver model
+ * data structures (normally these have been set up by pci_bind_bus_devices()
+ * earlier).
+ *
+ * Space is allocated for each PCI base address register (BAR) so that the
+ * devices are mapped into memory and I/O space ready for use.
+ *
+ * @bus:	Bus containing devices to bind
+ * @return 0 if OK, -ve on error
+ */
+int pci_auto_config_devices(struct udevice *bus);
+
+/**
+ * pci_bus_find_bdf() - Find a device given its PCI bus address
+ *
+ * @bdf:	PCI device address: bus, device and function -see PCI_BDF()
+ * @devp:	Returns the device for this address, if found
+ * @return 0 if OK, -ENODEV if not found
+ */
+int pci_bus_find_bdf(pci_dev_t bdf, struct udevice **devp);
+
+/**
+ * pci_bus_find_devfn() - Find a device on a bus
+ *
+ * @find_devfn:		PCI device address (device and function only)
+ * @devp:	Returns the device for this address, if found
+ * @return 0 if OK, -ENODEV if not found
+ */
+int pci_bus_find_devfn(struct udevice *bus, pci_dev_t find_devfn,
+		       struct udevice **devp);
+
+/**
+ * pci_get_ff() - Returns a mask for the given access size
+ *
+ * @size:	Access size
+ * @return 0xff for PCI_SIZE_8, 0xffff for PCI_SIZE_16, 0xffffffff for
+ * PCI_SIZE_32
+ */
+int pci_get_ff(enum pci_size_t size);
+
+/**
+ * pci_bus_find_devices () - Find devices on a bus
+ *
+ * @bus:	Bus to search
+ * @ids:	PCI vendor/device IDs to look for, terminated by 0, 0 record
+ * @indexp:	Pointer to device index to find. To find the first matching
+ *		device, pass 0; to find the second, pass 1, etc. This
+ *		parameter is decremented for each non-matching device so
+ *		can be called repeatedly.
+ * @devp:	Returns matching device if found
+ * @return 0 if found, -ENODEV if not
+ */
+int pci_bus_find_devices(struct udevice *bus, struct pci_device_id *ids,
+			 int *indexp, struct udevice **devp);
+
+/**
+ * pci_find_device_id() - Find a device on any bus
+ *
+ * @ids:	PCI vendor/device IDs to look for, terminated by 0, 0 record
+ * @index:	Index number of device to find, 0 for the first match, 1 for
+ *		the second, etc.
+ * @devp:	Returns matching device if found
+ * @return 0 if found, -ENODEV if not
+ */
+int pci_find_device_id(struct pci_device_id *ids, int index,
+		       struct udevice **devp);
+
+/**
+ * dm_pci_hose_probe_bus() - probe a subordinate bus, scanning it for devices
+ *
+ * This probes the given bus which causes it to be scanned for devices. The
+ * devices will be bound but not probed.
+ *
+ * @hose specifies the PCI hose that will be used for the scan. This is
+ * always a top-level bus with uclass UCLASS_PCI. The bus to scan is
+ * in @bdf, and is a subordinate bus reachable from @hose.
+ *
+ * @hose:	PCI hose to scan
+ * @bdf:	PCI bus address to scan (PCI_BUS(bdf) is the bus number)
+ * @return 0 if OK, -ve on error
+ */
+int dm_pci_hose_probe_bus(struct pci_controller *hose, pci_dev_t bdf);
+
+/**
+ * pci_bus_read_config() - Read a configuration value from a device
+ *
+ * TODO(sjg at chromium.org): We should be able to pass just a device and have
+ * it do the right thing. It would be good to have that function also.
+ *
+ * @bus:	Bus to read from
+ * @bdf:	PCI device address: bus, device and function -see PCI_BDF()
+ * @valuep:	Place to put the returned value
+ * @size:	Access size
+ * @return 0 if OK, -ve on error
+ */
+int pci_bus_read_config(struct udevice *bus, pci_dev_t bdf, int offset,
+			unsigned long *valuep, enum pci_size_t size);
+
+/**
+ * pci_bus_write_config() - Write a configuration value to a device
+ *
+ * @bus:	Bus to write from
+ * @bdf:	PCI device address: bus, device and function -see PCI_BDF()
+ * @value:	Value to write
+ * @size:	Access size
+ * @return 0 if OK, -ve on error
+ */
+int pci_bus_write_config(struct udevice *bus, pci_dev_t bdf, int offset,
+			 unsigned long value, enum pci_size_t size);
+
+/*
+ * The following functions provide access to the above without needing the
+ * size parameter. We are trying to encourage the use of the 8/16/32-style
+ * functions, rather than byte/word/dword. But both are supported.
+ */
+int pci_write_config32(pci_dev_t pcidev, int offset, u32 value);
+
+/* Compatibility with old naming */
+static inline int pci_write_config_dword(pci_dev_t pcidev, int offset,
+					 u32 value)
+{
+	return pci_write_config32(pcidev, offset, value);
+}
+
+int pci_write_config16(pci_dev_t pcidev, int offset, u16 value);
+
+/* Compatibility with old naming */
+static inline int pci_write_config_word(pci_dev_t pcidev, int offset,
+					u16 value)
+{
+	return pci_write_config16(pcidev, offset, value);
+}
+
+int pci_write_config8(pci_dev_t pcidev, int offset, u8 value);
+
+/* Compatibility with old naming */
+static inline int pci_write_config_byte(pci_dev_t pcidev, int offset,
+					u8 value)
+{
+	return pci_write_config8(pcidev, offset, value);
+}
+
+int pci_read_config32(pci_dev_t pcidev, int offset, u32 *valuep);
+
+/* Compatibility with old naming */
+static inline int pci_read_config_dword(pci_dev_t pcidev, int offset,
+					u32 *valuep)
+{
+	return pci_read_config32(pcidev, offset, valuep);
+}
+
+int pci_read_config16(pci_dev_t pcidev, int offset, u16 *valuep);
+
+/* Compatibility with old naming */
+static inline int pci_read_config_word(pci_dev_t pcidev, int offset,
+				       u16 *valuep)
+{
+	return pci_read_config16(pcidev, offset, valuep);
+}
+
+int pci_read_config8(pci_dev_t pcidev, int offset, u8 *valuep);
+
+/* Compatibility with old naming */
+static inline int pci_read_config_byte(pci_dev_t pcidev, int offset,
+				       u8 *valuep)
+{
+	return pci_read_config8(pcidev, offset, valuep);
+}
+
+#endif
+
 #endif /* __ASSEMBLY__ */
 #endif /* _PCI_H */
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 14/22] dm: sandbox: pci: Add PCI support for sandbox
  2015-03-05 19:25 [U-Boot] [PATCH v2 0/22] Add driver model support for PCI Simon Glass
                   ` (12 preceding siblings ...)
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 13/22] dm: pci: Add a uclass for PCI Simon Glass
@ 2015-03-05 19:25 ` Simon Glass
  2015-03-20 23:16   ` Simon Glass
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 15/22] dm: sandbox: Add a simple PCI driver Simon Glass
                   ` (8 subsequent siblings)
  22 siblings, 1 reply; 53+ messages in thread
From: Simon Glass @ 2015-03-05 19:25 UTC (permalink / raw)
  To: u-boot

Add the required header information, device tree nodes and I/O accessor
functions to support PCI on sandbox. All devices are emulated by drivers
which can be added as required for testing or development.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 arch/sandbox/Kconfig                      |   7 ++
 arch/sandbox/cpu/cpu.c                    |  37 +++++++-
 arch/sandbox/dts/sandbox.dts              |  20 +++++
 arch/sandbox/include/asm/io.h             |  16 +++-
 arch/sandbox/include/asm/processor.h      |  12 +++
 arch/sandbox/include/asm/test.h           |   7 +-
 arch/sandbox/include/asm/u-boot-sandbox.h |  48 +++++++++++
 arch/sandbox/lib/Makefile                 |   2 +-
 arch/sandbox/lib/pci_io.c                 | 138 ++++++++++++++++++++++++++++++
 9 files changed, 280 insertions(+), 7 deletions(-)
 create mode 100644 arch/sandbox/include/asm/processor.h
 create mode 100644 arch/sandbox/lib/pci_io.c

diff --git a/arch/sandbox/Kconfig b/arch/sandbox/Kconfig
index 2098b9c..477a20a 100644
--- a/arch/sandbox/Kconfig
+++ b/arch/sandbox/Kconfig
@@ -34,4 +34,11 @@ config DM_I2C
 config DM_TEST
 	default y
 
+config PCI
+	bool "PCI support"
+	help
+	  Enable support for PCI (Peripheral Interconnect Bus), a type of bus
+	  used on some devices to allow the CPU to communicate with its
+	  peripherals.
+
 endmenu
diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c
index 1aa397c..1e67a31 100644
--- a/arch/sandbox/cpu/cpu.c
+++ b/arch/sandbox/cpu/cpu.c
@@ -2,7 +2,7 @@
  * Copyright (c) 2011 The Chromium OS Authors.
  * SPDX-License-Identifier:	GPL-2.0+
  */
-
+#define DEBUG
 #include <common.h>
 #include <dm/root.h>
 #include <os.h>
@@ -10,6 +10,13 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+/* Enable access to PCI memory with map_sysmem() */
+static bool enable_pci_map;
+
+/* Last device that was mapped into memory, and length of mapping */
+static struct udevice *map_dev;
+unsigned long map_len;
+
 void reset_cpu(ulong ignored)
 {
 	if (state_uninit())
@@ -59,9 +66,37 @@ int cleanup_before_linux(void)
 
 void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
 {
+#ifdef CONFIG_PCI
+	unsigned long plen = len;
+	void *ptr;
+
+	map_dev = NULL;
+	if (enable_pci_map && !pci_map_physmem(paddr, &len, &map_dev, &ptr)) {
+		if (plen != len) {
+			printf("%s: Warning: partial map at %x, wanted %lx, got %lx\n",
+			       __func__, paddr, len, plen);
+		}
+		map_len = len;
+		return ptr;
+	}
+#endif
+
 	return (void *)(gd->arch.ram_buf + paddr);
 }
 
+void unmap_physmem(const void *vaddr, unsigned long flags)
+{
+	if (map_dev) {
+		pci_unmap_physmem(vaddr, map_len, map_dev);
+		map_dev = NULL;
+	}
+}
+
+void sandbox_set_enable_pci_map(int enable)
+{
+	enable_pci_map = enable;
+}
+
 phys_addr_t map_to_sysmem(const void *ptr)
 {
 	return (u8 *)ptr - gd->arch.ram_buf;
diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts
index d090ba8..42a1f21 100644
--- a/arch/sandbox/dts/sandbox.dts
+++ b/arch/sandbox/dts/sandbox.dts
@@ -4,6 +4,10 @@
 	#address-cells = <1>;
 	#size-cells = <1>;
 
+	aliases {
+		pci0 = &pci;
+	};
+
 	chosen {
 		stdout-path = "/serial";
 	};
@@ -181,4 +185,20 @@
 		};
 	};
 
+	pci: pci-controller {
+		compatible = "sandbox,pci";
+		device_type = "pci";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		ranges = <0x02000000 0 0x10000000 0x10000000 0 0x2000
+				0x01000000 0 0x20000000 0x20000000 0 0x2000>;
+		pci at 1f,0 {
+			compatible = "pci-generic";
+			reg = <0xf800 0 0 0 0>;
+			emul at 1f,0 {
+				compatible = "sandbox,swap-case";
+			};
+		};
+	};
+
 };
diff --git a/arch/sandbox/include/asm/io.h b/arch/sandbox/include/asm/io.h
index 895fcb8..5b87fde 100644
--- a/arch/sandbox/include/asm/io.h
+++ b/arch/sandbox/include/asm/io.h
@@ -22,10 +22,7 @@ void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags);
 /*
  * Take down a mapping set up by map_physmem().
  */
-static inline void unmap_physmem(void *vaddr, unsigned long flags)
-{
-
-}
+void unmap_physmem(const void *vaddr, unsigned long flags);
 
 /* For sandbox, we want addresses to point into our RAM buffer */
 static inline void *map_sysmem(phys_addr_t paddr, unsigned long len)
@@ -33,8 +30,10 @@ static inline void *map_sysmem(phys_addr_t paddr, unsigned long len)
 	return map_physmem(paddr, len, MAP_WRBACK);
 }
 
+/* Remove a previous mapping */
 static inline void unmap_sysmem(const void *vaddr)
 {
+	unmap_physmem(vaddr, MAP_WRBACK);
 }
 
 /* Map from a pointer to our RAM buffer */
@@ -48,6 +47,15 @@ phys_addr_t map_to_sysmem(const void *ptr);
 #define writew(v, addr)
 #define writel(v, addr)
 
+/* I/O access functions */
+int inl(unsigned int addr);
+int inw(unsigned int addr);
+int inb(unsigned int addr);
+
+void outl(unsigned int value, unsigned int addr);
+void outw(unsigned int value, unsigned int addr);
+void outb(unsigned int value, unsigned int addr);
+
 #include <iotrace.h>
 
 #endif
diff --git a/arch/sandbox/include/asm/processor.h b/arch/sandbox/include/asm/processor.h
new file mode 100644
index 0000000..3c1794e
--- /dev/null
+++ b/arch/sandbox/include/asm/processor.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _ASM_PROCESSOR_H
+#define _ASM_PROCESSOR_H
+
+/* This file is required for PCI */
+
+#endif
diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h
index 25a0c85..8e490e9 100644
--- a/arch/sandbox/include/asm/test.h
+++ b/arch/sandbox/include/asm/test.h
@@ -10,7 +10,12 @@
 #define __ASM_TEST_H
 
 /* The sandbox driver always permits an I2C device with this address */
-#define SANDBOX_I2C_TEST_ADDR	0x59
+#define SANDBOX_I2C_TEST_ADDR		0x59
+
+#define SANDBOX_PCI_VENDOR_ID		0x1234
+#define SANDBOX_PCI_DEVICE_ID		0x5678
+#define SANDBOX_PCI_CLASS_CODE		PCI_CLASS_CODE_COMM
+#define SANDBOX_PCI_CLASS_SUB_CODE	PCI_CLASS_SUB_CODE_COMM_SERIAL
 
 enum sandbox_i2c_eeprom_test_mode {
 	SIE_TEST_MODE_NONE,
diff --git a/arch/sandbox/include/asm/u-boot-sandbox.h b/arch/sandbox/include/asm/u-boot-sandbox.h
index 770ab5c..d5b9361 100644
--- a/arch/sandbox/include/asm/u-boot-sandbox.h
+++ b/arch/sandbox/include/asm/u-boot-sandbox.h
@@ -27,4 +27,52 @@ int cleanup_before_linux(void);
 /* drivers/video/sandbox_sdl.c */
 int sandbox_lcd_sdl_early_init(void);
 
+/**
+ * pci_map_physmem() - map a PCI device into memory
+ *
+ * This is used on sandbox to map a device into memory so that it can be
+ * used with normal memory access. After this call, some part of the device's
+ * internal structure becomes visible.
+ *
+ * This function is normally called from sandbox's map_sysmem() automatically.
+ *
+ * @paddr:	Physical memory address, normally corresponding to a PCI BAR
+ * @lenp:	On entry, the size of the area to map, On exit it is updated
+ *		to the size actually mapped, which may be less if the device
+ *		has less space
+ * @devp:	Returns the device which mapped into this space
+ * @ptrp:	Returns a pointer to the mapped address. The device's space
+ *		can be accessed as @lenp bytes starting here
+ * @return 0 if OK, -ve on error
+ */
+int pci_map_physmem(phys_addr_t paddr, unsigned long *lenp,
+		    struct udevice **devp, void **ptrp);
+
+/**
+ * pci_unmap_physmem() - undo a memory mapping
+ *
+ * This must be called after pci_map_physmem() to undo the mapping.
+ *
+ * @paddr:	Physical memory address, as passed to pci_map_physmem()
+ * @len:	Size of area mapped, as returned by pci_map_physmem()
+ * @dev:	Device to unmap, as returned by pci_map_physmem()
+ * @return 0 if OK, -ve on error
+ */
+int pci_unmap_physmem(const void *addr, unsigned long len,
+		      struct udevice *dev);
+
+/**
+ * sandbox_set_enable_pci_map() - Enable / disable PCI address mapping
+ *
+ * Since address mapping involves calling every driver, provide a way to
+ * enable and disable this. It can be handled automatically by the emulator
+ * uclass, which knows if any emulators are currently active.
+ *
+ * If this is disabled, pci_map_physmem() will not be called from
+ * map_sysmem().
+ *
+ * @enable: 0 to disable, 1 to enable
+ */
+void sandbox_set_enable_pci_map(int enable);
+
 #endif	/* _U_BOOT_SANDBOX_H_ */
diff --git a/arch/sandbox/lib/Makefile b/arch/sandbox/lib/Makefile
index 4c1a38d..75b135c 100644
--- a/arch/sandbox/lib/Makefile
+++ b/arch/sandbox/lib/Makefile
@@ -7,5 +7,5 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
-
 obj-y	+= interrupts.o
+obj-$(CONFIG_PCI)	+= pci_io.o
diff --git a/arch/sandbox/lib/pci_io.c b/arch/sandbox/lib/pci_io.c
new file mode 100644
index 0000000..0de124f
--- /dev/null
+++ b/arch/sandbox/lib/pci_io.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+/*
+ * IO space access commands.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <dm.h>
+#include <asm/io.h>
+
+int pci_map_physmem(phys_addr_t paddr, unsigned long *lenp,
+		    struct udevice **devp, void **ptrp)
+{
+	struct udevice *dev;
+	int ret;
+
+	*ptrp = 0;
+	for (uclass_first_device(UCLASS_PCI_EMUL, &dev);
+	     dev;
+	     uclass_next_device(&dev)) {
+		struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
+
+		if (!ops || !ops->map_physmem)
+			continue;
+		ret = (ops->map_physmem)(dev, paddr, lenp, ptrp);
+		if (ret)
+			continue;
+		*devp = dev;
+		return 0;
+	}
+
+	debug("%s: failed: addr=%x\n", __func__, paddr);
+	return -ENOSYS;
+}
+
+int pci_unmap_physmem(const void *vaddr, unsigned long len,
+		      struct udevice *dev)
+{
+	struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
+
+	if (!ops || !ops->unmap_physmem)
+		return -ENOSYS;
+	return (ops->unmap_physmem)(dev, vaddr, len);
+}
+
+static int pci_io_read(unsigned int addr, ulong *valuep, pci_size_t size)
+{
+	struct udevice *dev;
+	int ret;
+
+	*valuep = pci_get_ff(size);
+	for (uclass_first_device(UCLASS_PCI_EMUL, &dev);
+	     dev;
+	     uclass_next_device(&dev)) {
+		struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
+
+		if (ops && ops->read_io) {
+			ret = (ops->read_io)(dev, addr, valuep, size);
+			if (!ret)
+				return 0;
+		}
+	}
+
+	debug("%s: failed: addr=%x\n", __func__, addr);
+	return -ENOSYS;
+}
+
+static int pci_io_write(unsigned int addr, ulong value, pci_size_t size)
+{
+	struct udevice *dev;
+	int ret;
+
+	for (uclass_first_device(UCLASS_PCI_EMUL, &dev);
+	     dev;
+	     uclass_next_device(&dev)) {
+		struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
+
+		if (ops && ops->write_io) {
+			ret = (ops->write_io)(dev, addr, value, size);
+			if (!ret)
+				return 0;
+		}
+	}
+
+	debug("%s: failed: addr=%x, value=%lx\n", __func__, addr, value);
+	return -ENOSYS;
+}
+
+int inl(unsigned int addr)
+{
+	unsigned long value;
+	int ret;
+
+	ret = pci_io_read(addr, &value, PCI_SIZE_32);
+
+	return ret ? 0 : value;
+}
+
+int inw(unsigned int addr)
+{
+	unsigned long value;
+	int ret;
+
+	ret = pci_io_read(addr, &value, PCI_SIZE_16);
+
+	return ret ? 0 : value;
+}
+
+int inb(unsigned int addr)
+{
+	unsigned long value;
+	int ret;
+
+	ret = pci_io_read(addr, &value, PCI_SIZE_8);
+
+	return ret ? 0 : value;
+}
+
+void outl(unsigned int value, unsigned int addr)
+{
+	pci_io_write(addr, value, PCI_SIZE_32);
+}
+
+void outw(unsigned int value, unsigned int addr)
+{
+	pci_io_write(addr, value, PCI_SIZE_16);
+}
+
+void outb(unsigned int value, unsigned int addr)
+{
+	pci_io_write(addr, value, PCI_SIZE_8);
+}
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 15/22] dm: sandbox: Add a simple PCI driver
  2015-03-05 19:25 [U-Boot] [PATCH v2 0/22] Add driver model support for PCI Simon Glass
                   ` (13 preceding siblings ...)
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 14/22] dm: sandbox: pci: Add PCI support for sandbox Simon Glass
@ 2015-03-05 19:25 ` Simon Glass
  2015-03-20 23:16   ` Simon Glass
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 16/22] dm: sandbox: pci: Add a PCI emulation uclass Simon Glass
                   ` (7 subsequent siblings)
  22 siblings, 1 reply; 53+ messages in thread
From: Simon Glass @ 2015-03-05 19:25 UTC (permalink / raw)
  To: u-boot

Add a driver which can access emulations of devices and make them available
in sandbox.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/pci/Kconfig       | 10 ++++++
 drivers/pci/Makefile      |  1 +
 drivers/pci/pci_sandbox.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 90 insertions(+)
 create mode 100644 drivers/pci/pci_sandbox.c

diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 8b7e2ee..167d405 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -9,4 +9,14 @@ config DM_PCI
 	  available PCI devices, allows scanning of PCI buses and provides
 	  device configuration support.
 
+config PCI_SANDBOX
+	bool "Sandbox PCI support"
+	depends on SANDBOX && DM_PCI
+	help
+	  Support PCI on sandbox, as an emulated bus. This permits testing of
+	  PCI feature such as bus scanning, device configuration and device
+	  access. The available (emulated) devices are defined statically in
+	  the device tree but the normal PCI scan technique is used to find
+	  then.
+
 endmenu
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index db82786..9e2e5f9 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -7,6 +7,7 @@
 
 ifneq ($(CONFIG_DM_PCI),)
 obj-$(CONFIG_PCI) += pci-uclass.o pci_compat.o
+obj-$(CONFIG_PCI_SANDBOX) += pci_sandbox.o
 else
 obj-$(CONFIG_PCI) += pci.o
 endif
diff --git a/drivers/pci/pci_sandbox.c b/drivers/pci/pci_sandbox.c
new file mode 100644
index 0000000..6de5130
--- /dev/null
+++ b/drivers/pci/pci_sandbox.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <inttypes.h>
+#include <pci.h>
+#include <dm/root.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int sandbox_pci_write_config(struct udevice *bus, pci_dev_t devfn,
+				    uint offset, ulong value,
+				    enum pci_size_t size)
+{
+	struct dm_pci_emul_ops *ops;
+	struct udevice *emul;
+	int ret;
+
+	ret = sandbox_pci_get_emul(bus, devfn, &emul);
+	if (ret)
+		return ret == -ENODEV ? 0 : ret;
+	ops = pci_get_emul_ops(emul);
+	if (!ops || !ops->write_config)
+		return -ENOSYS;
+
+	return ops->write_config(emul, offset, value, size);
+}
+
+static int sandbox_pci_read_config(struct udevice *bus, pci_dev_t devfn,
+				   uint offset, ulong *valuep,
+				   enum pci_size_t size)
+{
+	struct dm_pci_emul_ops *ops;
+	struct udevice *emul;
+	int ret;
+
+	/* Prepare the default response */
+	*valuep = pci_get_ff(size);
+	ret = sandbox_pci_get_emul(bus, devfn, &emul);
+	if (ret)
+		return ret == -ENODEV ? 0 : ret;
+	ops = pci_get_emul_ops(emul);
+	if (!ops || !ops->read_config)
+		return -ENOSYS;
+
+	return ops->read_config(emul, offset, valuep, size);
+}
+
+static int sandbox_pci_child_post_bind(struct udevice *dev)
+{
+	/* Attach an emulator if we can */
+	return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
+}
+
+static const struct dm_pci_ops sandbox_pci_ops = {
+	.read_config = sandbox_pci_read_config,
+	.write_config = sandbox_pci_write_config,
+};
+
+static const struct udevice_id sandbox_pci_ids[] = {
+	{ .compatible = "sandbox,pci" },
+	{ }
+};
+
+U_BOOT_DRIVER(pci_sandbox) = {
+	.name	= "pci_sandbox",
+	.id	= UCLASS_PCI,
+	.of_match = sandbox_pci_ids,
+	.ops	= &sandbox_pci_ops,
+	.child_post_bind = sandbox_pci_child_post_bind,
+	.per_child_platdata_auto_alloc_size =
+			sizeof(struct pci_child_platdata),
+};
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 16/22] dm: sandbox: pci: Add a PCI emulation uclass
  2015-03-05 19:25 [U-Boot] [PATCH v2 0/22] Add driver model support for PCI Simon Glass
                   ` (14 preceding siblings ...)
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 15/22] dm: sandbox: Add a simple PCI driver Simon Glass
@ 2015-03-05 19:25 ` Simon Glass
  2015-03-20 23:16   ` Simon Glass
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 17/22] dm: sandbox: Add a emulated PCI device as an example Simon Glass
                   ` (6 subsequent siblings)
  22 siblings, 1 reply; 53+ messages in thread
From: Simon Glass @ 2015-03-05 19:25 UTC (permalink / raw)
  To: u-boot

Since sandbox does not have real devices (unless it borrows those from the
host) it must use emulations. Provide a uclass which permits PCI operations
to be passed through to an emulation device.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/pci/Makefile          |   1 +
 drivers/pci/pci-emul-uclass.c |  67 ++++++++++++++++++++++++++
 include/dm/uclass-id.h        |   1 +
 include/pci.h                 | 108 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 177 insertions(+)
 create mode 100644 drivers/pci/pci-emul-uclass.c

diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 9e2e5f9..c1c2ae3 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -8,6 +8,7 @@
 ifneq ($(CONFIG_DM_PCI),)
 obj-$(CONFIG_PCI) += pci-uclass.o pci_compat.o
 obj-$(CONFIG_PCI_SANDBOX) += pci_sandbox.o
+obj-$(CONFIG_SANDBOX) += pci-emul-uclass.o
 else
 obj-$(CONFIG_PCI) += pci.o
 endif
diff --git a/drivers/pci/pci-emul-uclass.c b/drivers/pci/pci-emul-uclass.c
new file mode 100644
index 0000000..0f8e3c9
--- /dev/null
+++ b/drivers/pci/pci-emul-uclass.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <libfdt.h>
+#include <pci.h>
+#include <dm/lists.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct sandbox_pci_priv {
+	int dev_count;
+};
+
+int sandbox_pci_get_emul(struct udevice *bus, pci_dev_t find_devfn,
+			 struct udevice **emulp)
+{
+	struct udevice *dev;
+	int ret;
+
+	ret = pci_bus_find_devfn(bus, find_devfn, &dev);
+	if (ret) {
+		debug("%s: Could not find emulator for dev %x\n", __func__,
+		      find_devfn);
+		return ret;
+	}
+
+	ret = device_find_first_child(dev, emulp);
+	if (ret)
+		return ret;
+
+	return *emulp ? 0 : -ENODEV;
+}
+
+static int sandbox_pci_emul_post_probe(struct udevice *dev)
+{
+	struct sandbox_pci_priv *priv = dev->uclass->priv;
+
+	priv->dev_count++;
+	sandbox_set_enable_pci_map(true);
+
+	return 0;
+}
+
+static int sandbox_pci_emul_pre_remove(struct udevice *dev)
+{
+	struct sandbox_pci_priv *priv = dev->uclass->priv;
+
+	priv->dev_count--;
+	sandbox_set_enable_pci_map(priv->dev_count > 0);
+
+	return 0;
+}
+
+UCLASS_DRIVER(pci_emul) = {
+	.id		= UCLASS_PCI_EMUL,
+	.name		= "pci_emul",
+	.post_probe	= sandbox_pci_emul_post_probe,
+	.pre_remove	= sandbox_pci_emul_pre_remove,
+	.priv_auto_alloc_size	= sizeof(struct sandbox_pci_priv),
+};
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index b984407..0b6e850 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -20,6 +20,7 @@ enum uclass_id {
 	UCLASS_TEST_BUS,
 	UCLASS_SPI_EMUL,	/* sandbox SPI device emulator */
 	UCLASS_I2C_EMUL,	/* sandbox I2C device emulator */
+	UCLASS_PCI_EMUL,	/* sandbox PCI device emulator */
 	UCLASS_SIMPLE_BUS,
 
 	/* U-Boot uclasses start here */
diff --git a/include/pci.h b/include/pci.h
index 07345fd..07b1e9a 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -992,6 +992,114 @@ static inline int pci_read_config_byte(pci_dev_t pcidev, int offset,
 	return pci_read_config8(pcidev, offset, valuep);
 }
 
+/**
+ * struct dm_pci_emul_ops - PCI device emulator operations
+ */
+struct dm_pci_emul_ops {
+	/**
+	 * get_devfn(): Check which device and function this emulators
+	 *
+	 * @dev:	device to check
+	 * @return the device and function this emulates, or -ve on error
+	 */
+	int (*get_devfn)(struct udevice *dev);
+	/**
+	 * read_config() - Read a PCI configuration value
+	 *
+	 * @dev:	Emulated device to read from
+	 * @offset:	Byte offset within the device's configuration space
+	 * @valuep:	Place to put the returned value
+	 * @size:	Access size
+	 * @return 0 if OK, -ve on error
+	 */
+	int (*read_config)(struct udevice *dev, uint offset, ulong *valuep,
+			   enum pci_size_t size);
+	/**
+	 * write_config() - Write a PCI configuration value
+	 *
+	 * @dev:	Emulated device to write to
+	 * @offset:	Byte offset within the device's configuration space
+	 * @value:	Value to write
+	 * @size:	Access size
+	 * @return 0 if OK, -ve on error
+	 */
+	int (*write_config)(struct udevice *dev, uint offset, ulong value,
+			    enum pci_size_t size);
+	/**
+	 * read_io() - Read a PCI I/O value
+	 *
+	 * @dev:	Emulated device to read from
+	 * @addr:	I/O address to read
+	 * @valuep:	Place to put the returned value
+	 * @size:	Access size
+	 * @return 0 if OK, -ENOENT if @addr is not mapped by this device,
+	 *		other -ve value on error
+	 */
+	int (*read_io)(struct udevice *dev, unsigned int addr, ulong *valuep,
+		       enum pci_size_t size);
+	/**
+	 * write_io() - Write a PCI I/O value
+	 *
+	 * @dev:	Emulated device to write from
+	 * @addr:	I/O address to write
+	 * @value:	Value to write
+	 * @size:	Access size
+	 * @return 0 if OK, -ENOENT if @addr is not mapped by this device,
+	 *		other -ve value on error
+	 */
+	int (*write_io)(struct udevice *dev, unsigned int addr,
+			ulong value, enum pci_size_t size);
+	/**
+	 * map_physmem() - Map a device into sandbox memory
+	 *
+	 * @dev:	Emulated device to map
+	 * @addr:	Memory address, normally corresponding to a PCI BAR.
+	 *		The device should have been configured to have a BAR
+	 *		at this address.
+	 * @lenp:	On entry, the size of the area to map, On exit it is
+	 *		updated to the size actually mapped, which may be less
+	 *		if the device has less space
+	 * @ptrp:	Returns a pointer to the mapped address. The device's
+	 *		space can be accessed as @lenp bytes starting here
+	 * @return 0 if OK, -ENOENT if @addr is not mapped by this device,
+	 *		other -ve value on error
+	 */
+	int (*map_physmem)(struct udevice *dev, phys_addr_t addr,
+			   unsigned long *lenp, void **ptrp);
+	/**
+	 * unmap_physmem() - undo a memory mapping
+	 *
+	 * This must be called after map_physmem() to undo the mapping.
+	 * Some devices can use this to check what has been written into
+	 * their mapped memory and perform an operations they require on it.
+	 * In this way, map/unmap can be used as a sort of handshake between
+	 * the emulated device and its users.
+	 *
+	 * @dev:	Emuated device to unmap
+	 * @vaddr:	Mapped memory address, as passed to map_physmem()
+	 * @len:	Size of area mapped, as returned by map_physmem()
+	 * @return 0 if OK, -ve on error
+	 */
+	int (*unmap_physmem)(struct udevice *dev, const void *vaddr,
+			     unsigned long len);
+};
+
+/* Get access to a PCI device emulator's operations */
+#define pci_get_emul_ops(dev)	((struct dm_pci_emul_ops *)(dev)->driver->ops)
+
+/**
+ * sandbox_pci_get_emul() - Get the emulation device for a PCI device
+ *
+ * Searches for a suitable emulator for the given PCI bus device
+ *
+ * @bus:	PCI bus to search
+ * @find_devfn:	PCI device and function address (PCI_DEVFN())
+ * @emulp:	Returns emulated device if found
+ * @return 0 if found, -ENODEV if not found
+ */
+int sandbox_pci_get_emul(struct udevice *bus, pci_dev_t find_devfn,
+			 struct udevice **emulp);
+
 #endif
 
 #endif /* __ASSEMBLY__ */
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 17/22] dm: sandbox: Add a emulated PCI device as an example
  2015-03-05 19:25 [U-Boot] [PATCH v2 0/22] Add driver model support for PCI Simon Glass
                   ` (15 preceding siblings ...)
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 16/22] dm: sandbox: pci: Add a PCI emulation uclass Simon Glass
@ 2015-03-05 19:25 ` Simon Glass
  2015-03-20 23:16   ` Simon Glass
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 18/22] dm: sandbox: pci: Enable PCI for sandbox Simon Glass
                   ` (5 subsequent siblings)
  22 siblings, 1 reply; 53+ messages in thread
From: Simon Glass @ 2015-03-05 19:25 UTC (permalink / raw)
  To: u-boot

This device sits on the sandbox PCI bus and provides a case-swapping
service for sandbox. It illustrates the use of both PCI I/O and PCI
memory accesses.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 drivers/misc/Makefile    |   1 +
 drivers/misc/swap_case.c | 285 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 286 insertions(+)
 create mode 100644 drivers/misc/swap_case.c

diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index a34972d..7783b72 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -26,5 +26,6 @@ obj-$(CONFIG_SANDBOX) += i2c_eeprom_emul.o
 endif
 obj-$(CONFIG_SMSC_LPC47M) += smsc_lpc47m.o
 obj-$(CONFIG_STATUS_LED) += status_led.o
+obj-$(CONFIG_SANDBOX) += swap_case.o
 obj-$(CONFIG_TWL4030_LED) += twl4030_led.o
 obj-$(CONFIG_FSL_IFC) += fsl_ifc.o
diff --git a/drivers/misc/swap_case.c b/drivers/misc/swap_case.c
new file mode 100644
index 0000000..f6028ba
--- /dev/null
+++ b/drivers/misc/swap_case.c
@@ -0,0 +1,285 @@
+/*
+ * PCI emulation device which swaps the case of text
+ *
+ * Copyright (c) 2014 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <pci.h>
+#include <asm/test.h>
+#include <linux/ctype.h>
+
+/**
+ * struct swap_case_platdata - platform data for this device
+ *
+ * @command:	Current PCI command value
+ * @bar:	Current base address values
+ */
+struct swap_case_platdata {
+	u16 command;
+	u32 bar[2];
+};
+
+#define offset_to_barnum(offset)	\
+		(((offset) - PCI_BASE_ADDRESS_0) / sizeof(u32))
+
+enum {
+	MEM_TEXT_SIZE	= 0x100,
+};
+
+enum swap_case_op {
+	OP_TO_LOWER,
+	OP_TO_UPPER,
+	OP_SWAP,
+};
+
+static struct pci_bar {
+	int type;
+	u32 size;
+} barinfo[] = {
+	{ PCI_BASE_ADDRESS_SPACE_IO, 1 },
+	{ PCI_BASE_ADDRESS_MEM_TYPE_32, MEM_TEXT_SIZE },
+	{ 0, 0 },
+	{ 0, 0 },
+	{ 0, 0 },
+	{ 0, 0 },
+};
+
+struct swap_case_priv {
+	enum swap_case_op op;
+	char mem_text[MEM_TEXT_SIZE];
+};
+
+static int sandbox_swap_case_get_devfn(struct udevice *dev)
+{
+	struct pci_child_platdata *plat = dev_get_parent_platdata(dev);
+
+	return plat->devfn;
+}
+
+static int sandbox_swap_case_read_config(struct udevice *emul, uint offset,
+					 ulong *valuep, enum pci_size_t size)
+{
+	struct swap_case_platdata *plat = dev_get_platdata(emul);
+
+	switch (offset) {
+	case PCI_COMMAND:
+		*valuep = plat->command;
+		break;
+	case PCI_HEADER_TYPE:
+		*valuep = 0;
+		break;
+	case PCI_VENDOR_ID:
+		*valuep = SANDBOX_PCI_VENDOR_ID;
+		break;
+	case PCI_DEVICE_ID:
+		*valuep = SANDBOX_PCI_DEVICE_ID;
+		break;
+	case PCI_CLASS_DEVICE:
+		if (size == PCI_SIZE_8) {
+			*valuep = SANDBOX_PCI_CLASS_SUB_CODE;
+		} else {
+			*valuep = (SANDBOX_PCI_CLASS_CODE << 8) |
+					SANDBOX_PCI_CLASS_SUB_CODE;
+		}
+		break;
+	case PCI_CLASS_CODE:
+		*valuep = SANDBOX_PCI_CLASS_CODE;
+		break;
+	case PCI_BASE_ADDRESS_0:
+	case PCI_BASE_ADDRESS_1:
+	case PCI_BASE_ADDRESS_2:
+	case PCI_BASE_ADDRESS_3:
+	case PCI_BASE_ADDRESS_4:
+	case PCI_BASE_ADDRESS_5: {
+		int barnum;
+		u32 *bar, result;
+
+		barnum = offset_to_barnum(offset);
+		bar = &plat->bar[barnum];
+
+		result = *bar;
+		if (*bar == 0xffffffff) {
+			if (barinfo[barnum].type) {
+				result = (~(barinfo[barnum].size - 1) &
+					PCI_BASE_ADDRESS_IO_MASK) |
+					PCI_BASE_ADDRESS_SPACE_IO;
+			} else {
+				result = (~(barinfo[barnum].size - 1) &
+					PCI_BASE_ADDRESS_MEM_MASK) |
+					PCI_BASE_ADDRESS_MEM_TYPE_32;
+			}
+		}
+		debug("r bar %d=%x\n", barnum, result);
+		*valuep = result;
+		break;
+	}
+	}
+
+	return 0;
+}
+
+static int sandbox_swap_case_write_config(struct udevice *emul, uint offset,
+					  ulong value, enum pci_size_t size)
+{
+	struct swap_case_platdata *plat = dev_get_platdata(emul);
+
+	switch (offset) {
+	case PCI_COMMAND:
+		plat->command = value;
+		break;
+	case PCI_BASE_ADDRESS_0:
+	case PCI_BASE_ADDRESS_1: {
+		int barnum;
+		u32 *bar;
+
+		barnum = offset_to_barnum(offset);
+		bar = &plat->bar[barnum];
+
+		debug("w bar %d=%lx\n", barnum, value);
+		*bar = value;
+		break;
+	}
+	}
+
+	return 0;
+}
+
+static int sandbox_swap_case_find_bar(struct udevice *emul, unsigned int addr,
+				      int *barnump, unsigned int *offsetp)
+{
+	struct swap_case_platdata *plat = dev_get_platdata(emul);
+	int barnum;
+
+	for (barnum = 0; barnum < ARRAY_SIZE(barinfo); barnum++) {
+		unsigned int size = barinfo[barnum].size;
+
+		if (addr >= plat->bar[barnum] &&
+		    addr < plat->bar[barnum] + size) {
+			*barnump = barnum;
+			*offsetp = addr - plat->bar[barnum];
+			return 0;
+		}
+	}
+	*barnump = -1;
+
+	return -ENOENT;
+}
+
+static void sandbox_swap_case_do_op(enum swap_case_op op, char *str, int len)
+{
+	for (; len > 0; len--, str++) {
+		switch (op) {
+		case OP_TO_UPPER:
+			*str = toupper(*str);
+			break;
+		case OP_TO_LOWER:
+			*str = tolower(*str);
+			break;
+		case OP_SWAP:
+			if (isupper(*str))
+				*str = tolower(*str);
+			else
+				*str = toupper(*str);
+			break;
+		}
+	}
+}
+
+int sandbox_swap_case_read_io(struct udevice *dev, unsigned int addr,
+			      ulong *valuep, enum pci_size_t size)
+{
+	struct swap_case_priv *priv = dev_get_priv(dev);
+	unsigned int offset;
+	int barnum;
+	int ret;
+
+	ret = sandbox_swap_case_find_bar(dev, addr, &barnum, &offset);
+	if (ret)
+		return ret;
+
+	if (barnum == 0 && offset == 0)
+		*valuep = (*valuep & ~0xff) | priv->op;
+
+	return 0;
+}
+
+int sandbox_swap_case_write_io(struct udevice *dev, unsigned int addr,
+			       ulong value, enum pci_size_t size)
+{
+	struct swap_case_priv *priv = dev_get_priv(dev);
+	unsigned int offset;
+	int barnum;
+	int ret;
+
+	ret = sandbox_swap_case_find_bar(dev, addr, &barnum, &offset);
+	if (ret)
+		return ret;
+	if (barnum == 0 && offset == 0)
+		priv->op = value;
+
+	return 0;
+}
+
+static int sandbox_swap_case_map_physmem(struct udevice *dev,
+		phys_addr_t addr, unsigned long *lenp, void **ptrp)
+{
+	struct swap_case_priv *priv = dev_get_priv(dev);
+	unsigned int offset, avail;
+	int barnum;
+	int ret;
+
+	ret = sandbox_swap_case_find_bar(dev, addr, &barnum, &offset);
+	if (ret)
+		return ret;
+	if (barnum == 1) {
+		*ptrp = priv->mem_text + offset;
+		avail = barinfo[1].size - offset;
+		if (avail > barinfo[1].size)
+			*lenp = 0;
+		else
+			*lenp = min(*lenp, (ulong)avail);
+
+		return 0;
+	}
+
+	return -ENOENT;
+}
+
+static int sandbox_swap_case_unmap_physmem(struct udevice *dev,
+					   const void *vaddr, unsigned long len)
+{
+	struct swap_case_priv *priv = dev_get_priv(dev);
+
+	sandbox_swap_case_do_op(priv->op, (void *)vaddr, len);
+
+	return 0;
+}
+
+struct dm_pci_emul_ops sandbox_swap_case_emul_ops = {
+	.get_devfn = sandbox_swap_case_get_devfn,
+	.read_config = sandbox_swap_case_read_config,
+	.write_config = sandbox_swap_case_write_config,
+	.read_io = sandbox_swap_case_read_io,
+	.write_io = sandbox_swap_case_write_io,
+	.map_physmem = sandbox_swap_case_map_physmem,
+	.unmap_physmem = sandbox_swap_case_unmap_physmem,
+};
+
+static const struct udevice_id sandbox_swap_case_ids[] = {
+	{ .compatible = "sandbox,swap-case" },
+	{ }
+};
+
+U_BOOT_DRIVER(sandbox_swap_case_emul) = {
+	.name		= "sandbox_swap_case_emul",
+	.id		= UCLASS_PCI_EMUL,
+	.of_match	= sandbox_swap_case_ids,
+	.ops		= &sandbox_swap_case_emul_ops,
+	.priv_auto_alloc_size = sizeof(struct swap_case_priv),
+	.platdata_auto_alloc_size = sizeof(struct swap_case_platdata),
+};
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 18/22] dm: sandbox: pci: Enable PCI for sandbox
  2015-03-05 19:25 [U-Boot] [PATCH v2 0/22] Add driver model support for PCI Simon Glass
                   ` (16 preceding siblings ...)
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 17/22] dm: sandbox: Add a emulated PCI device as an example Simon Glass
@ 2015-03-05 19:25 ` Simon Glass
  2015-03-20 23:16   ` Simon Glass
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 19/22] dm: x86: pci: Add a PCI driver for driver model Simon Glass
                   ` (4 subsequent siblings)
  22 siblings, 1 reply; 53+ messages in thread
From: Simon Glass @ 2015-03-05 19:25 UTC (permalink / raw)
  To: u-boot

Enable PCI options so that sandbox can be used for testing this bus with
driver model.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 configs/sandbox_defconfig | 3 +++
 include/configs/sandbox.h | 4 ++++
 2 files changed, 7 insertions(+)

diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 70f5b86..e23b959 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -12,3 +12,6 @@ CONFIG_DM_CROS_EC=y
 CONFIG_CROS_EC_SANDBOX=y
 CONFIG_CROS_EC_KEYB=y
 CONFIG_CMD_CROS_EC=y
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_PCI_SANDBOX=y
diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index febbfb6..c12c538 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -34,6 +34,10 @@
 #define CONFIG_CMD_FDT
 #define CONFIG_ANDROID_BOOT_IMAGE
 
+#define CONFIG_CMD_PCI
+#define CONFIG_PCI_PNP
+#define CONFIG_CMD_IO
+
 #define CONFIG_FS_FAT
 #define CONFIG_FAT_WRITE
 #define CONFIG_FS_EXT4
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 19/22] dm: x86: pci: Add a PCI driver for driver model
  2015-03-05 19:25 [U-Boot] [PATCH v2 0/22] Add driver model support for PCI Simon Glass
                   ` (17 preceding siblings ...)
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 18/22] dm: sandbox: pci: Enable PCI for sandbox Simon Glass
@ 2015-03-05 19:25 ` Simon Glass
  2015-03-20 23:16   ` Simon Glass
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 20/22] dm: x86: pci: Convert coreboot to use driver model for pci Simon Glass
                   ` (3 subsequent siblings)
  22 siblings, 1 reply; 53+ messages in thread
From: Simon Glass @ 2015-03-05 19:25 UTC (permalink / raw)
  To: u-boot

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

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 arch/x86/cpu/pci.c         | 40 ++++++++++++++++++++++++++++++++++++++++
 arch/x86/include/asm/pci.h |  8 ++++++++
 arch/x86/lib/Makefile      |  2 ++
 drivers/pci/Makefile       |  1 +
 drivers/pci/pci_x86.c      | 24 ++++++++++++++++++++++++
 5 files changed, 75 insertions(+)
 create mode 100644 drivers/pci/pci_x86.c

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 @@ void x86_pci_write_config32(pci_dev_t dev, unsigned where, unsigned value)
 {
 	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_config8(pci_dev_t dev, unsigned where, unsigned value);
 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	+= interrupts.o
 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 c1c2ae3..adc238f 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -9,6 +9,7 @@ ifneq ($(CONFIG_DM_PCI),)
 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,
+};
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 20/22] dm: x86: pci: Convert coreboot to use driver model for pci
  2015-03-05 19:25 [U-Boot] [PATCH v2 0/22] Add driver model support for PCI Simon Glass
                   ` (18 preceding siblings ...)
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 19/22] dm: x86: pci: Add a PCI driver for driver model Simon Glass
@ 2015-03-05 19:25 ` Simon Glass
  2015-03-20 23:16   ` Simon Glass
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 21/22] dm: x86: pci: Convert chromebook_link " Simon Glass
                   ` (2 subsequent siblings)
  22 siblings, 1 reply; 53+ messages in thread
From: Simon Glass @ 2015-03-05 19:25 UTC (permalink / raw)
  To: u-boot

Move coreboot-x86 over to driver model for PCI.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 arch/x86/cpu/coreboot/pci.c         | 63 ++++++++++---------------------------
 arch/x86/dts/chromebook_link.dts    |  7 +++++
 board/google/chromebook_link/link.c |  9 ++++++
 configs/coreboot-x86_defconfig      |  1 +
 include/dm/uclass-id.h              |  1 +
 5 files changed, 34 insertions(+), 47 deletions(-)

diff --git a/arch/x86/cpu/coreboot/pci.c b/arch/x86/cpu/coreboot/pci.c
index c9983f1..fa415dd 100644
--- a/arch/x86/cpu/coreboot/pci.c
+++ b/arch/x86/cpu/coreboot/pci.c
@@ -10,58 +10,27 @@
  */
 
 #include <common.h>
+#include <dm.h>
+#include <errno.h>
 #include <pci.h>
+#include <asm/io.h>
 #include <asm/pci.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-static void config_pci_bridge(struct pci_controller *hose, pci_dev_t dev,
-			      struct pci_config_table *table)
-{
-	u8 secondary;
-	hose->read_byte(hose, dev, PCI_SECONDARY_BUS, &secondary);
-	hose->last_busno = max(hose->last_busno, (int)secondary);
-	pci_hose_scan_bus(hose, secondary);
-}
-
-static struct pci_config_table pci_coreboot_config_table[] = {
-	/* vendor, device, class, bus, dev, func */
-	{ PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_BRIDGE_PCI,
-		PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, &config_pci_bridge },
-	{}
+static const struct dm_pci_ops pci_x86_ops = {
+	.read_config	= pci_x86_read_config,
+	.write_config	= pci_x86_write_config,
 };
 
-void board_pci_setup_hose(struct pci_controller *hose)
-{
-	hose->config_table = pci_coreboot_config_table;
-	hose->first_busno = 0;
-	hose->last_busno = 0;
-
-	/* PCI memory space */
-	pci_set_region(hose->regions + 0,
-		       CONFIG_PCI_MEM_BUS,
-		       CONFIG_PCI_MEM_PHYS,
-		       CONFIG_PCI_MEM_SIZE,
-		       PCI_REGION_MEM);
-
-	/* PCI IO space */
-	pci_set_region(hose->regions + 1,
-		       CONFIG_PCI_IO_BUS,
-		       CONFIG_PCI_IO_PHYS,
-		       CONFIG_PCI_IO_SIZE,
-		       PCI_REGION_IO);
-
-	pci_set_region(hose->regions + 2,
-		       CONFIG_PCI_PREF_BUS,
-		       CONFIG_PCI_PREF_PHYS,
-		       CONFIG_PCI_PREF_SIZE,
-		       PCI_REGION_PREFETCH);
-
-	pci_set_region(hose->regions + 3,
-		       0,
-		       0,
-		       gd->ram_size,
-		       PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
+static const struct udevice_id pci_x86_ids[] = {
+	{ .compatible = "pci-x86" },
+	{ }
+};
 
-	hose->region_count = 4;
-}
+U_BOOT_DRIVER(pci_x86_drv) = {
+	.name		= "pci_x86",
+	.id		= UCLASS_PCI,
+	.of_match	= pci_x86_ids,
+	.ops		= &pci_x86_ops,
+};
diff --git a/arch/x86/dts/chromebook_link.dts b/arch/x86/dts/chromebook_link.dts
index 45ada61..cdbdb68 100644
--- a/arch/x86/dts/chromebook_link.dts
+++ b/arch/x86/dts/chromebook_link.dts
@@ -172,6 +172,13 @@
 	};
 
 	pci {
+		compatible = "intel,pci-ivybridge", "pci-x86";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		u-boot,dm-pre-reloc;
+		ranges = <0x02000000 0x0 0xe0000000 0xe0000000 0 0x10000000
+			0x42000000 0x0 0xd0000000 0xd0000000 0 0x10000000
+			0x01000000 0x0 0x1000 0x1000 0 0xefff>;
 		sata {
 			compatible = "intel,pantherpoint-ahci";
 			intel,sata-mode = "ahci";
diff --git a/board/google/chromebook_link/link.c b/board/google/chromebook_link/link.c
index 9978e92..8c04cb8 100644
--- a/board/google/chromebook_link/link.c
+++ b/board/google/chromebook_link/link.c
@@ -6,6 +6,7 @@
 
 #include <common.h>
 #include <cros_ec.h>
+#include <dm.h>
 #include <asm/gpio.h>
 #include <asm/io.h>
 #include <asm/pci.h>
@@ -13,6 +14,14 @@
 
 int arch_early_init_r(void)
 {
+	struct udevice *dev;
+	int ret;
+
+	/* Make sure the platform controller hub is up and running */
+	ret = uclass_get_device(UCLASS_PCH, 0, &dev);
+	if (ret)
+		return ret;
+
 	if (cros_ec_board_init())
 		return -1;
 
diff --git a/configs/coreboot-x86_defconfig b/configs/coreboot-x86_defconfig
index 3cc034a..0249172 100644
--- a/configs/coreboot-x86_defconfig
+++ b/configs/coreboot-x86_defconfig
@@ -2,3 +2,4 @@ CONFIG_SYS_EXTRA_OPTIONS="SYS_TEXT_BASE=0x01110000"
 CONFIG_X86=y
 CONFIG_TARGET_COREBOOT=y
 CONFIG_OF_CONTROL=y
+CONFIG_DM_PCI=y
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 0b6e850..047ac15 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -37,6 +37,7 @@ enum uclass_id {
 	UCLASS_MOD_EXP,		/* RSA Mod Exp device */
 	UCLASS_PCI,		/* PCI bus */
 	UCLASS_PCI_GENERIC,	/* Generic PCI bus device */
+	UCLASS_PCH,		/* x86 platform controller hub */
 
 	UCLASS_COUNT,
 	UCLASS_INVALID = -1,
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 21/22] dm: x86: pci: Convert chromebook_link to use driver model for pci
  2015-03-05 19:25 [U-Boot] [PATCH v2 0/22] Add driver model support for PCI Simon Glass
                   ` (19 preceding siblings ...)
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 20/22] dm: x86: pci: Convert coreboot to use driver model for pci Simon Glass
@ 2015-03-05 19:25 ` Simon Glass
  2015-03-20 23:16   ` Simon Glass
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 22/22] dm: pci: Add driver model tests for PCI Simon Glass
  2015-03-20 23:13 ` [U-Boot] [PATCH v2 0/22] Add driver model support " Simon Glass
  22 siblings, 1 reply; 53+ messages in thread
From: Simon Glass @ 2015-03-05 19:25 UTC (permalink / raw)
  To: u-boot

Move chromebook_link over to driver model for PCI.

This involves:
- adding a uclass for platform controller hub
- removing most of the existing PCI driver
- adjusting how CPU init works to use driver model instead
- rename the lpc compatible string (it will be removed later)

This does not really take advantage of driver model fully, but it does work.
Furture work will improve the code structure to remove many of the explicit
calls to init the board.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 arch/x86/cpu/ivybridge/bd82x6x.c              | 24 +++++++-
 arch/x86/cpu/ivybridge/cpu.c                  | 16 +++---
 arch/x86/cpu/ivybridge/lpc.c                  |  1 +
 arch/x86/cpu/ivybridge/pci.c                  | 81 ++++++++-------------------
 arch/x86/dts/chromebook_link.dts              |  3 +-
 arch/x86/include/asm/arch-ivybridge/bd82x6x.h |  1 -
 configs/chromebook_link_defconfig             |  1 +
 configs/chromebox_panther_defconfig           |  1 +
 lib/fdtdec.c                                  |  2 +-
 9 files changed, 62 insertions(+), 68 deletions(-)

diff --git a/arch/x86/cpu/ivybridge/bd82x6x.c b/arch/x86/cpu/ivybridge/bd82x6x.c
index 56b19e3..7b74282 100644
--- a/arch/x86/cpu/ivybridge/bd82x6x.c
+++ b/arch/x86/cpu/ivybridge/bd82x6x.c
@@ -5,6 +5,7 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <errno.h>
 #include <fdtdec.h>
 #include <malloc.h>
@@ -86,7 +87,7 @@ void bd82x6x_pci_bus_enable_resources(pci_dev_t dev)
 	bd82x6x_pci_dev_enable_resources(dev);
 }
 
-int bd82x6x_init_pci_devices(void)
+static int bd82x6x_probe(struct udevice *dev)
 {
 	const void *blob = gd->fdt_blob;
 	struct pci_controller *hose;
@@ -144,3 +145,24 @@ int bd82x6x_init(void)
 
 	return 0;
 }
+
+static const struct udevice_id bd82x6x_ids[] = {
+	{ .compatible = "intel,bd82x6x" },
+	{ }
+};
+
+U_BOOT_DRIVER(bd82x6x_drv) = {
+	.name		= "bd82x6x",
+	.id		= UCLASS_PCH,
+	.of_match	= bd82x6x_ids,
+	.probe		= bd82x6x_probe,
+};
+
+/*
+ * TODO(sjg at chromium.org): Move this to arch/x86/lib or similar when other
+ * boards also use a PCH
+ */
+UCLASS_DRIVER(pch) = {
+	.id		= UCLASS_PCH,
+	.name		= "pch",
+};
diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c
index e6ef481..2639ec2 100644
--- a/arch/x86/cpu/ivybridge/cpu.c
+++ b/arch/x86/cpu/ivybridge/cpu.c
@@ -12,6 +12,7 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <errno.h>
 #include <fdtdec.h>
 #include <asm/cpu.h>
@@ -126,19 +127,20 @@ int arch_cpu_init_dm(void)
 {
 	const void *blob = gd->fdt_blob;
 	struct pci_controller *hose;
+	struct udevice *bus;
 	int node;
 	int ret;
 
-	post_code(POST_CPU_INIT);
-	timer_set_base(rdtsc());
-
-	ret = x86_cpu_init_f();
+	post_code(0x70);
+	ret = uclass_get_device(UCLASS_PCI, 0, &bus);
+	post_code(0x71);
 	if (ret)
 		return ret;
+	post_code(0x72);
+	hose = dev_get_uclass_priv(bus);
 
-	ret = pci_early_init_hose(&hose);
-	if (ret)
-		return ret;
+	/* TODO(sjg at chromium.org): Get rid of gd->hose */
+	gd->hose = hose;
 
 	node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_LPC);
 	if (node < 0)
diff --git a/arch/x86/cpu/ivybridge/lpc.c b/arch/x86/cpu/ivybridge/lpc.c
index 33b11a1..c20e180 100644
--- a/arch/x86/cpu/ivybridge/lpc.c
+++ b/arch/x86/cpu/ivybridge/lpc.c
@@ -7,6 +7,7 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <errno.h>
 #include <fdtdec.h>
 #include <rtc.h>
diff --git a/arch/x86/cpu/ivybridge/pci.c b/arch/x86/cpu/ivybridge/pci.c
index 7f62a86..5e90f30 100644
--- a/arch/x86/cpu/ivybridge/pci.c
+++ b/arch/x86/cpu/ivybridge/pci.c
@@ -10,63 +10,24 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <pci.h>
 #include <asm/pci.h>
+#include <asm/post.h>
 #include <asm/arch/bd82x6x.h>
 #include <asm/arch/pch.h>
 
-static void config_pci_bridge(struct pci_controller *hose, pci_dev_t dev,
-			      struct pci_config_table *table)
-{
-	u8 secondary;
-
-	hose->read_byte(hose, dev, PCI_SECONDARY_BUS, &secondary);
-	if (secondary != 0)
-		pci_hose_scan_bus(hose, secondary);
-}
-
-static struct pci_config_table pci_ivybridge_config_table[] = {
-	/* vendor, device, class, bus, dev, func */
-	{ PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_BRIDGE_PCI,
-		PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, &config_pci_bridge },
-	{}
-};
-
-void board_pci_setup_hose(struct pci_controller *hose)
-{
-	hose->config_table = pci_ivybridge_config_table;
-	hose->first_busno = 0;
-	hose->last_busno = 0;
-
-	/* PCI memory space */
-	pci_set_region(hose->regions + 0,
-		       CONFIG_PCI_MEM_BUS,
-		       CONFIG_PCI_MEM_PHYS,
-		       CONFIG_PCI_MEM_SIZE,
-		       PCI_REGION_MEM);
-
-	/* PCI IO space */
-	pci_set_region(hose->regions + 1,
-		       CONFIG_PCI_IO_BUS,
-		       CONFIG_PCI_IO_PHYS,
-		       CONFIG_PCI_IO_SIZE,
-		       PCI_REGION_IO);
-
-	pci_set_region(hose->regions + 2,
-		       CONFIG_PCI_PREF_BUS,
-		       CONFIG_PCI_PREF_PHYS,
-		       CONFIG_PCI_PREF_SIZE,
-		       PCI_REGION_PREFETCH);
-
-	hose->region_count = 3;
-}
-
-int board_pci_pre_scan(struct pci_controller *hose)
+static int pci_ivybridge_probe(struct udevice *bus)
 {
+	struct pci_controller *hose = dev_get_uclass_priv(bus);
 	pci_dev_t dev;
 	u16 reg16;
 
+	if (!(gd->flags & GD_FLG_RELOC))
+		return 0;
+	post_code(0x50);
 	bd82x6x_init();
+	post_code(0x51);
 
 	reg16 = 0xff;
 	dev = PCH_DEV;
@@ -82,19 +43,25 @@ int board_pci_pre_scan(struct pci_controller *hose)
 	pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
 
 	pci_write_bar32(hose, dev, 0, 0xf0000000);
+	post_code(0x52);
 
 	return 0;
 }
 
-int board_pci_post_scan(struct pci_controller *hose)
-{
-	int ret;
+static const struct dm_pci_ops pci_ivybridge_ops = {
+	.read_config	= pci_x86_read_config,
+	.write_config	= pci_x86_write_config,
+};
 
-	ret = bd82x6x_init_pci_devices();
-	if (ret) {
-		printf("bd82x6x_init_pci_devices() failed: %d\n", ret);
-		return ret;
-	}
+static const struct udevice_id pci_ivybridge_ids[] = {
+	{ .compatible = "intel,pci-ivybridge" },
+	{ }
+};
 
-	return 0;
-}
+U_BOOT_DRIVER(pci_ivybridge_drv) = {
+	.name		= "pci_ivybridge",
+	.id		= UCLASS_PCI,
+	.of_match	= pci_ivybridge_ids,
+	.ops		= &pci_ivybridge_ops,
+	.probe		= pci_ivybridge_probe,
+};
diff --git a/arch/x86/dts/chromebook_link.dts b/arch/x86/dts/chromebook_link.dts
index cdbdb68..0a845f2 100644
--- a/arch/x86/dts/chromebook_link.dts
+++ b/arch/x86/dts/chromebook_link.dts
@@ -200,7 +200,8 @@
 		};
 
 		lpc {
-			compatible = "intel,lpc";
+			reg = <0x0000f800 0 0 0 0>;
+			compatible = "intel,bd82x6x";
 			#address-cells = <1>;
 			#size-cells = <1>;
 			gen-dec = <0x800 0xfc 0x900 0xfc>;
diff --git a/arch/x86/include/asm/arch-ivybridge/bd82x6x.h b/arch/x86/include/asm/arch-ivybridge/bd82x6x.h
index e1d9a9b..5ae32f7 100644
--- a/arch/x86/include/asm/arch-ivybridge/bd82x6x.h
+++ b/arch/x86/include/asm/arch-ivybridge/bd82x6x.h
@@ -12,7 +12,6 @@ void bd82x6x_sata_enable(pci_dev_t dev, const void *blob, int node);
 void bd82x6x_pci_init(pci_dev_t dev);
 void bd82x6x_usb_ehci_init(pci_dev_t dev);
 void bd82x6x_usb_xhci_init(pci_dev_t dev);
-int bd82x6x_init_pci_devices(void);
 int gma_func0_init(pci_dev_t dev, struct pci_controller *hose,
 		   const void *blob, int node);
 int bd82x6x_init(void);
diff --git a/configs/chromebook_link_defconfig b/configs/chromebook_link_defconfig
index 2f0c714..f3196fd 100644
--- a/configs/chromebook_link_defconfig
+++ b/configs/chromebook_link_defconfig
@@ -9,3 +9,4 @@ CONFIG_SMM_TSEG_SIZE=0x800000
 CONFIG_VIDEO_VESA=y
 CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
 CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
+CONFIG_DM_PCI=y
diff --git a/configs/chromebox_panther_defconfig b/configs/chromebox_panther_defconfig
index cbde39e..0613cd6 100644
--- a/configs/chromebox_panther_defconfig
+++ b/configs/chromebox_panther_defconfig
@@ -9,3 +9,4 @@ CONFIG_SMM_TSEG_SIZE=0x800000
 CONFIG_VIDEO_VESA=y
 CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
 CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
+CONFIG_DM_PCI=y
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 9212f03..d65e168 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -67,7 +67,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
 	COMPAT(COMPAT_NXP_PTN3460, "nxp,ptn3460"),
 	COMPAT(SAMSUNG_EXYNOS_SYSMMU, "samsung,sysmmu-v3.3"),
 	COMPAT(PARADE_PS8625, "parade,ps8625"),
-	COMPAT(COMPAT_INTEL_LPC, "intel,lpc"),
+	COMPAT(COMPAT_INTEL_LPC, "intel,bd82x6x"),
 	COMPAT(INTEL_MICROCODE, "intel,microcode"),
 	COMPAT(MEMORY_SPD, "memory-spd"),
 	COMPAT(INTEL_PANTHERPOINT_AHCI, "intel,pantherpoint-ahci"),
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 22/22] dm: pci: Add driver model tests for PCI
  2015-03-05 19:25 [U-Boot] [PATCH v2 0/22] Add driver model support for PCI Simon Glass
                   ` (20 preceding siblings ...)
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 21/22] dm: x86: pci: Convert chromebook_link " Simon Glass
@ 2015-03-05 19:25 ` Simon Glass
  2015-03-20 23:16   ` Simon Glass
  2015-03-20 23:13 ` [U-Boot] [PATCH v2 0/22] Add driver model support " Simon Glass
  22 siblings, 1 reply; 53+ messages in thread
From: Simon Glass @ 2015-03-05 19:25 UTC (permalink / raw)
  To: u-boot

Add some basic tests to check that things work as expected with sandbox.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 test/dm/Makefile |  1 +
 test/dm/pci.c    | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 test/dm/test.dts | 17 ++++++++++++++++
 3 files changed, 77 insertions(+)
 create mode 100644 test/dm/pci.c

diff --git a/test/dm/Makefile b/test/dm/Makefile
index 612aa95..8281779 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -21,4 +21,5 @@ obj-$(CONFIG_DM_GPIO) += gpio.o
 obj-$(CONFIG_DM_SPI) += spi.o
 obj-$(CONFIG_DM_SPI_FLASH) += sf.o
 obj-$(CONFIG_DM_I2C) += i2c.o
+obj-$(CONFIG_DM_PCI) += pci.o
 endif
diff --git a/test/dm/pci.c b/test/dm/pci.c
new file mode 100644
index 0000000..6c63fa4
--- /dev/null
+++ b/test/dm/pci.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/io.h>
+#include <dm/test.h>
+#include <dm/ut.h>
+
+/* Test that sandbox PCI works correctly */
+static int dm_test_pci_base(struct dm_test_state *dms)
+{
+	struct udevice *bus;
+
+	ut_assertok(uclass_get_device(UCLASS_PCI, 0, &bus));
+
+	return 0;
+}
+DM_TEST(dm_test_pci_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test that we can use the swapcase device correctly */
+static int dm_test_pci_swapcase(struct dm_test_state *dms)
+{
+	pci_dev_t pci_dev = PCI_BDF(0, 0x1f, 0);
+	struct pci_controller *hose;
+	struct udevice *bus, *swap;
+	ulong io_addr, mem_addr;
+	char *ptr;
+
+	/* Check that asking for the device automatically fires up PCI */
+	ut_assertok(uclass_get_device(UCLASS_PCI_EMUL, 0, &swap));
+
+	ut_assertok(uclass_get_device(UCLASS_PCI, 0, &bus));
+	hose = dev_get_uclass_priv(bus);
+
+	/* First test I/O */
+	io_addr = pci_read_bar32(hose, pci_dev, 0);
+	outb(2, io_addr);
+	ut_asserteq(2, inb(io_addr));
+
+	/*
+	 * Now test memory mapping - note we must unmap and remap to cause
+	 * the swapcase emulation to see our data and response.
+	 */
+	mem_addr = pci_read_bar32(hose, pci_dev, 1);
+	ptr = map_sysmem(mem_addr, 20);
+	strcpy(ptr, "This is a TesT");
+	unmap_sysmem(ptr);
+
+	ptr = map_sysmem(mem_addr, 20);
+	ut_asserteq_str("tHIS IS A tESt", ptr);
+	unmap_sysmem(ptr);
+
+	return 0;
+}
+DM_TEST(dm_test_pci_swapcase, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
diff --git a/test/dm/test.dts b/test/dm/test.dts
index 84024a4..96775e1 100644
--- a/test/dm/test.dts
+++ b/test/dm/test.dts
@@ -10,6 +10,7 @@
 		console = &uart0;
 		i2c0 = "/i2c at 0";
 		spi0 = "/spi at 0";
+		pci0 = &pci;
 		testfdt6 = "/e-test";
 		testbus3 = "/some-bus";
 		testfdt0 = "/some-bus/c-test at 0";
@@ -135,6 +136,22 @@
 		};
 	};
 
+	pci: pci-controller {
+		compatible = "sandbox,pci";
+		device_type = "pci";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		ranges = <0x02000000 0 0x10000000 0x10000000 0 0x2000
+				0x01000000 0 0x20000000 0x20000000 0 0x2000>;
+		pci at 1f,0 {
+			compatible = "pci-generic";
+			reg = <0xf800 0 0 0 0>;
+			emul at 1f,0 {
+				compatible = "sandbox,swap-case";
+			};
+		};
+	};
+
 	spi at 0 {
 		#address-cells = <1>;
 		#size-cells = <0>;
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 02/22] fdt: Export fdtdec_get_number() for general use
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 02/22] fdt: Export fdtdec_get_number() for general use Simon Glass
@ 2015-03-06 15:43   ` Tom Rini
  2015-03-20 23:14     ` Simon Glass
  0 siblings, 1 reply; 53+ messages in thread
From: Tom Rini @ 2015-03-06 15:43 UTC (permalink / raw)
  To: u-boot

On Thu, Mar 05, 2015 at 12:25:14PM -0700, Simon Glass wrote:

> This function is missing a prototype but is more widey useful. Add it.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>

Reviewed-by: Tom Rini <trini@konsulko.com>

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20150306/f1020dea/attachment.sig>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 07/22] fdt: Tighten up error handling in fdtdec_get_pci_addr()
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 07/22] fdt: Tighten up error handling in fdtdec_get_pci_addr() Simon Glass
@ 2015-03-06 15:43   ` Tom Rini
  2015-03-09  9:09   ` Bin Meng
  1 sibling, 0 replies; 53+ messages in thread
From: Tom Rini @ 2015-03-06 15:43 UTC (permalink / raw)
  To: u-boot

On Thu, Mar 05, 2015 at 12:25:19PM -0700, Simon Glass wrote:

> This function returns -ENOENT when the property is missing (which the caller
> might forgive) and also when the property is present but incorrectly
> formatted (which many callers would like to report).
> 
> Update the error return value to allow these different situations to be
> distinguished.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>

Reviewed-by: Tom Rini <trini@konsulko.com>

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20150306/2dc530d7/attachment.sig>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 01/22] sandbox: Update device tree 'reg' properties for I2C and SPI
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 01/22] sandbox: Update device tree 'reg' properties for I2C and SPI Simon Glass
@ 2015-03-09  8:57   ` Bin Meng
  2015-03-20 23:13     ` Simon Glass
  0 siblings, 1 reply; 53+ messages in thread
From: Bin Meng @ 2015-03-09  8:57 UTC (permalink / raw)
  To: u-boot

On Fri, Mar 6, 2015 at 3:25 AM, Simon Glass <sjg@chromium.org> wrote:
> We should have a size value for these. Add one in each case. This will
> be needed for PCI.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2:
> - Update root node #size=cells to 1 in this patch
>
>  arch/sandbox/dts/sandbox.dts | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts
> index 9ce31bf..d090ba8 100644
> --- a/arch/sandbox/dts/sandbox.dts
> +++ b/arch/sandbox/dts/sandbox.dts
> @@ -2,7 +2,7 @@
>
>  / {
>         #address-cells = <1>;
> -       #size-cells = <0>;
> +       #size-cells = <1>;
>
>         chosen {
>                 stdout-path = "/serial";
> @@ -144,7 +144,7 @@
>         i2c at 0 {
>                 #address-cells = <1>;
>                 #size-cells = <0>;
> -               reg = <0>;
> +               reg = <0 0>;
>                 compatible = "sandbox,i2c";
>                 clock-frequency = <400000>;
>                 eeprom at 2c {
> @@ -161,7 +161,7 @@
>         spi at 0 {
>                 #address-cells = <1>;
>                 #size-cells = <0>;
> -               reg = <0>;
> +               reg = <0 0>;
>                 compatible = "sandbox,spi";
>                 cs-gpios = <0>, <&gpio_a 0>;
>                 flash at 0 {
> --

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 04/22] dm: Add a new CPU init function which can use driver model
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 04/22] dm: Add a new CPU init function which can use driver model Simon Glass
@ 2015-03-09  9:02   ` Bin Meng
  2015-03-20 23:14     ` Simon Glass
  0 siblings, 1 reply; 53+ messages in thread
From: Bin Meng @ 2015-03-09  9:02 UTC (permalink / raw)
  To: u-boot

On Fri, Mar 6, 2015 at 3:25 AM, Simon Glass <sjg@chromium.org> wrote:
> Since driver model is set up after arch_cpu_init(), that function cannot
> use drivers. Add a new arch_cpu_init_dm() function which is called
> immediately after driver model is ready, and can reference devices.
>
> This can be used to probe essential devices for the CPU.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2:
> - Add a new patch with a CPU init function which can use driver model
>
>  common/board_f.c |  6 ++++++
>  include/common.h | 11 +++++++++++
>  2 files changed, 17 insertions(+)
>
> diff --git a/common/board_f.c b/common/board_f.c
> index 4d8b8a6..8bbece2 100644
> --- a/common/board_f.c
> +++ b/common/board_f.c
> @@ -787,6 +787,11 @@ __weak int reserve_arch(void)
>         return 0;
>  }
>
> +__weak int arch_cpu_init_dm(void)
> +{
> +       return 0;
> +}
> +
>  static init_fnc_t init_sequence_f[] = {
>  #ifdef CONFIG_SANDBOX
>         setup_ram_buf,
> @@ -807,6 +812,7 @@ static init_fnc_t init_sequence_f[] = {
>         fdtdec_check_fdt,
>  #endif
>         initf_dm,
> +       arch_cpu_init_dm,
>  #if defined(CONFIG_BOARD_EARLY_INIT_F)
>         board_early_init_f,
>  #endif
> diff --git a/include/common.h b/include/common.h
> index 77c55c6..f9aaaa5 100644
> --- a/include/common.h
> +++ b/include/common.h
> @@ -253,6 +253,17 @@ int update_flash_size(int flash_size);
>  int arch_early_init_r(void);
>
>  /**
> + * arch_cpu_init_dm() - init CPU after driver model is available
> + *
> + * This is called immediately after driver model is available before
> + * relocation. This is similar to arch_cpu_init() but is able to reference
> + * devices
> + *
> + * @return 0 if OK, -ve on error
> + */
> +int arch_cpu_init_dm(void);
> +
> +/**
>   * Reserve all necessary stacks
>   *
>   * This is used in generic board init sequence in common/board_f.c. Each
> --

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 05/22] x86: Split up arch_cpu_init()
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 05/22] x86: Split up arch_cpu_init() Simon Glass
@ 2015-03-09  9:06   ` Bin Meng
  2015-03-20 23:14     ` Simon Glass
  0 siblings, 1 reply; 53+ messages in thread
From: Bin Meng @ 2015-03-09  9:06 UTC (permalink / raw)
  To: u-boot

On Fri, Mar 6, 2015 at 3:25 AM, Simon Glass <sjg@chromium.org> wrote:
> At present we do more in this function than we should. Split out the
> post-driver-model part into a separate function.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2:
> - Use the new arch_cpu_init_dm() function instead of something x86-specific
>
>  arch/x86/cpu/ivybridge/cpu.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
>
> diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c
> index 5fd3753..e6ef481 100644
> --- a/arch/x86/cpu/ivybridge/cpu.c
> +++ b/arch/x86/cpu/ivybridge/cpu.c
> @@ -116,6 +116,14 @@ static void set_spi_speed(void)
>
>  int arch_cpu_init(void)
>  {
> +       post_code(POST_CPU_INIT);
> +       timer_set_base(rdtsc());
> +
> +       return x86_cpu_init_f();
> +}
> +
> +int arch_cpu_init_dm(void)
> +{
>         const void *blob = gd->fdt_blob;
>         struct pci_controller *hose;
>         int node;
> --

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 06/22] Correct map_sysmem() logic in do_mem_mw()
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 06/22] Correct map_sysmem() logic in do_mem_mw() Simon Glass
@ 2015-03-09  9:06   ` Bin Meng
  2015-03-20 23:14     ` Simon Glass
  0 siblings, 1 reply; 53+ messages in thread
From: Bin Meng @ 2015-03-09  9:06 UTC (permalink / raw)
  To: u-boot

On Fri, Mar 6, 2015 at 3:25 AM, Simon Glass <sjg@chromium.org> wrote:
> This function does not unmap what it maps. Correct it.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  common/cmd_mem.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/common/cmd_mem.c b/common/cmd_mem.c
> index bcb3ee3..855aa57 100644
> --- a/common/cmd_mem.c
> +++ b/common/cmd_mem.c
> @@ -165,7 +165,7 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
>  #endif
>         ulong   addr, count;
>         int     size;
> -       void *buf;
> +       void *buf, *start;
>         ulong bytes;
>
>         if ((argc < 3) || (argc > 4))
> @@ -197,7 +197,8 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
>         }
>
>         bytes = size * count;
> -       buf = map_sysmem(addr, bytes);
> +       start = map_sysmem(addr, bytes);
> +       buf = start;
>         while (count-- > 0) {
>                 if (size == 4)
>                         *((u32 *)buf) = (u32)writeval;
> @@ -211,7 +212,7 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
>                         *((u8 *)buf) = (u8)writeval;
>                 buf += size;
>         }
> -       unmap_sysmem(buf);
> +       unmap_sysmem(start);
>         return 0;
>  }
>
> --

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 07/22] fdt: Tighten up error handling in fdtdec_get_pci_addr()
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 07/22] fdt: Tighten up error handling in fdtdec_get_pci_addr() Simon Glass
  2015-03-06 15:43   ` Tom Rini
@ 2015-03-09  9:09   ` Bin Meng
  2015-03-20 23:14     ` Simon Glass
  1 sibling, 1 reply; 53+ messages in thread
From: Bin Meng @ 2015-03-09  9:09 UTC (permalink / raw)
  To: u-boot

On Fri, Mar 6, 2015 at 3:25 AM, Simon Glass <sjg@chromium.org> wrote:
> This function returns -ENOENT when the property is missing (which the caller
> might forgive) and also when the property is present but incorrectly
> formatted (which many callers would like to report).
>
> Update the error return value to allow these different situations to be
> distinguished.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2:
> - Add -ve sign before ENXIO
>
>  include/fdtdec.h | 4 +++-
>  lib/fdtdec.c     | 4 +++-
>  2 files changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/include/fdtdec.h b/include/fdtdec.h
> index 21bd6bb..6944048 100644
> --- a/include/fdtdec.h
> +++ b/include/fdtdec.h
> @@ -327,7 +327,9 @@ fdt_addr_t fdtdec_get_addr_size(const void *blob, int node,
>   * @param type         pci address type (FDT_PCI_SPACE_xxx)
>   * @param prop_name    name of property to find
>   * @param addr         returns pci address in the form of fdt_pci_addr
> - * @return 0 if ok, negative on error
> + * @return 0 if ok, -ENOENT if the property did not exist, -EINVAL if the
> + *             format of the property was invalid, -ENXIO if the requested
> + *             address type was not found
>   */
>  int fdtdec_get_pci_addr(const void *blob, int node, enum fdt_pci_space type,
>                 const char *prop_name, struct fdt_pci_addr *addr);
> diff --git a/lib/fdtdec.c b/lib/fdtdec.c
> index e47fa96..9212f03 100644
> --- a/lib/fdtdec.c
> +++ b/lib/fdtdec.c
> @@ -160,8 +160,10 @@ int fdtdec_get_pci_addr(const void *blob, int node, enum fdt_pci_space type,
>                         }
>                 }
>
> -               if (i == num)
> +               if (i == num) {
> +                       ret = -ENXIO;
>                         goto fail;
> +               }
>
>                 return 0;
>         } else {
> --

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 01/22] sandbox: Update device tree 'reg' properties for I2C and SPI
  2015-03-09  8:57   ` Bin Meng
@ 2015-03-20 23:13     ` Simon Glass
  0 siblings, 0 replies; 53+ messages in thread
From: Simon Glass @ 2015-03-20 23:13 UTC (permalink / raw)
  To: u-boot

On 9 March 2015 at 02:57, Bin Meng <bmeng.cn@gmail.com> wrote:
> On Fri, Mar 6, 2015 at 3:25 AM, Simon Glass <sjg@chromium.org> wrote:
>> We should have a size value for these. Add one in each case. This will
>> be needed for PCI.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>> Changes in v2:
>> - Update root node #size=cells to 1 in this patch
>>
>>  arch/sandbox/dts/sandbox.dts | 6 +++---
>>  1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts
>> index 9ce31bf..d090ba8 100644
>> --- a/arch/sandbox/dts/sandbox.dts
>> +++ b/arch/sandbox/dts/sandbox.dts
>> @@ -2,7 +2,7 @@
>>
>>  / {
>>         #address-cells = <1>;
>> -       #size-cells = <0>;
>> +       #size-cells = <1>;
>>
>>         chosen {
>>                 stdout-path = "/serial";
>> @@ -144,7 +144,7 @@
>>         i2c at 0 {
>>                 #address-cells = <1>;
>>                 #size-cells = <0>;
>> -               reg = <0>;
>> +               reg = <0 0>;
>>                 compatible = "sandbox,i2c";
>>                 clock-frequency = <400000>;
>>                 eeprom at 2c {
>> @@ -161,7 +161,7 @@
>>         spi at 0 {
>>                 #address-cells = <1>;
>>                 #size-cells = <0>;
>> -               reg = <0>;
>> +               reg = <0 0>;
>>                 compatible = "sandbox,spi";
>>                 cs-gpios = <0>, <&gpio_a 0>;
>>                 flash at 0 {
>> --
>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 0/22] Add driver model support for PCI
  2015-03-05 19:25 [U-Boot] [PATCH v2 0/22] Add driver model support for PCI Simon Glass
                   ` (21 preceding siblings ...)
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 22/22] dm: pci: Add driver model tests for PCI Simon Glass
@ 2015-03-20 23:13 ` Simon Glass
  22 siblings, 0 replies; 53+ messages in thread
From: Simon Glass @ 2015-03-20 23:13 UTC (permalink / raw)
  To: u-boot

Hi,

On 5 March 2015 at 12:25, Simon Glass <sjg@chromium.org> wrote:
>
> This series is a collection of changes in core DM, sandbox, x86 and PCI code
> to implement a PCI uclass and associated operations. Some basic tests are
> provided as well.
>
> As is becoming common with DM conversions, the existing structure (here
> struct pci_controller) becomes per-bus uclass data. This allows the concept
> of a 'hose' (generally a PCI host controller and a bus) to continue to exist
> in the interim, even if it should not be needed in the end. This makes it
> much easier to convert over existing code.
>
> PCI buses are not scanned in the bind() method but only later when probe()
> is called. This will be automatic if you access a bus, but it does mean that
> if PCI is not used it will not be touched, in keeping with U-Boot's lazy-
> init philosophy.
>
> The existing 'pciauto' bus configuration code is still used, although it now
> uses DM underneath. It works exclusively by reading and writing PCI config
> and does not refer to DM data structures. The one change is to drop use of
> the hose->current_busno field which is no longer required. The fact that
> file works largely as before is an indication that a good level of
> compatibility is achieved between DM and legacy PCI.
>
> In order to support testing of PCI I/O and memory space, support has been
> added to sandbox to allow mapping of these. This allows commands like 'md'
> and 'iod' to display data from mapped PCI devices. Similarly, it is possible
> to make changes to this space. This support relies on the existing
> map_sysmem() and unmap_sysmem() calls which are now fairly widespread in
> U-Boot.
>
> Apart from the driver model tests (run with ./test/dm/test-dm.sh) you can
> try out these commands which use the new 'swap_case' test device:
>
> ../u-boot -d b/sandbox/u-boot.dtb
> ....
> => iow.b 20000000 2
> => iod.b 20000000
> 0000: 02
> => mw.l 10000000 64436241
> => md.l 10000000 1
> 10000000: 44634261                               aBcD
> =>
>
> This shows an I/O access to 20000000, setting the value 2 which means to
> swap the case. Then 'AbCd' is written to the memory space at 10000000 and
> 'aBcD' is read back.
>
> The 'pci' command can be used as before.
>
> Most existing PCI functions (in pci.h) still work, but route through driver
> model. The file drivers/pci/pci.c is replaced when driver model is enabled
> so not everything is present. A new pci_common.c file holds functions common
> to driver model and the old system, and pci_compat.c contains functions I
> would like to eventually deprecate.
>
> Two x86 boards (coreboot and chromebook_link) are converted over to use
> driver model for PCI.
>
> Core driver model changes include:
> - Addition of a new pre_probe() method for the uclass to set up devices just
> before the device's probe() method is called
> - A change in the ordering of when a device is marked as probed
> - A dev_get_uclass_priv() accessor
> - A tweak to the 'dm uclass' command to improve sequence number display
>
> Notably missing from this series are functions to access PCI devices using
> a 'struct udevice *'. Where there is no device tree entry for a bus device,
> a generic PCI device is created in driver model to mirror the device, as
> with I2C and SPI. Future work could add more real devices to x86 and create
> a demand for these sorts of functions. Also we might store things like the
> PCI base address registers (BARs) in data structures if there is a need.
> These things are probably best developed as a need arises to avoid creating
> infrastructure and overhead that may not be used.
>
> This series is available at u-boot-dm.git branch pci-working.
>
> Changes in v2:
> - Update root node #size=cells to 1 in this patch
> - Add a new patch with a CPU init function which can use driver model
> - Use the new arch_cpu_init_dm() function instead of something x86-specific
> - Add -ve sign before ENXIO

I'm going to go ahead and apply this to u-boot-dm/next along with the
x86 panther series (which it depends on).

>
> Simon Glass (22):
>   sandbox: Update device tree 'reg' properties for I2C and SPI
>   fdt: Export fdtdec_get_number() for general use
>   x86: Add a x86_ prefix to the x86-specific PCI functions
>   dm: Add a new CPU init function which can use driver model
>   x86: Split up arch_cpu_init()
>   Correct map_sysmem() logic in do_mem_mw()
>   fdt: Tighten up error handling in fdtdec_get_pci_addr()
>   dm: core: Add dev_get_uclass_priv() to access uclass private data
>   dm: core: Mark device as active before calling its probe() method
>   dm: core: Add a uclass pre_probe() method for devices
>   dm: Show both allocated and requested seq numbers in 'dm uclass'
>   dm: pci: Move common PCI functions into their own file
>   dm: pci: Add a uclass for PCI
>   dm: sandbox: pci: Add PCI support for sandbox
>   dm: sandbox: Add a simple PCI driver
>   dm: sandbox: pci: Add a PCI emulation uclass
>   dm: sandbox: Add a emulated PCI device as an example
>   dm: sandbox: pci: Enable PCI for sandbox
>   dm: x86: pci: Add a PCI driver for driver model
>   dm: x86: pci: Convert coreboot to use driver model for pci
>   dm: x86: pci: Convert chromebook_link to use driver model for pci
>   dm: pci: Add driver model tests for PCI
>
>  arch/sandbox/Kconfig                          |   7 +
>  arch/sandbox/cpu/cpu.c                        |  37 +-
>  arch/sandbox/dts/sandbox.dts                  |  26 +-
>  arch/sandbox/include/asm/io.h                 |  16 +-
>  arch/sandbox/include/asm/processor.h          |  12 +
>  arch/sandbox/include/asm/test.h               |   7 +-
>  arch/sandbox/include/asm/u-boot-sandbox.h     |  48 ++
>  arch/sandbox/lib/Makefile                     |   2 +-
>  arch/sandbox/lib/pci_io.c                     | 138 ++++++
>  arch/x86/cpu/baytrail/early_uart.c            |   5 +-
>  arch/x86/cpu/coreboot/pci.c                   |  63 +--
>  arch/x86/cpu/ivybridge/bd82x6x.c              |  56 ++-
>  arch/x86/cpu/ivybridge/cpu.c                  |  62 +--
>  arch/x86/cpu/ivybridge/early_init.c           |  58 +--
>  arch/x86/cpu/ivybridge/early_me.c             |  12 +-
>  arch/x86/cpu/ivybridge/gma.c                  |   4 +-
>  arch/x86/cpu/ivybridge/lpc.c                  |  75 +--
>  arch/x86/cpu/ivybridge/northbridge.c          |   6 +-
>  arch/x86/cpu/ivybridge/pch.c                  |   4 +-
>  arch/x86/cpu/ivybridge/pci.c                  |  85 ++--
>  arch/x86/cpu/ivybridge/report_platform.c      |   4 +-
>  arch/x86/cpu/ivybridge/sata.c                 |  61 +--
>  arch/x86/cpu/ivybridge/sdram.c                |  20 +-
>  arch/x86/cpu/ivybridge/usb_ehci.c             |   4 +-
>  arch/x86/cpu/ivybridge/usb_xhci.c             |   8 +-
>  arch/x86/cpu/pci.c                            |  52 ++-
>  arch/x86/cpu/quark/quark.c                    |   4 +-
>  arch/x86/cpu/queensbay/tnc.c                  |   4 +-
>  arch/x86/dts/chromebook_link.dts              |  10 +-
>  arch/x86/include/asm/arch-ivybridge/bd82x6x.h |   1 -
>  arch/x86/include/asm/pci.h                    |  20 +-
>  arch/x86/lib/Makefile                         |   2 +
>  arch/x86/lib/bios_interrupts.c                |  12 +-
>  board/google/chromebook_link/link.c           |   9 +
>  common/board_f.c                              |   6 +
>  common/board_r.c                              |   2 +
>  common/cmd_mem.c                              |   7 +-
>  common/cmd_pci.c                              |  14 +-
>  common/cmd_sf.c                               |   2 +-
>  common/cros_ec.c                              |   2 +-
>  configs/chromebook_link_defconfig             |   1 +
>  configs/chromebox_panther_defconfig           |   1 +
>  configs/coreboot-x86_defconfig                |   1 +
>  configs/sandbox_defconfig                     |   3 +
>  doc/driver-model/pci-info.txt                 |  70 +++
>  drivers/core/device.c                         |  19 +-
>  drivers/core/uclass.c                         |  10 +-
>  drivers/gpio/at91_gpio.c                      |   2 +-
>  drivers/gpio/bcm2835_gpio.c                   |   2 +-
>  drivers/gpio/gpio-uclass.c                    |  22 +-
>  drivers/gpio/intel_ich6_gpio.c                |  18 +-
>  drivers/gpio/mxc_gpio.c                       |   2 +-
>  drivers/gpio/omap_gpio.c                      |   2 +-
>  drivers/gpio/s5p_gpio.c                       |   2 +-
>  drivers/gpio/sandbox.c                        |   6 +-
>  drivers/gpio/sunxi_gpio.c                     |   2 +-
>  drivers/gpio/tegra_gpio.c                     |   2 +-
>  drivers/i2c/i2c-uclass.c                      |   6 +-
>  drivers/i2c/sandbox_i2c.c                     |   2 +-
>  drivers/misc/Makefile                         |   1 +
>  drivers/misc/cros_ec.c                        |   6 +-
>  drivers/misc/cros_ec_i2c.c                    |   2 +-
>  drivers/misc/cros_ec_sandbox.c                |   2 +-
>  drivers/misc/cros_ec_spi.c                    |   4 +-
>  drivers/misc/swap_case.c                      | 285 ++++++++++++
>  drivers/mtd/spi/sf-uclass.c                   |   2 +-
>  drivers/mtd/spi/sf_probe.c                    |   8 +-
>  drivers/pci/Kconfig                           |  22 +
>  drivers/pci/Makefile                          |  11 +-
>  drivers/pci/pci-emul-uclass.c                 |  67 +++
>  drivers/pci/pci-uclass.c                      | 639 ++++++++++++++++++++++++++
>  drivers/pci/pci.c                             | 281 +----------
>  drivers/pci/pci_auto.c                        |  16 +-
>  drivers/pci/pci_common.c                      | 292 ++++++++++++
>  drivers/pci/pci_compat.c                      |  43 ++
>  drivers/pci/pci_sandbox.c                     |  79 ++++
>  drivers/pci/pci_x86.c                         |  24 +
>  drivers/serial/serial-uclass.c                |   4 +-
>  drivers/spi/spi-uclass.c                      |   4 +-
>  include/common.h                              |  11 +
>  include/configs/sandbox.h                     |   4 +
>  include/dm/device.h                           |  10 +
>  include/dm/test.h                             |   1 +
>  include/dm/uclass-id.h                        |   4 +
>  include/dm/uclass-internal.h                  |   7 +-
>  include/dm/uclass.h                           |   2 +
>  include/fdtdec.h                              |  15 +-
>  include/i2c.h                                 |   8 +-
>  include/pci.h                                 | 411 ++++++++++++++++-
>  lib/fdtdec.c                                  |   8 +-
>  test/dm/Makefile                              |   1 +
>  test/dm/cmd_dm.c                              |   4 +-
>  test/dm/core.c                                |   9 +-
>  test/dm/pci.c                                 |  59 +++
>  test/dm/test-uclass.c                         |  16 +-
>  test/dm/test.dts                              |  17 +
>  96 files changed, 2842 insertions(+), 677 deletions(-)
>  create mode 100644 arch/sandbox/include/asm/processor.h
>  create mode 100644 arch/sandbox/lib/pci_io.c
>  create mode 100644 doc/driver-model/pci-info.txt
>  create mode 100644 drivers/misc/swap_case.c
>  create mode 100644 drivers/pci/pci-emul-uclass.c
>  create mode 100644 drivers/pci/pci-uclass.c
>  create mode 100644 drivers/pci/pci_common.c
>  create mode 100644 drivers/pci/pci_compat.c
>  create mode 100644 drivers/pci/pci_sandbox.c
>  create mode 100644 drivers/pci/pci_x86.c
>  create mode 100644 test/dm/pci.c
>
> --
> 2.2.0.rc0.207.ga3a616c
>

Regards,
Simon

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 02/22] fdt: Export fdtdec_get_number() for general use
  2015-03-06 15:43   ` Tom Rini
@ 2015-03-20 23:14     ` Simon Glass
  0 siblings, 0 replies; 53+ messages in thread
From: Simon Glass @ 2015-03-20 23:14 UTC (permalink / raw)
  To: u-boot

On 6 March 2015 at 08:43, Tom Rini <trini@konsulko.com> wrote:
> On Thu, Mar 05, 2015 at 12:25:14PM -0700, Simon Glass wrote:
>
>> This function is missing a prototype but is more widey useful. Add it.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>
> Reviewed-by: Tom Rini <trini@konsulko.com>

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 03/22] x86: Add a x86_ prefix to the x86-specific PCI functions
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 03/22] x86: Add a x86_ prefix to the x86-specific PCI functions Simon Glass
@ 2015-03-20 23:14   ` Simon Glass
  0 siblings, 0 replies; 53+ messages in thread
From: Simon Glass @ 2015-03-20 23:14 UTC (permalink / raw)
  To: u-boot

On 5 March 2015 at 12:25, Simon Glass <sjg@chromium.org> wrote:
> These functions currently use a generic name, but they are for x86 only.
> This may introduce confusion and prevents U-Boot from using these names
> more widely.
>
> In fact it should be possible to remove these at some point and use
> generic functions, but for now, rename them.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v2: None

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 04/22] dm: Add a new CPU init function which can use driver model
  2015-03-09  9:02   ` Bin Meng
@ 2015-03-20 23:14     ` Simon Glass
  0 siblings, 0 replies; 53+ messages in thread
From: Simon Glass @ 2015-03-20 23:14 UTC (permalink / raw)
  To: u-boot

On 9 March 2015 at 03:02, Bin Meng <bmeng.cn@gmail.com> wrote:
> On Fri, Mar 6, 2015 at 3:25 AM, Simon Glass <sjg@chromium.org> wrote:
>> Since driver model is set up after arch_cpu_init(), that function cannot
>> use drivers. Add a new arch_cpu_init_dm() function which is called
>> immediately after driver model is ready, and can reference devices.
>>
>> This can be used to probe essential devices for the CPU.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>> Changes in v2:
>> - Add a new patch with a CPU init function which can use driver model
>>
>>  common/board_f.c |  6 ++++++
>>  include/common.h | 11 +++++++++++
>>  2 files changed, 17 insertions(+)
>>
>> diff --git a/common/board_f.c b/common/board_f.c
>> index 4d8b8a6..8bbece2 100644
>> --- a/common/board_f.c
>> +++ b/common/board_f.c
>> @@ -787,6 +787,11 @@ __weak int reserve_arch(void)
>>         return 0;
>>  }
>>
>> +__weak int arch_cpu_init_dm(void)
>> +{
>> +       return 0;
>> +}
>> +
>>  static init_fnc_t init_sequence_f[] = {
>>  #ifdef CONFIG_SANDBOX
>>         setup_ram_buf,
>> @@ -807,6 +812,7 @@ static init_fnc_t init_sequence_f[] = {
>>         fdtdec_check_fdt,
>>  #endif
>>         initf_dm,
>> +       arch_cpu_init_dm,
>>  #if defined(CONFIG_BOARD_EARLY_INIT_F)
>>         board_early_init_f,
>>  #endif
>> diff --git a/include/common.h b/include/common.h
>> index 77c55c6..f9aaaa5 100644
>> --- a/include/common.h
>> +++ b/include/common.h
>> @@ -253,6 +253,17 @@ int update_flash_size(int flash_size);
>>  int arch_early_init_r(void);
>>
>>  /**
>> + * arch_cpu_init_dm() - init CPU after driver model is available
>> + *
>> + * This is called immediately after driver model is available before
>> + * relocation. This is similar to arch_cpu_init() but is able to reference
>> + * devices
>> + *
>> + * @return 0 if OK, -ve on error
>> + */
>> +int arch_cpu_init_dm(void);
>> +
>> +/**
>>   * Reserve all necessary stacks
>>   *
>>   * This is used in generic board init sequence in common/board_f.c. Each
>> --
>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 05/22] x86: Split up arch_cpu_init()
  2015-03-09  9:06   ` Bin Meng
@ 2015-03-20 23:14     ` Simon Glass
  0 siblings, 0 replies; 53+ messages in thread
From: Simon Glass @ 2015-03-20 23:14 UTC (permalink / raw)
  To: u-boot

On 9 March 2015 at 03:06, Bin Meng <bmeng.cn@gmail.com> wrote:
> On Fri, Mar 6, 2015 at 3:25 AM, Simon Glass <sjg@chromium.org> wrote:
>> At present we do more in this function than we should. Split out the
>> post-driver-model part into a separate function.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>> Changes in v2:
>> - Use the new arch_cpu_init_dm() function instead of something x86-specific
>>
>>  arch/x86/cpu/ivybridge/cpu.c | 8 ++++++++
>>  1 file changed, 8 insertions(+)
>>
>> diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c
>> index 5fd3753..e6ef481 100644
>> --- a/arch/x86/cpu/ivybridge/cpu.c
>> +++ b/arch/x86/cpu/ivybridge/cpu.c
>> @@ -116,6 +116,14 @@ static void set_spi_speed(void)
>>
>>  int arch_cpu_init(void)
>>  {
>> +       post_code(POST_CPU_INIT);
>> +       timer_set_base(rdtsc());
>> +
>> +       return x86_cpu_init_f();
>> +}
>> +
>> +int arch_cpu_init_dm(void)
>> +{
>>         const void *blob = gd->fdt_blob;
>>         struct pci_controller *hose;
>>         int node;
>> --
>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 06/22] Correct map_sysmem() logic in do_mem_mw()
  2015-03-09  9:06   ` Bin Meng
@ 2015-03-20 23:14     ` Simon Glass
  0 siblings, 0 replies; 53+ messages in thread
From: Simon Glass @ 2015-03-20 23:14 UTC (permalink / raw)
  To: u-boot

On 9 March 2015 at 03:06, Bin Meng <bmeng.cn@gmail.com> wrote:
> On Fri, Mar 6, 2015 at 3:25 AM, Simon Glass <sjg@chromium.org> wrote:
>> This function does not unmap what it maps. Correct it.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>> Changes in v2: None
>>
>>  common/cmd_mem.c | 7 ++++---
>>  1 file changed, 4 insertions(+), 3 deletions(-)
>>
>> diff --git a/common/cmd_mem.c b/common/cmd_mem.c
>> index bcb3ee3..855aa57 100644
>> --- a/common/cmd_mem.c
>> +++ b/common/cmd_mem.c
>> @@ -165,7 +165,7 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
>>  #endif
>>         ulong   addr, count;
>>         int     size;
>> -       void *buf;
>> +       void *buf, *start;
>>         ulong bytes;
>>
>>         if ((argc < 3) || (argc > 4))
>> @@ -197,7 +197,8 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
>>         }
>>
>>         bytes = size * count;
>> -       buf = map_sysmem(addr, bytes);
>> +       start = map_sysmem(addr, bytes);
>> +       buf = start;
>>         while (count-- > 0) {
>>                 if (size == 4)
>>                         *((u32 *)buf) = (u32)writeval;
>> @@ -211,7 +212,7 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
>>                         *((u8 *)buf) = (u8)writeval;
>>                 buf += size;
>>         }
>> -       unmap_sysmem(buf);
>> +       unmap_sysmem(start);
>>         return 0;
>>  }
>>
>> --
>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 07/22] fdt: Tighten up error handling in fdtdec_get_pci_addr()
  2015-03-09  9:09   ` Bin Meng
@ 2015-03-20 23:14     ` Simon Glass
  0 siblings, 0 replies; 53+ messages in thread
From: Simon Glass @ 2015-03-20 23:14 UTC (permalink / raw)
  To: u-boot

On 9 March 2015 at 03:09, Bin Meng <bmeng.cn@gmail.com> wrote:
> On Fri, Mar 6, 2015 at 3:25 AM, Simon Glass <sjg@chromium.org> wrote:
>> This function returns -ENOENT when the property is missing (which the caller
>> might forgive) and also when the property is present but incorrectly
>> formatted (which many callers would like to report).
>>
>> Update the error return value to allow these different situations to be
>> distinguished.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>> Changes in v2:
>> - Add -ve sign before ENXIO
>>
>>  include/fdtdec.h | 4 +++-
>>  lib/fdtdec.c     | 4 +++-
>>  2 files changed, 6 insertions(+), 2 deletions(-)
>>
>> diff --git a/include/fdtdec.h b/include/fdtdec.h
>> index 21bd6bb..6944048 100644
>> --- a/include/fdtdec.h
>> +++ b/include/fdtdec.h
>> @@ -327,7 +327,9 @@ fdt_addr_t fdtdec_get_addr_size(const void *blob, int node,
>>   * @param type         pci address type (FDT_PCI_SPACE_xxx)
>>   * @param prop_name    name of property to find
>>   * @param addr         returns pci address in the form of fdt_pci_addr
>> - * @return 0 if ok, negative on error
>> + * @return 0 if ok, -ENOENT if the property did not exist, -EINVAL if the
>> + *             format of the property was invalid, -ENXIO if the requested
>> + *             address type was not found
>>   */
>>  int fdtdec_get_pci_addr(const void *blob, int node, enum fdt_pci_space type,
>>                 const char *prop_name, struct fdt_pci_addr *addr);
>> diff --git a/lib/fdtdec.c b/lib/fdtdec.c
>> index e47fa96..9212f03 100644
>> --- a/lib/fdtdec.c
>> +++ b/lib/fdtdec.c
>> @@ -160,8 +160,10 @@ int fdtdec_get_pci_addr(const void *blob, int node, enum fdt_pci_space type,
>>                         }
>>                 }
>>
>> -               if (i == num)
>> +               if (i == num) {
>> +                       ret = -ENXIO;
>>                         goto fail;
>> +               }
>>
>>                 return 0;
>>         } else {
>> --
>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 08/22] dm: core: Add dev_get_uclass_priv() to access uclass private data
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 08/22] dm: core: Add dev_get_uclass_priv() to access uclass private data Simon Glass
@ 2015-03-20 23:15   ` Simon Glass
  0 siblings, 0 replies; 53+ messages in thread
From: Simon Glass @ 2015-03-20 23:15 UTC (permalink / raw)
  To: u-boot

On 5 March 2015 at 12:25, Simon Glass <sjg@chromium.org> wrote:
> Add a convenience function to access the private data that a uclass stores
> for each of its devices. Convert over most existing uses for consistency
> and to provide an example for others.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  common/cmd_sf.c                |  2 +-
>  common/cros_ec.c               |  2 +-
>  drivers/core/device.c          | 10 ++++++++++
>  drivers/gpio/at91_gpio.c       |  2 +-
>  drivers/gpio/bcm2835_gpio.c    |  2 +-
>  drivers/gpio/gpio-uclass.c     | 22 +++++++++++-----------
>  drivers/gpio/intel_ich6_gpio.c |  2 +-
>  drivers/gpio/mxc_gpio.c        |  2 +-
>  drivers/gpio/omap_gpio.c       |  2 +-
>  drivers/gpio/s5p_gpio.c        |  2 +-
>  drivers/gpio/sandbox.c         |  6 +++---
>  drivers/gpio/sunxi_gpio.c      |  2 +-
>  drivers/gpio/tegra_gpio.c      |  2 +-
>  drivers/i2c/i2c-uclass.c       |  6 +++---
>  drivers/i2c/sandbox_i2c.c      |  2 +-
>  drivers/misc/cros_ec.c         |  6 +++---
>  drivers/misc/cros_ec_i2c.c     |  2 +-
>  drivers/misc/cros_ec_sandbox.c |  2 +-
>  drivers/misc/cros_ec_spi.c     |  4 ++--
>  drivers/mtd/spi/sf-uclass.c    |  2 +-
>  drivers/mtd/spi/sf_probe.c     |  8 ++++----
>  drivers/serial/serial-uclass.c |  4 ++--
>  drivers/spi/spi-uclass.c       |  4 ++--
>  include/dm/device.h            | 10 ++++++++++
>  include/i2c.h                  |  8 ++++----
>  test/dm/core.c                 |  2 +-
>  test/dm/test-uclass.c          |  4 ++--
>  27 files changed, 71 insertions(+), 51 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 09/22] dm: core: Mark device as active before calling its probe() method
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 09/22] dm: core: Mark device as active before calling its probe() method Simon Glass
@ 2015-03-20 23:15   ` Simon Glass
  0 siblings, 0 replies; 53+ messages in thread
From: Simon Glass @ 2015-03-20 23:15 UTC (permalink / raw)
  To: u-boot

On 5 March 2015 at 12:25, Simon Glass <sjg@chromium.org> wrote:
> At present the device is not active when the probe() method is called. But
> some probe() methods want to set up the device and this can involve
> accessing it through normal methods. For example a PCI bus may wish to
> set up its PCI parameters using calls to pci_hose_write_config_dword() and
> similar.
>
> At present this does not work because every such call within the probe()
> method sees that the device is not active and attempts to probe it.
>
> Already we mark the device as probed before calling the uclass post_probe()
> method. This is a subtle change but I believe the new approach is better.
> Since the scope of the change is only the probe() method and all its callees
> it should still be within the control of the board author.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/core/device.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 10/22] dm: core: Add a uclass pre_probe() method for devices
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 10/22] dm: core: Add a uclass pre_probe() method for devices Simon Glass
@ 2015-03-20 23:15   ` Simon Glass
  0 siblings, 0 replies; 53+ messages in thread
From: Simon Glass @ 2015-03-20 23:15 UTC (permalink / raw)
  To: u-boot

On 5 March 2015 at 12:25, Simon Glass <sjg@chromium.org> wrote:
> Some uclasses want to set up a device before it is probed. Add a method
> for this.
>
> An example is with PCI, where a PCI uclass wants to set up its private
> data for later use. This allows the device's uclass() method to make calls
> whcih use that data (for example, read PCI memory regions from device
> tree, set up bus numbers).
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 11/22] dm: Show both allocated and requested seq numbers in 'dm uclass'
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 11/22] dm: Show both allocated and requested seq numbers in 'dm uclass' Simon Glass
@ 2015-03-20 23:16   ` Simon Glass
  0 siblings, 0 replies; 53+ messages in thread
From: Simon Glass @ 2015-03-20 23:16 UTC (permalink / raw)
  To: u-boot

On 5 March 2015 at 12:25, Simon Glass <sjg@chromium.org> wrote:
> Both of these values are useful for understanding what is going on, so show
> them both.
>
> The requested number comes from a device tree alias. The allocated one is
> set up when the device is activated, and is unique throughout the uclass.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  test/dm/cmd_dm.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 12/22] dm: pci: Move common PCI functions into their own file
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 12/22] dm: pci: Move common PCI functions into their own file Simon Glass
@ 2015-03-20 23:16   ` Simon Glass
  0 siblings, 0 replies; 53+ messages in thread
From: Simon Glass @ 2015-03-20 23:16 UTC (permalink / raw)
  To: u-boot

On 5 March 2015 at 12:25, Simon Glass <sjg@chromium.org> wrote:
> Driver model will share many functions with the existing PCI implementation.
> Move these into their own file to avoid duplication and confusion.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/pci/Makefile     |   2 +-
>  drivers/pci/pci.c        | 281 +--------------------------------------------
>  drivers/pci/pci_common.c | 292 +++++++++++++++++++++++++++++++++++++++++++++++
>  include/pci.h            |  14 +++
>  4 files changed, 313 insertions(+), 276 deletions(-)
>  create mode 100644 drivers/pci/pci_common.c

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 13/22] dm: pci: Add a uclass for PCI
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 13/22] dm: pci: Add a uclass for PCI Simon Glass
@ 2015-03-20 23:16   ` Simon Glass
  0 siblings, 0 replies; 53+ messages in thread
From: Simon Glass @ 2015-03-20 23:16 UTC (permalink / raw)
  To: u-boot

On 5 March 2015 at 12:25, Simon Glass <sjg@chromium.org> wrote:
> Add a uclass for PCI controllers and a generic one for PCI devices. Adjust
> the 'pci' command and the existing PCI support to work with this new uclass.
> Keep most of the compatibility code in a separate file so that it can be
> removed one day.
>
> TODO: Add more header file comments to the new parts of pci.h
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  common/board_r.c              |   2 +
>  common/cmd_pci.c              |  14 +-
>  doc/driver-model/pci-info.txt |  70 +++++
>  drivers/pci/Kconfig           |  12 +
>  drivers/pci/Makefile          |   8 +-
>  drivers/pci/pci-uclass.c      | 639 ++++++++++++++++++++++++++++++++++++++++++
>  drivers/pci/pci_auto.c        |  16 +-
>  drivers/pci/pci_compat.c      |  43 +++
>  include/dm/uclass-id.h        |   2 +
>  include/pci.h                 | 289 ++++++++++++++++++-
>  10 files changed, 1081 insertions(+), 14 deletions(-)
>  create mode 100644 doc/driver-model/pci-info.txt
>  create mode 100644 drivers/pci/pci-uclass.c
>  create mode 100644 drivers/pci/pci_compat.c

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 14/22] dm: sandbox: pci: Add PCI support for sandbox
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 14/22] dm: sandbox: pci: Add PCI support for sandbox Simon Glass
@ 2015-03-20 23:16   ` Simon Glass
  0 siblings, 0 replies; 53+ messages in thread
From: Simon Glass @ 2015-03-20 23:16 UTC (permalink / raw)
  To: u-boot

On 5 March 2015 at 12:25, Simon Glass <sjg@chromium.org> wrote:
> Add the required header information, device tree nodes and I/O accessor
> functions to support PCI on sandbox. All devices are emulated by drivers
> which can be added as required for testing or development.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 15/22] dm: sandbox: Add a simple PCI driver
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 15/22] dm: sandbox: Add a simple PCI driver Simon Glass
@ 2015-03-20 23:16   ` Simon Glass
  0 siblings, 0 replies; 53+ messages in thread
From: Simon Glass @ 2015-03-20 23:16 UTC (permalink / raw)
  To: u-boot

On 5 March 2015 at 12:25, Simon Glass <sjg@chromium.org> wrote:
> Add a driver which can access emulations of devices and make them available
> in sandbox.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/pci/Kconfig       | 10 ++++++
>  drivers/pci/Makefile      |  1 +
>  drivers/pci/pci_sandbox.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 90 insertions(+)
>  create mode 100644 drivers/pci/pci_sandbox.c

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 16/22] dm: sandbox: pci: Add a PCI emulation uclass
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 16/22] dm: sandbox: pci: Add a PCI emulation uclass Simon Glass
@ 2015-03-20 23:16   ` Simon Glass
  0 siblings, 0 replies; 53+ messages in thread
From: Simon Glass @ 2015-03-20 23:16 UTC (permalink / raw)
  To: u-boot

On 5 March 2015 at 12:25, Simon Glass <sjg@chromium.org> wrote:
> Since sandbox does not have real devices (unless it borrows those from the
> host) it must use emulations. Provide a uclass which permits PCI operations
> to be passed through to an emulation device.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/pci/Makefile          |   1 +
>  drivers/pci/pci-emul-uclass.c |  67 ++++++++++++++++++++++++++
>  include/dm/uclass-id.h        |   1 +
>  include/pci.h                 | 108 ++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 177 insertions(+)
>  create mode 100644 drivers/pci/pci-emul-uclass.c

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 17/22] dm: sandbox: Add a emulated PCI device as an example
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 17/22] dm: sandbox: Add a emulated PCI device as an example Simon Glass
@ 2015-03-20 23:16   ` Simon Glass
  0 siblings, 0 replies; 53+ messages in thread
From: Simon Glass @ 2015-03-20 23:16 UTC (permalink / raw)
  To: u-boot

On 5 March 2015 at 12:25, Simon Glass <sjg@chromium.org> wrote:
> This device sits on the sandbox PCI bus and provides a case-swapping
> service for sandbox. It illustrates the use of both PCI I/O and PCI
> memory accesses.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  drivers/misc/Makefile    |   1 +
>  drivers/misc/swap_case.c | 285 +++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 286 insertions(+)
>  create mode 100644 drivers/misc/swap_case.c

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 18/22] dm: sandbox: pci: Enable PCI for sandbox
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 18/22] dm: sandbox: pci: Enable PCI for sandbox Simon Glass
@ 2015-03-20 23:16   ` Simon Glass
  0 siblings, 0 replies; 53+ messages in thread
From: Simon Glass @ 2015-03-20 23:16 UTC (permalink / raw)
  To: u-boot

On 5 March 2015 at 12:25, Simon Glass <sjg@chromium.org> wrote:
> Enable PCI options so that sandbox can be used for testing this bus with
> driver model.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  configs/sandbox_defconfig | 3 +++
>  include/configs/sandbox.h | 4 ++++
>  2 files changed, 7 insertions(+)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 19/22] dm: x86: pci: Add a PCI driver for driver model
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 19/22] dm: x86: pci: Add a PCI driver for driver model Simon Glass
@ 2015-03-20 23:16   ` Simon Glass
  0 siblings, 0 replies; 53+ messages in thread
From: Simon Glass @ 2015-03-20 23:16 UTC (permalink / raw)
  To: u-boot

On 5 March 2015 at 12:25, Simon Glass <sjg@chromium.org> wrote:
> Add a simple x86 PCI driver which uses standard functions provided by the
> architecture.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  arch/x86/cpu/pci.c         | 40 ++++++++++++++++++++++++++++++++++++++++
>  arch/x86/include/asm/pci.h |  8 ++++++++
>  arch/x86/lib/Makefile      |  2 ++
>  drivers/pci/Makefile       |  1 +
>  drivers/pci/pci_x86.c      | 24 ++++++++++++++++++++++++
>  5 files changed, 75 insertions(+)
>  create mode 100644 drivers/pci/pci_x86.c

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 20/22] dm: x86: pci: Convert coreboot to use driver model for pci
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 20/22] dm: x86: pci: Convert coreboot to use driver model for pci Simon Glass
@ 2015-03-20 23:16   ` Simon Glass
  0 siblings, 0 replies; 53+ messages in thread
From: Simon Glass @ 2015-03-20 23:16 UTC (permalink / raw)
  To: u-boot

On 5 March 2015 at 12:25, Simon Glass <sjg@chromium.org> wrote:
> Move coreboot-x86 over to driver model for PCI.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  arch/x86/cpu/coreboot/pci.c         | 63 ++++++++++---------------------------
>  arch/x86/dts/chromebook_link.dts    |  7 +++++
>  board/google/chromebook_link/link.c |  9 ++++++
>  configs/coreboot-x86_defconfig      |  1 +
>  include/dm/uclass-id.h              |  1 +
>  5 files changed, 34 insertions(+), 47 deletions(-)

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 21/22] dm: x86: pci: Convert chromebook_link to use driver model for pci
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 21/22] dm: x86: pci: Convert chromebook_link " Simon Glass
@ 2015-03-20 23:16   ` Simon Glass
  0 siblings, 0 replies; 53+ messages in thread
From: Simon Glass @ 2015-03-20 23:16 UTC (permalink / raw)
  To: u-boot

On 5 March 2015 at 12:25, Simon Glass <sjg@chromium.org> wrote:
> Move chromebook_link over to driver model for PCI.
>
> This involves:
> - adding a uclass for platform controller hub
> - removing most of the existing PCI driver
> - adjusting how CPU init works to use driver model instead
> - rename the lpc compatible string (it will be removed later)
>
> This does not really take advantage of driver model fully, but it does work.
> Furture work will improve the code structure to remove many of the explicit
> calls to init the board.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 53+ messages in thread

* [U-Boot] [PATCH v2 22/22] dm: pci: Add driver model tests for PCI
  2015-03-05 19:25 ` [U-Boot] [PATCH v2 22/22] dm: pci: Add driver model tests for PCI Simon Glass
@ 2015-03-20 23:16   ` Simon Glass
  0 siblings, 0 replies; 53+ messages in thread
From: Simon Glass @ 2015-03-20 23:16 UTC (permalink / raw)
  To: u-boot

On 5 March 2015 at 12:25, Simon Glass <sjg@chromium.org> wrote:
> Add some basic tests to check that things work as expected with sandbox.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  test/dm/Makefile |  1 +
>  test/dm/pci.c    | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  test/dm/test.dts | 17 ++++++++++++++++
>  3 files changed, 77 insertions(+)
>  create mode 100644 test/dm/pci.c

Applied to u-boot-dm/next.

^ permalink raw reply	[flat|nested] 53+ messages in thread

end of thread, other threads:[~2015-03-20 23:16 UTC | newest]

Thread overview: 53+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-05 19:25 [U-Boot] [PATCH v2 0/22] Add driver model support for PCI Simon Glass
2015-03-05 19:25 ` [U-Boot] [PATCH v2 01/22] sandbox: Update device tree 'reg' properties for I2C and SPI Simon Glass
2015-03-09  8:57   ` Bin Meng
2015-03-20 23:13     ` Simon Glass
2015-03-05 19:25 ` [U-Boot] [PATCH v2 02/22] fdt: Export fdtdec_get_number() for general use Simon Glass
2015-03-06 15:43   ` Tom Rini
2015-03-20 23:14     ` Simon Glass
2015-03-05 19:25 ` [U-Boot] [PATCH v2 03/22] x86: Add a x86_ prefix to the x86-specific PCI functions Simon Glass
2015-03-20 23:14   ` Simon Glass
2015-03-05 19:25 ` [U-Boot] [PATCH v2 04/22] dm: Add a new CPU init function which can use driver model Simon Glass
2015-03-09  9:02   ` Bin Meng
2015-03-20 23:14     ` Simon Glass
2015-03-05 19:25 ` [U-Boot] [PATCH v2 05/22] x86: Split up arch_cpu_init() Simon Glass
2015-03-09  9:06   ` Bin Meng
2015-03-20 23:14     ` Simon Glass
2015-03-05 19:25 ` [U-Boot] [PATCH v2 06/22] Correct map_sysmem() logic in do_mem_mw() Simon Glass
2015-03-09  9:06   ` Bin Meng
2015-03-20 23:14     ` Simon Glass
2015-03-05 19:25 ` [U-Boot] [PATCH v2 07/22] fdt: Tighten up error handling in fdtdec_get_pci_addr() Simon Glass
2015-03-06 15:43   ` Tom Rini
2015-03-09  9:09   ` Bin Meng
2015-03-20 23:14     ` Simon Glass
2015-03-05 19:25 ` [U-Boot] [PATCH v2 08/22] dm: core: Add dev_get_uclass_priv() to access uclass private data Simon Glass
2015-03-20 23:15   ` Simon Glass
2015-03-05 19:25 ` [U-Boot] [PATCH v2 09/22] dm: core: Mark device as active before calling its probe() method Simon Glass
2015-03-20 23:15   ` Simon Glass
2015-03-05 19:25 ` [U-Boot] [PATCH v2 10/22] dm: core: Add a uclass pre_probe() method for devices Simon Glass
2015-03-20 23:15   ` Simon Glass
2015-03-05 19:25 ` [U-Boot] [PATCH v2 11/22] dm: Show both allocated and requested seq numbers in 'dm uclass' Simon Glass
2015-03-20 23:16   ` Simon Glass
2015-03-05 19:25 ` [U-Boot] [PATCH v2 12/22] dm: pci: Move common PCI functions into their own file Simon Glass
2015-03-20 23:16   ` Simon Glass
2015-03-05 19:25 ` [U-Boot] [PATCH v2 13/22] dm: pci: Add a uclass for PCI Simon Glass
2015-03-20 23:16   ` Simon Glass
2015-03-05 19:25 ` [U-Boot] [PATCH v2 14/22] dm: sandbox: pci: Add PCI support for sandbox Simon Glass
2015-03-20 23:16   ` Simon Glass
2015-03-05 19:25 ` [U-Boot] [PATCH v2 15/22] dm: sandbox: Add a simple PCI driver Simon Glass
2015-03-20 23:16   ` Simon Glass
2015-03-05 19:25 ` [U-Boot] [PATCH v2 16/22] dm: sandbox: pci: Add a PCI emulation uclass Simon Glass
2015-03-20 23:16   ` Simon Glass
2015-03-05 19:25 ` [U-Boot] [PATCH v2 17/22] dm: sandbox: Add a emulated PCI device as an example Simon Glass
2015-03-20 23:16   ` Simon Glass
2015-03-05 19:25 ` [U-Boot] [PATCH v2 18/22] dm: sandbox: pci: Enable PCI for sandbox Simon Glass
2015-03-20 23:16   ` Simon Glass
2015-03-05 19:25 ` [U-Boot] [PATCH v2 19/22] dm: x86: pci: Add a PCI driver for driver model Simon Glass
2015-03-20 23:16   ` Simon Glass
2015-03-05 19:25 ` [U-Boot] [PATCH v2 20/22] dm: x86: pci: Convert coreboot to use driver model for pci Simon Glass
2015-03-20 23:16   ` Simon Glass
2015-03-05 19:25 ` [U-Boot] [PATCH v2 21/22] dm: x86: pci: Convert chromebook_link " Simon Glass
2015-03-20 23:16   ` Simon Glass
2015-03-05 19:25 ` [U-Boot] [PATCH v2 22/22] dm: pci: Add driver model tests for PCI Simon Glass
2015-03-20 23:16   ` Simon Glass
2015-03-20 23:13 ` [U-Boot] [PATCH v2 0/22] Add driver model support " Simon Glass

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.