[U-Boot] [PATCH v3 01/10] dm: pci: Provide friendly config access functions

Simon Glass sjg at chromium.org
Mon Aug 10 15:05:03 CEST 2015


At present there are no PCI functions which allow access to PCI
configuration using a struct udevice. This is a sad situation for driver
model as it makes use of PCI harder. Add these functions.

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

Changes in v3: None
Changes in v2:
- Correct 'Driver mode' typo
- Add blank line after dm_pci_read_config() declaration

 drivers/pci/pci-uclass.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/pci.h            | 18 ++++++++++++
 2 files changed, 94 insertions(+)

diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index 6262f35..b79927e 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -210,6 +210,17 @@ int pci_write_config(pci_dev_t bdf, int offset, unsigned long value,
 	return pci_bus_write_config(bus, bdf, offset, value, size);
 }
 
+int dm_pci_write_config(struct udevice *dev, int offset, unsigned long value,
+			enum pci_size_t size)
+{
+	struct udevice *bus;
+
+	for (bus = dev; device_get_uclass_id(bus->parent) == UCLASS_PCI;)
+		bus = bus->parent;
+	return pci_bus_write_config(bus, pci_get_bdf(dev), 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);
@@ -225,6 +236,21 @@ int pci_write_config8(pci_dev_t bdf, int offset, u8 value)
 	return pci_write_config(bdf, offset, value, PCI_SIZE_8);
 }
 
+int dm_pci_write_config8(struct udevice *dev, int offset, u8 value)
+{
+	return dm_pci_write_config(dev, offset, value, PCI_SIZE_8);
+}
+
+int dm_pci_write_config16(struct udevice *dev, int offset, u16 value)
+{
+	return dm_pci_write_config(dev, offset, value, PCI_SIZE_16);
+}
+
+int dm_pci_write_config32(struct udevice *dev, int offset, u32 value)
+{
+	return dm_pci_write_config(dev, offset, value, PCI_SIZE_32);
+}
+
 int pci_bus_read_config(struct udevice *bus, pci_dev_t bdf, int offset,
 			unsigned long *valuep, enum pci_size_t size)
 {
@@ -249,6 +275,17 @@ int pci_read_config(pci_dev_t bdf, int offset, unsigned long *valuep,
 	return pci_bus_read_config(bus, bdf, offset, valuep, size);
 }
 
+int dm_pci_read_config(struct udevice *dev, int offset, unsigned long *valuep,
+		       enum pci_size_t size)
+{
+	struct udevice *bus;
+
+	for (bus = dev; device_get_uclass_id(bus->parent) == UCLASS_PCI;)
+		bus = bus->parent;
+	return pci_bus_read_config(bus, pci_get_bdf(dev), offset, valuep,
+				   size);
+}
+
 int pci_read_config32(pci_dev_t bdf, int offset, u32 *valuep)
 {
 	unsigned long value;
@@ -288,6 +325,45 @@ int pci_read_config8(pci_dev_t bdf, int offset, u8 *valuep)
 	return 0;
 }
 
+int dm_pci_read_config8(struct udevice *dev, int offset, u8 *valuep)
+{
+	unsigned long value;
+	int ret;
+
+	ret = dm_pci_read_config(dev, offset, &value, PCI_SIZE_8);
+	if (ret)
+		return ret;
+	*valuep = value;
+
+	return 0;
+}
+
+int dm_pci_read_config16(struct udevice *dev, int offset, u16 *valuep)
+{
+	unsigned long value;
+	int ret;
+
+	ret = dm_pci_read_config(dev, offset, &value, PCI_SIZE_16);
+	if (ret)
+		return ret;
+	*valuep = value;
+
+	return 0;
+}
+
+int dm_pci_read_config32(struct udevice *dev, int offset, u32 *valuep)
+{
+	unsigned long value;
+	int ret;
+
+	ret = dm_pci_read_config(dev, offset, &value, PCI_SIZE_32);
+	if (ret)
+		return ret;
+	*valuep = value;
+
+	return 0;
+}
+
 int pci_auto_config_devices(struct udevice *bus)
 {
 	struct pci_controller *hose = bus->uclass_priv;
diff --git a/include/pci.h b/include/pci.h
index 628ede0..d1e2765 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -988,6 +988,24 @@ int pci_bus_read_config(struct udevice *bus, pci_dev_t bdf, int offset,
 int pci_bus_write_config(struct udevice *bus, pci_dev_t bdf, int offset,
 			 unsigned long value, enum pci_size_t size);
 
+/**
+ * Driver model PCI config access functions. Use these in preference to others
+ * when you have a valid device
+ */
+int dm_pci_read_config(struct udevice *dev, int offset, unsigned long *valuep,
+		       enum pci_size_t size);
+
+int dm_pci_read_config8(struct udevice *dev, int offset, u8 *valuep);
+int dm_pci_read_config16(struct udevice *dev, int offset, u16 *valuep);
+int dm_pci_read_config32(struct udevice *dev, int offset, u32 *valuep);
+
+int dm_pci_write_config(struct udevice *dev, int offset, unsigned long value,
+			enum pci_size_t size);
+
+int dm_pci_write_config8(struct udevice *dev, int offset, u8 value);
+int dm_pci_write_config16(struct udevice *dev, int offset, u16 value);
+int dm_pci_write_config32(struct udevice *dev, int offset, u32 value);
+
 /*
  * 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
-- 
2.5.0.rc2.392.g76e840b



More information about the U-Boot mailing list