
On Mon, Nov 30, 2015 at 4:17 AM, Simon Glass sjg@chromium.org wrote:
Use the driver model version of the function to find the BAR. This updates the fdtdec function, of which ns16550 is the only user.
The fdtdec_get_pci_bdf() function is dropped for several reasons:
- with driver model we should use 'struct udevice *' rather than passing the device tree offset explicitly
- there are no other users in the tree
- the function parses for information which is already available in the PCI
device structure (specifically struct pci_child_platdata which is available at dev_get_parent_platdata(dev)
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2:
- Put this code behind CONFIG_DM_PCI to avoid PowerPC build errors
drivers/serial/ns16550.c | 5 ++--- include/fdtdec.h | 23 +++---------------- lib/fdtdec.c | 57 +++++------------------------------------------- 3 files changed, 10 insertions(+), 75 deletions(-)
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c index d5bcbc3..28259e6 100644 --- a/drivers/serial/ns16550.c +++ b/drivers/serial/ns16550.c @@ -368,7 +368,7 @@ int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
/* try Processor Local Bus device first */ addr = dev_get_addr(dev);
-#ifdef CONFIG_PCI +#if defined(CONFIG_PCI) && defined(CONFIG_DM_PCI) if (addr == FDT_ADDR_T_NONE) { /* then try pci device */ struct fdt_pci_addr pci_addr; @@ -389,8 +389,7 @@ int ns16550_serial_ofdata_to_platdata(struct udevice *dev) return ret; }
ret = fdtdec_get_pci_bar32(gd->fdt_blob, dev->of_offset,
&pci_addr, &bar);
ret = fdtdec_get_pci_bar32(dev, &pci_addr, &bar); if (ret) return ret;
diff --git a/include/fdtdec.h b/include/fdtdec.h index 7fe657d..018d151 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -444,32 +444,15 @@ int fdtdec_get_pci_vendev(const void *blob, int node,
/**
- Look at the pci address of a device node that represents a PCI device
- and parse the bus, device and function number from it. For some cases
- like the bus number encoded in reg property is not correct after pci
- enumeration, this function looks through the node's compatible strings
- to get these numbers extracted instead.
- @param blob FDT blob
- @param node node to examine
- @param addr pci address in the form of fdt_pci_addr
- @param bdf returns bus, device, function triplet
- @return 0 if ok, negative on error
- */
-int fdtdec_get_pci_bdf(const void *blob, int node,
struct fdt_pci_addr *addr, pci_dev_t *bdf);
-/**
- Look at the pci address of a device node that represents a PCI device
- and return base address of the pci device's registers.
- @param blob FDT blob
- @param node node to examine
*/
- @param dev device to examine
- @param addr pci address in the form of fdt_pci_addr
- @param bar returns base address of the pci device's registers
- @return 0 if ok, negative on error
-int fdtdec_get_pci_bar32(const void *blob, int node,
struct fdt_pci_addr *addr, u32 *bar);
+int fdtdec_get_pci_bar32(struct udevice *dev, struct fdt_pci_addr *addr,
u32 *bar);
/**
- Look up a 32-bit integer property in a node and return it. The property
diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 82d0090..f6f23ae 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -5,6 +5,7 @@
#ifndef USE_HOSTCC #include <common.h> +#include <dm.h> #include <errno.h> #include <serial.h> #include <libfdt.h> @@ -189,7 +190,7 @@ fdt_addr_t fdtdec_get_addr(const void *blob, int node, return fdtdec_get_addr_size(blob, node, prop_name, NULL); }
-#ifdef CONFIG_PCI +#if defined(CONFIG_PCI) && defined(CONFIG_DM_PCI) int fdtdec_get_pci_addr(const void *blob, int node, enum fdt_pci_space type, const char *prop_name, struct fdt_pci_addr *addr) { @@ -282,58 +283,10 @@ int fdtdec_get_pci_vendev(const void *blob, int node, u16 *vendor, u16 *device) return -ENOENT; }
-int fdtdec_get_pci_bdf(const void *blob, int node,
struct fdt_pci_addr *addr, pci_dev_t *bdf)
+int fdtdec_get_pci_bar32(struct udevice *dev, struct fdt_pci_addr *addr,
u32 *bar)
{
u16 dt_vendor, dt_device, vendor, device;
int ret;
/* get vendor id & device id from the compatible string */
ret = fdtdec_get_pci_vendev(blob, node, &dt_vendor, &dt_device);
if (ret)
return ret;
/* extract the bdf from fdt_pci_addr */
*bdf = addr->phys_hi & 0xffff00;
/* read vendor id & device id based on bdf */
pci_read_config_word(*bdf, PCI_VENDOR_ID, &vendor);
pci_read_config_word(*bdf, PCI_DEVICE_ID, &device);
/*
* Note there are two places in the device tree to fully describe
* a pci device: one is via compatible string with a format of
* "pciVVVV,DDDD" and the other one is the bdf numbers encoded in
* the device node's reg address property. We read the vendor id
* and device id based on bdf and compare the values with the
* "VVVV,DDDD". If they are the same, then we are good to use bdf
* to read device's bar. But if they are different, we have to rely
* on the vendor id and device id extracted from the compatible
* string and locate the real bdf by pci_find_device(). This is
* because normally we may only know device's device number and
* function number when writing device tree. The bus number is
* dynamically assigned during the pci enumeration process.
*/
if ((dt_vendor != vendor) || (dt_device != device)) {
*bdf = pci_find_device(dt_vendor, dt_device, 0);
if (*bdf == -1)
return -ENODEV;
}
return 0;
-}
-int fdtdec_get_pci_bar32(const void *blob, int node,
struct fdt_pci_addr *addr, u32 *bar)
-{
pci_dev_t bdf; int barnum;
int ret;
/* get pci devices's bdf */
ret = fdtdec_get_pci_bdf(blob, node, addr, &bdf);
if (ret)
return ret; /* extract the bar number from fdt_pci_addr */ barnum = addr->phys_hi & 0xff;
@@ -341,7 +294,7 @@ int fdtdec_get_pci_bar32(const void *blob, int node, return -EINVAL;
barnum = (barnum - PCI_BASE_ADDRESS_0) / 4;
*bar = pci_read_bar32(pci_bus_to_hose(PCI_BUS(bdf)), bdf, barnum);
*bar = dm_pci_read_bar32(dev, barnum); return 0;
}
Reviewed-by: Bin Meng bmeng.cn@gmail.com
With the following two patches applied to fix the PCI UART broken issue first, http://patchwork.ozlabs.org/patch/553319/ http://patchwork.ozlabs.org/patch/553385/ Tested-by: Bin Meng bmeng.cn@gmail.com