dm: serial: Convert ns16550 driver to use driver model PCI API

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>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
master
Simon Glass 9 years ago
parent bab17cf143
commit fcc0a8774b
  1. 5
      drivers/serial/ns16550.c
  2. 23
      include/fdtdec.h
  3. 57
      lib/fdtdec.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;

@ -445,32 +445,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

@ -5,6 +5,7 @@
#ifndef USE_HOSTCC
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <serial.h>
#include <libfdt.h>
@ -190,7 +191,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)
{
@ -283,58 +284,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;
@ -342,7 +295,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;
}

Loading…
Cancel
Save