fdt: allow fdtdec_get_addr_size_*() to translate addresses
Some code may want to read reg values from DT, but from nodes that aren't associated with DM devices, so using dev_get_addr_index() isn't appropriate. In this case, fdtdec_get_addr_size_*() are the functions to use. However, "translation" (via the chain of ranges properties in parent nodes) may still be desirable. Add a function parameter to request that, and implement it. Update all call sites to default to the original behaviour. Signed-off-by: Stephen Warren <swarren@nvidia.com> Reviewed-by: Simon Glass <sjg@chromium.org> Squashed in build fix from Stephen: Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
committed by
Simon Glass
parent
11e44fc6bd
commit
6e06acb732
@@ -671,7 +671,7 @@ fdt_addr_t dev_get_addr_index(struct udevice *dev, int index)
|
|||||||
addr = fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
|
addr = fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
|
||||||
dev->parent->of_offset,
|
dev->parent->of_offset,
|
||||||
dev->of_offset, "reg",
|
dev->of_offset, "reg",
|
||||||
index, NULL);
|
index, NULL, false);
|
||||||
if (CONFIG_IS_ENABLED(SIMPLE_BUS) && addr != FDT_ADDR_T_NONE) {
|
if (CONFIG_IS_ENABLED(SIMPLE_BUS) && addr != FDT_ADDR_T_NONE) {
|
||||||
if (device_get_uclass_id(dev->parent) ==
|
if (device_get_uclass_id(dev->parent) ==
|
||||||
UCLASS_SIMPLE_BUS)
|
UCLASS_SIMPLE_BUS)
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ static int mpc85xx_gpio_ofdata_to_platdata(struct udevice *dev) {
|
|||||||
fdt_size_t size;
|
fdt_size_t size;
|
||||||
|
|
||||||
addr = fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, dev->of_offset,
|
addr = fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, dev->of_offset,
|
||||||
"reg", 0, &size);
|
"reg", 0, &size, false);
|
||||||
|
|
||||||
plat->addr = addr;
|
plat->addr = addr;
|
||||||
plat->size = size;
|
plat->size = size;
|
||||||
|
|||||||
@@ -587,7 +587,7 @@ static int fsl_i2c_ofdata_to_platdata(struct udevice *bus)
|
|||||||
fdt_size_t size;
|
fdt_size_t size;
|
||||||
|
|
||||||
addr = fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, bus->of_offset,
|
addr = fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, bus->of_offset,
|
||||||
"reg", 0, &size);
|
"reg", 0, &size, false);
|
||||||
|
|
||||||
dev->base = map_sysmem(CONFIG_SYS_IMMR + addr, size);
|
dev->base = map_sysmem(CONFIG_SYS_IMMR + addr, size);
|
||||||
|
|
||||||
|
|||||||
@@ -178,7 +178,8 @@ static int msm_ofdata_to_platdata(struct udevice *dev)
|
|||||||
priv->base = (void *)fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
|
priv->base = (void *)fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
|
||||||
parent->of_offset,
|
parent->of_offset,
|
||||||
dev->of_offset,
|
dev->of_offset,
|
||||||
"reg", 1, NULL);
|
"reg", 1, NULL,
|
||||||
|
false);
|
||||||
if (priv->base == (void *)FDT_ADDR_T_NONE ||
|
if (priv->base == (void *)FDT_ADDR_T_NONE ||
|
||||||
host->ioaddr == (void *)FDT_ADDR_T_NONE)
|
host->ioaddr == (void *)FDT_ADDR_T_NONE)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|||||||
@@ -1146,7 +1146,8 @@ static const struct eth_ops cpsw_eth_ops = {
|
|||||||
|
|
||||||
static inline fdt_addr_t cpsw_get_addr_by_node(const void *fdt, int node)
|
static inline fdt_addr_t cpsw_get_addr_by_node(const void *fdt, int node)
|
||||||
{
|
{
|
||||||
return fdtdec_get_addr_size_auto_noparent(fdt, node, "reg", 0, NULL);
|
return fdtdec_get_addr_size_auto_noparent(fdt, node, "reg", 0, NULL,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
|
static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
|
||||||
|
|||||||
@@ -153,11 +153,12 @@ static int msm_spmi_probe(struct udevice *dev)
|
|||||||
priv->spmi_core = fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
|
priv->spmi_core = fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
|
||||||
parent->of_offset,
|
parent->of_offset,
|
||||||
dev->of_offset,
|
dev->of_offset,
|
||||||
"reg", 1, NULL);
|
"reg", 1, NULL,
|
||||||
|
false);
|
||||||
priv->spmi_obs = fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
|
priv->spmi_obs = fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
|
||||||
parent->of_offset,
|
parent->of_offset,
|
||||||
dev->of_offset, "reg",
|
dev->of_offset, "reg",
|
||||||
2, NULL);
|
2, NULL, false);
|
||||||
if (priv->arb_chnl == FDT_ADDR_T_NONE ||
|
if (priv->arb_chnl == FDT_ADDR_T_NONE ||
|
||||||
priv->spmi_core == FDT_ADDR_T_NONE ||
|
priv->spmi_core == FDT_ADDR_T_NONE ||
|
||||||
priv->spmi_obs == FDT_ADDR_T_NONE)
|
priv->spmi_obs == FDT_ADDR_T_NONE)
|
||||||
|
|||||||
@@ -297,11 +297,13 @@ int fdtdec_next_compatible_subnode(const void *blob, int node,
|
|||||||
* @param na the number of cells used to represent an address
|
* @param na the number of cells used to represent an address
|
||||||
* @param ns the number of cells used to represent a size
|
* @param ns the number of cells used to represent a size
|
||||||
* @param sizep a pointer to store the size into. Use NULL if not required
|
* @param sizep a pointer to store the size into. Use NULL if not required
|
||||||
|
* @param translate Indicates whether to translate the returned value
|
||||||
|
* using the parent node's ranges property.
|
||||||
* @return address, if found, or FDT_ADDR_T_NONE if not
|
* @return address, if found, or FDT_ADDR_T_NONE if not
|
||||||
*/
|
*/
|
||||||
fdt_addr_t fdtdec_get_addr_size_fixed(const void *blob, int node,
|
fdt_addr_t fdtdec_get_addr_size_fixed(const void *blob, int node,
|
||||||
const char *prop_name, int index, int na, int ns,
|
const char *prop_name, int index, int na, int ns,
|
||||||
fdt_size_t *sizep);
|
fdt_size_t *sizep, bool translate);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Look up an address property in a node and return the parsed address, and
|
* Look up an address property in a node and return the parsed address, and
|
||||||
@@ -317,10 +319,13 @@ fdt_addr_t fdtdec_get_addr_size_fixed(const void *blob, int node,
|
|||||||
* @param prop_name name of property to find
|
* @param prop_name name of property to find
|
||||||
* @param index which address to retrieve from a list of addresses. Often 0.
|
* @param index which address to retrieve from a list of addresses. Often 0.
|
||||||
* @param sizep a pointer to store the size into. Use NULL if not required
|
* @param sizep a pointer to store the size into. Use NULL if not required
|
||||||
|
* @param translate Indicates whether to translate the returned value
|
||||||
|
* using the parent node's ranges property.
|
||||||
* @return address, if found, or FDT_ADDR_T_NONE if not
|
* @return address, if found, or FDT_ADDR_T_NONE if not
|
||||||
*/
|
*/
|
||||||
fdt_addr_t fdtdec_get_addr_size_auto_parent(const void *blob, int parent,
|
fdt_addr_t fdtdec_get_addr_size_auto_parent(const void *blob, int parent,
|
||||||
int node, const char *prop_name, int index, fdt_size_t *sizep);
|
int node, const char *prop_name, int index, fdt_size_t *sizep,
|
||||||
|
bool translate);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Look up an address property in a node and return the parsed address, and
|
* Look up an address property in a node and return the parsed address, and
|
||||||
@@ -340,10 +345,13 @@ fdt_addr_t fdtdec_get_addr_size_auto_parent(const void *blob, int parent,
|
|||||||
* @param prop_name name of property to find
|
* @param prop_name name of property to find
|
||||||
* @param index which address to retrieve from a list of addresses. Often 0.
|
* @param index which address to retrieve from a list of addresses. Often 0.
|
||||||
* @param sizep a pointer to store the size into. Use NULL if not required
|
* @param sizep a pointer to store the size into. Use NULL if not required
|
||||||
|
* @param translate Indicates whether to translate the returned value
|
||||||
|
* using the parent node's ranges property.
|
||||||
* @return address, if found, or FDT_ADDR_T_NONE if not
|
* @return address, if found, or FDT_ADDR_T_NONE if not
|
||||||
*/
|
*/
|
||||||
fdt_addr_t fdtdec_get_addr_size_auto_noparent(const void *blob, int node,
|
fdt_addr_t fdtdec_get_addr_size_auto_noparent(const void *blob, int node,
|
||||||
const char *prop_name, int index, fdt_size_t *sizep);
|
const char *prop_name, int index, fdt_size_t *sizep,
|
||||||
|
bool translate);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Look up an address property in a node and return the parsed address.
|
* Look up an address property in a node and return the parsed address.
|
||||||
|
|||||||
22
lib/fdtdec.c
22
lib/fdtdec.c
@@ -9,6 +9,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <serial.h>
|
#include <serial.h>
|
||||||
#include <libfdt.h>
|
#include <libfdt.h>
|
||||||
|
#include <fdt_support.h>
|
||||||
#include <fdtdec.h>
|
#include <fdtdec.h>
|
||||||
#include <asm/sections.h>
|
#include <asm/sections.h>
|
||||||
#include <linux/ctype.h>
|
#include <linux/ctype.h>
|
||||||
@@ -77,7 +78,7 @@ const char *fdtdec_get_compatible(enum fdt_compat_id id)
|
|||||||
|
|
||||||
fdt_addr_t fdtdec_get_addr_size_fixed(const void *blob, int node,
|
fdt_addr_t fdtdec_get_addr_size_fixed(const void *blob, int node,
|
||||||
const char *prop_name, int index, int na, int ns,
|
const char *prop_name, int index, int na, int ns,
|
||||||
fdt_size_t *sizep)
|
fdt_size_t *sizep, bool translate)
|
||||||
{
|
{
|
||||||
const fdt32_t *prop, *prop_end;
|
const fdt32_t *prop, *prop_end;
|
||||||
const fdt32_t *prop_addr, *prop_size, *prop_after_size;
|
const fdt32_t *prop_addr, *prop_size, *prop_after_size;
|
||||||
@@ -112,7 +113,12 @@ fdt_addr_t fdtdec_get_addr_size_fixed(const void *blob, int node,
|
|||||||
return FDT_ADDR_T_NONE;
|
return FDT_ADDR_T_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr = fdtdec_get_number(prop_addr, na);
|
#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_OF_LIBFDT)
|
||||||
|
if (translate)
|
||||||
|
addr = fdt_translate_address(blob, node, prop_addr);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
addr = fdtdec_get_number(prop_addr, na);
|
||||||
|
|
||||||
if (sizep) {
|
if (sizep) {
|
||||||
*sizep = fdtdec_get_number(prop_size, ns);
|
*sizep = fdtdec_get_number(prop_size, ns);
|
||||||
@@ -126,7 +132,8 @@ fdt_addr_t fdtdec_get_addr_size_fixed(const void *blob, int node,
|
|||||||
}
|
}
|
||||||
|
|
||||||
fdt_addr_t fdtdec_get_addr_size_auto_parent(const void *blob, int parent,
|
fdt_addr_t fdtdec_get_addr_size_auto_parent(const void *blob, int parent,
|
||||||
int node, const char *prop_name, int index, fdt_size_t *sizep)
|
int node, const char *prop_name, int index, fdt_size_t *sizep,
|
||||||
|
bool translate)
|
||||||
{
|
{
|
||||||
int na, ns;
|
int na, ns;
|
||||||
|
|
||||||
@@ -147,11 +154,12 @@ fdt_addr_t fdtdec_get_addr_size_auto_parent(const void *blob, int parent,
|
|||||||
debug("na=%d, ns=%d, ", na, ns);
|
debug("na=%d, ns=%d, ", na, ns);
|
||||||
|
|
||||||
return fdtdec_get_addr_size_fixed(blob, node, prop_name, index, na,
|
return fdtdec_get_addr_size_fixed(blob, node, prop_name, index, na,
|
||||||
ns, sizep);
|
ns, sizep, translate);
|
||||||
}
|
}
|
||||||
|
|
||||||
fdt_addr_t fdtdec_get_addr_size_auto_noparent(const void *blob, int node,
|
fdt_addr_t fdtdec_get_addr_size_auto_noparent(const void *blob, int node,
|
||||||
const char *prop_name, int index, fdt_size_t *sizep)
|
const char *prop_name, int index, fdt_size_t *sizep,
|
||||||
|
bool translate)
|
||||||
{
|
{
|
||||||
int parent;
|
int parent;
|
||||||
|
|
||||||
@@ -164,7 +172,7 @@ fdt_addr_t fdtdec_get_addr_size_auto_noparent(const void *blob, int node,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return fdtdec_get_addr_size_auto_parent(blob, parent, node, prop_name,
|
return fdtdec_get_addr_size_auto_parent(blob, parent, node, prop_name,
|
||||||
index, sizep);
|
index, sizep, translate);
|
||||||
}
|
}
|
||||||
|
|
||||||
fdt_addr_t fdtdec_get_addr_size(const void *blob, int node,
|
fdt_addr_t fdtdec_get_addr_size(const void *blob, int node,
|
||||||
@@ -174,7 +182,7 @@ fdt_addr_t fdtdec_get_addr_size(const void *blob, int node,
|
|||||||
|
|
||||||
return fdtdec_get_addr_size_fixed(blob, node, prop_name, 0,
|
return fdtdec_get_addr_size_fixed(blob, node, prop_name, 0,
|
||||||
sizeof(fdt_addr_t) / sizeof(fdt32_t),
|
sizeof(fdt_addr_t) / sizeof(fdt32_t),
|
||||||
ns, sizep);
|
ns, sizep, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
fdt_addr_t fdtdec_get_addr(const void *blob, int node,
|
fdt_addr_t fdtdec_get_addr(const void *blob, int node,
|
||||||
|
|||||||
Reference in New Issue
Block a user