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

Heinrich Schuchardt xypron.glpk at gmx.de
Fri Jul 24 18:37:11 CEST 2020


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 at 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



More information about the U-Boot mailing list