
At present we decode simple bus <ranges> using the following assumption:
- parent #address-cells 1 - child #address-cells 1 - child #size-cells 1
However this might not always be the case.
Update to use fdt_addr_t and fdt_size_t in 'struct simple_bus_plat', and use fdt_read_ranges() to correctly decode it according to the actual parent and child #address-cells / #size-cells.
Signed-off-by: Bin Meng bmeng.cn@gmail.com ---
drivers/core/simple-bus.c | 15 ++++++++++----- include/dm/simple_bus.h | 6 +++--- 2 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/drivers/core/simple-bus.c b/drivers/core/simple-bus.c index b0c2c20958..b5863f2b2c 100644 --- a/drivers/core/simple-bus.c +++ b/drivers/core/simple-bus.c @@ -6,6 +6,9 @@ #include <common.h> #include <dm.h> #include <dm/simple_bus.h> +#include <fdt_support.h> + +DECLARE_GLOBAL_DATA_PTR;
fdt_addr_t simple_bus_translate(struct udevice *dev, fdt_addr_t addr) { @@ -22,16 +25,18 @@ static int simple_bus_post_bind(struct udevice *dev) #if CONFIG_IS_ENABLED(OF_PLATDATA) return 0; #else - u32 cell[3]; + uint64_t caddr, paddr, len; int ret;
- ret = dev_read_u32_array(dev, "ranges", cell, ARRAY_SIZE(cell)); + /* only read range index 0 */ + ret = fdt_read_range((void *)gd->fdt_blob, dev_of_offset(dev), 0, + &caddr, &paddr, &len); if (!ret) { struct simple_bus_plat *plat = dev_get_uclass_plat(dev);
- plat->base = cell[0]; - plat->target = cell[1]; - plat->size = cell[2]; + plat->base = caddr; + plat->target = paddr; + plat->size = len; }
return dm_scan_fdt_dev(dev); diff --git a/include/dm/simple_bus.h b/include/dm/simple_bus.h index 4ad4cc4051..b7104013c0 100644 --- a/include/dm/simple_bus.h +++ b/include/dm/simple_bus.h @@ -7,9 +7,9 @@ #define __DM_SIMPLE_BUS_H
struct simple_bus_plat { - u32 base; - u32 size; - u32 target; + fdt_addr_t base; + fdt_size_t size; + fdt_addr_t target; };
#endif