
Hi Tuomas,
On Wed, Sep 20, 2017 at 4:18 AM, Tuomas Tynkkynen tuomas.tynkkynen@iki.fi wrote:
This sort of pattern for implementing memory-mapped PCI config space accesses appears in U-Boot twice already, and a third user is coming up. So add helper functions to avoid code duplication, similar to how Linux has pci_generic_config_write and pci_generic_config_read.
Signed-off-by: Tuomas Tynkkynen tuomas.tynkkynen@iki.fi
drivers/pci/pci-uclass.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++ include/pci.h | 51 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+)
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 86df141d60..5a24eb6428 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -518,6 +518,64 @@ int pci_auto_config_devices(struct udevice *bus) return sub_bus; }
+int pci_generic_mmap_write_config(
struct udevice *bus,
int (*addr_f)(struct udevice *bus, pci_dev_t bdf, uint offset, void **addrp),
pci_dev_t bdf,
uint offset,
ulong value,
enum pci_size_t size)
+{
void *address;
if (addr_f(bus, bdf, offset, &address) < 0)
return 0;
switch (size) {
case PCI_SIZE_8:
writeb(value, address);
return 0;
case PCI_SIZE_16:
writew(value, address);
return 0;
case PCI_SIZE_32:
writel(value, address);
return 0;
default:
return -EINVAL;
}
+}
+int pci_generic_mmap_read_config(
struct udevice *bus,
int (*addr_f)(struct udevice *bus, pci_dev_t bdf, uint offset, void **addrp),
pci_dev_t bdf,
uint offset,
ulong *valuep,
enum pci_size_t size)
+{
void *address;
if (addr_f(bus, bdf, offset, &address) < 0) {
*valuep = pci_get_ff(size);
return 0;
}
switch (size) {
case PCI_SIZE_8:
*valuep = readb(address);
return 0;
case PCI_SIZE_16:
*valuep = readw(address);
return 0;
case PCI_SIZE_32:
*valuep = readl(address);
return 0;
default:
return -EINVAL;
}
+}
int dm_pci_hose_probe_bus(struct udevice *bus) { int sub_bus; diff --git a/include/pci.h b/include/pci.h index c8ef997d0d..7adc04301c 100644 --- a/include/pci.h +++ b/include/pci.h @@ -1086,6 +1086,57 @@ int pci_read_config32(pci_dev_t pcidev, int offset, u32 *valuep); int pci_read_config16(pci_dev_t pcidev, int offset, u16 *valuep); int pci_read_config8(pci_dev_t pcidev, int offset, u8 *valuep);
+/**
- pci_generic_mmap_write_config() - Generic helper for writing to
- memory-mapped PCI configuration space.
nits: suggest adding one blank line here.
- @bus: Pointer to the PCI bus
- @addr_f: Callback for calculating the config space address
- @bdf: Identifies the PCI device to access
- @offset: The offset into the device's configuration space
- @value: The value to write
- @size: Indicates the size of access to perform
- Write the value @value of size @size from offset @offset within the
- configuration space of the device identified by the bus, device & function
- numbers in @bdf on the PCI bus @bus. The callback function @addr_f is
- responsible for calculating the CPU address of the respective configuration
- space offset.
- Return: 0 on success, else -EINVAL
- */
+int pci_generic_mmap_write_config(
struct udevice *bus,
int (*addr_f)(struct udevice *bus, pci_dev_t bdf, uint offset, void **addrp),
pci_dev_t bdf,
uint offset,
ulong value,
enum pci_size_t size);
+/**
- pci_generic_mmap_read_config() - Generic helper for reading from
- memory-mapped PCI configuration space.
nits: suggest adding one blank line here.
- @bus: Pointer to the PCI bus
- @addr_f: Callback for calculating the config space address
- @bdf: Identifies the PCI device to access
- @offset: The offset into the device's configuration space
- @valuep: A pointer at which to store the read value
- @size: Indicates the size of access to perform
- Read a value of size @size from offset @offset within the configuration
- space of the device identified by the bus, device & function numbers in @bdf
- on the PCI bus @bus. The callback function @addr_f is responsible for
- calculating the CPU address of the respective configuration space offset.
- Return: 0 on success, else -EINVAL
- */
+int pci_generic_mmap_read_config(
struct udevice *bus,
int (*addr_f)(struct udevice *bus, pci_dev_t bdf, uint offset, void **addrp),
pci_dev_t bdf,
uint offset,
ulong *valuep,
enum pci_size_t size);
#ifdef CONFIG_DM_PCI_COMPAT /* Compatibility with old naming */ static inline int pci_write_config_dword(pci_dev_t pcidev, int offset, --
Other than above nits:
Reviewed-by: Bin Meng bmeng.cn@gmail.com
Regards, Bin