common: fdt_support: Support special case of PCI address in fdt_read_prop()
At present fdt_read_prop() can only handle 1 or 2 cells. It is called by fdt_read_range() which may be used to read PCI address from <ranges> for a PCI bus node where the number of PCI address cell is 3. The <ranges> property is an array of: { <child address> <parent address> <size in child address space> } When trying to read <child address> from a PCI bus node using fdt_read_prop(), as the codes below: /* Read <child address> */ if (child_addr) { r = fdt_read_prop(ranges, ranges_len, cell, child_addr, acells); if (r) return r; } it will fail, because the PCI child address is made up of 3 cells but fdt_read_prop() cannot handle it. We advance the cell offset by 1 so that the <child address> can be correctly read. This adds the special handling of such case. Signed-off-by: Bin Meng <bmeng.cn@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org> Reviewed-by: Priyanka Jain <priyanka.jain@nxp.com>
This commit is contained in:
parent
5cd1ecb994
commit
a932aa3c69
@ -1668,22 +1668,36 @@ u64 fdt_get_base_address(const void *fdt, int node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read a property of size <prop_len>. Currently only supports 1 or 2 cells.
|
* Read a property of size <prop_len>. Currently only supports 1 or 2 cells,
|
||||||
|
* or 3 cells specially for a PCI address.
|
||||||
*/
|
*/
|
||||||
static int fdt_read_prop(const fdt32_t *prop, int prop_len, int cell_off,
|
static int fdt_read_prop(const fdt32_t *prop, int prop_len, int cell_off,
|
||||||
uint64_t *val, int cells)
|
uint64_t *val, int cells)
|
||||||
{
|
{
|
||||||
const fdt32_t *prop32 = &prop[cell_off];
|
const fdt32_t *prop32;
|
||||||
const unaligned_fdt64_t *prop64 = (const fdt64_t *)&prop[cell_off];
|
const unaligned_fdt64_t *prop64;
|
||||||
|
|
||||||
if ((cell_off + cells) > prop_len)
|
if ((cell_off + cells) > prop_len)
|
||||||
return -FDT_ERR_NOSPACE;
|
return -FDT_ERR_NOSPACE;
|
||||||
|
|
||||||
|
prop32 = &prop[cell_off];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Special handling for PCI address in PCI bus <ranges>
|
||||||
|
*
|
||||||
|
* PCI child address is made up of 3 cells. Advance the cell offset
|
||||||
|
* by 1 so that the PCI child address can be correctly read.
|
||||||
|
*/
|
||||||
|
if (cells == 3)
|
||||||
|
cell_off += 1;
|
||||||
|
prop64 = (const fdt64_t *)&prop[cell_off];
|
||||||
|
|
||||||
switch (cells) {
|
switch (cells) {
|
||||||
case 1:
|
case 1:
|
||||||
*val = fdt32_to_cpu(*prop32);
|
*val = fdt32_to_cpu(*prop32);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
|
case 3:
|
||||||
*val = fdt64_to_cpu(*prop64);
|
*val = fdt64_to_cpu(*prop64);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
Loading…
Reference in New Issue
Block a user