From 6e06acb73248e32457064d8fe820cbc217c45f3f Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 5 Aug 2016 09:47:51 -0600 Subject: [PATCH] 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 Reviewed-by: Simon Glass Squashed in build fix from Stephen: Signed-off-by: Simon Glass --- drivers/core/device.c | 2 +- drivers/gpio/mpc85xx_gpio.c | 2 +- drivers/i2c/fsl_i2c.c | 2 +- drivers/mmc/msm_sdhci.c | 3 ++- drivers/net/cpsw.c | 3 ++- drivers/spmi/spmi-msm.c | 5 +++-- include/fdtdec.h | 14 +++++++++++--- lib/fdtdec.c | 22 +++++++++++++++------- 8 files changed, 36 insertions(+), 17 deletions(-) diff --git a/drivers/core/device.c b/drivers/core/device.c index 5bb1d7793d..b737f1c789 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -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, dev->parent->of_offset, dev->of_offset, "reg", - index, NULL); + index, NULL, false); if (CONFIG_IS_ENABLED(SIMPLE_BUS) && addr != FDT_ADDR_T_NONE) { if (device_get_uclass_id(dev->parent) == UCLASS_SIMPLE_BUS) diff --git a/drivers/gpio/mpc85xx_gpio.c b/drivers/gpio/mpc85xx_gpio.c index 3754a8215c..168c696c4d 100644 --- a/drivers/gpio/mpc85xx_gpio.c +++ b/drivers/gpio/mpc85xx_gpio.c @@ -170,7 +170,7 @@ static int mpc85xx_gpio_ofdata_to_platdata(struct udevice *dev) { fdt_size_t size; addr = fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, dev->of_offset, - "reg", 0, &size); + "reg", 0, &size, false); plat->addr = addr; plat->size = size; diff --git a/drivers/i2c/fsl_i2c.c b/drivers/i2c/fsl_i2c.c index 407c4a7b10..c3f826d68c 100644 --- a/drivers/i2c/fsl_i2c.c +++ b/drivers/i2c/fsl_i2c.c @@ -587,7 +587,7 @@ static int fsl_i2c_ofdata_to_platdata(struct udevice *bus) fdt_size_t size; 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); diff --git a/drivers/mmc/msm_sdhci.c b/drivers/mmc/msm_sdhci.c index a8cb9e249d..8d4399e967 100644 --- a/drivers/mmc/msm_sdhci.c +++ b/drivers/mmc/msm_sdhci.c @@ -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, parent->of_offset, dev->of_offset, - "reg", 1, NULL); + "reg", 1, NULL, + false); if (priv->base == (void *)FDT_ADDR_T_NONE || host->ioaddr == (void *)FDT_ADDR_T_NONE) return -EINVAL; diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c index 774b021e35..8a2f88a095 100644 --- a/drivers/net/cpsw.c +++ b/drivers/net/cpsw.c @@ -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) { - 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) diff --git a/drivers/spmi/spmi-msm.c b/drivers/spmi/spmi-msm.c index 0cef505e37..48bc157596 100644 --- a/drivers/spmi/spmi-msm.c +++ b/drivers/spmi/spmi-msm.c @@ -153,11 +153,12 @@ static int msm_spmi_probe(struct udevice *dev) priv->spmi_core = fdtdec_get_addr_size_auto_parent(gd->fdt_blob, parent->of_offset, dev->of_offset, - "reg", 1, NULL); + "reg", 1, NULL, + false); priv->spmi_obs = fdtdec_get_addr_size_auto_parent(gd->fdt_blob, parent->of_offset, dev->of_offset, "reg", - 2, NULL); + 2, NULL, false); if (priv->arb_chnl == FDT_ADDR_T_NONE || priv->spmi_core == FDT_ADDR_T_NONE || priv->spmi_obs == FDT_ADDR_T_NONE) diff --git a/include/fdtdec.h b/include/fdtdec.h index 70ea0bfc0b..aeb6bab1c4 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -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 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 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 */ fdt_addr_t fdtdec_get_addr_size_fixed(const void *blob, int node, 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 @@ -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 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 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 */ 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 @@ -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 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 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 */ 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. diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 462a24f96a..e638ca5d6a 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -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, 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_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; } - 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) { *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, - 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; @@ -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); 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, - const char *prop_name, int index, fdt_size_t *sizep) + const char *prop_name, int index, fdt_size_t *sizep, + bool translate) { 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, - index, sizep); + index, sizep, translate); } 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, sizeof(fdt_addr_t) / sizeof(fdt32_t), - ns, sizep); + ns, sizep, false); } fdt_addr_t fdtdec_get_addr(const void *blob, int node, -- 2.39.5