[PATCH v2 1/1] mtd: cfi_flash: read device tree correctly

The size of #address-cells and #size-cells is not correctly determined if CONFIG_OF_LIVE=n.
dev_read_size_cells() and dev_read_addr_cells() do not walk up the device tree to find the number of cells. On error they return 1 and 2 respectively. On qemu_arm64_defconfig this leads to the incorrect detection of the address of the second flash bank as 0x400000000000000 instead of 0x4000000.
When running
qemu-system-aarch64 -machine virt -bios u-boot.bin \ -cpu cortex-a53 -nographic \ -drive if=3Dpflash,format=3Draw,index=3D1,file=3Denvstore.img
the command 'saveenv' fails with
Saving Environment to Flash... Error: start and/or end address not on sector boundary Error: start and/or end address not on sector boundary Failed (1)
due to this incorrect address.
Use function fdtdec_get_addr_size_auto_noparent() to read the array of flash banks from the device tree if CONFIG_OF_LIVE=n.
Add debug statements for testing.
Signed-off-by: Heinrich Schuchardt xypron.glpk@gmx.de --- v2: Do not change the existing logic for CONFIG_OF_LIVE=y. --- drivers/mtd/cfi_flash.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+)
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index b7289ba539..0030949779 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -2466,6 +2466,9 @@ unsigned long flash_init(void) }
#ifdef CONFIG_CFI_FLASH /* for driver model */ + +#ifdef CONFIG_OF_LIVE + static int cfi_flash_probe(struct udevice *dev) { const fdt32_t *cell; @@ -2488,6 +2491,7 @@ static int cfi_flash_probe(struct udevice *dev)
flash_info[cfi_flash_num_flash_banks].dev = dev; flash_info[cfi_flash_num_flash_banks].base = addr; + debug("CFI flash at 0x%llx\n", addr); cfi_flash_num_flash_banks++;
idx += addrc + sizec; @@ -2497,6 +2501,38 @@ static int cfi_flash_probe(struct udevice *dev) return 0; }
+#else + +static int cfi_flash_probe(struct udevice *dev) +{ + const fdt32_t *cell; + int len; + + /* decode regs; there may be multiple reg tuples. */ + cell = dev_read_prop(dev, "reg", &len); + if (!cell) + return -ENOENT; + + for (cfi_flash_num_flash_banks = 0; ; ++cfi_flash_num_flash_banks) { + phys_addr_t addr; + + addr = fdtdec_get_addr_size_auto_noparent( + gd->fdt_blob, dev_of_offset(dev), "reg", + cfi_flash_num_flash_banks, NULL, false); + if (addr == FDT_ADDR_T_NONE) + break; + + flash_info[cfi_flash_num_flash_banks].dev = dev; + flash_info[cfi_flash_num_flash_banks].base = addr; + debug("CFI flash at 0x%llx\n", addr); + } + gd->bd->bi_flashstart = flash_info[0].base; + + return 0; +} + +#endif + static const struct udevice_id cfi_flash_ids[] = { { .compatible = "cfi-flash" }, { .compatible = "jedec-flash" }, -- 2.27.0
participants (1)
-
Heinrich Schuchardt