From 43bacbe6ab85030a4dc424700f83108333e99536 Mon Sep 17 00:00:00 2001
From: =?utf8?q?Nuno=20S=C3=A1?= <nuno.sa@analog.com>
Date: Thu, 11 May 2023 13:19:50 +0200
Subject: [PATCH] mtd: cfi: respect reg address length
MIME-Version: 1.0
Content-Type: text/plain; charset=utf8
Content-Transfer-Encoding: 8bit

flash_get_size() will get the flash size from the device itself and go
through all erase regions to read protection status. However, the device
mappable region (eg: devicetree reg property) might be lower than the
device full size which means that the above cycle will result in a data
bus exception. This change fixes it by reading the 'addr_size' during
probe() and also use that as one possible upper limit.

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
---
 drivers/mtd/cfi_flash.c | 10 +++++++++-
 include/flash.h         |  1 +
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index f378f6fb61..8ade7949a6 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -2196,6 +2196,12 @@ ulong flash_get_size(phys_addr_t base, int banknum)
 		/* multiply the size by the number of chips */
 		info->size *= size_ratio;
 		max_size = cfi_flash_bank_size(banknum);
+#ifdef CONFIG_CFI_FLASH
+		if (max_size)
+			max_size = min((unsigned long)info->addr_size, max_size);
+		else
+			max_size = info->addr_size;
+#endif
 		if (max_size && info->size > max_size) {
 			debug("[truncated from %ldMiB]", info->size >> 20);
 			info->size = max_size;
@@ -2492,15 +2498,17 @@ unsigned long flash_init(void)
 static int cfi_flash_probe(struct udevice *dev)
 {
 	fdt_addr_t addr;
+	fdt_size_t size;
 	int idx;
 
 	for (idx = 0; idx < CFI_MAX_FLASH_BANKS; idx++) {
-		addr = dev_read_addr_index(dev, idx);
+		addr = dev_read_addr_size_index(dev, idx, &size);
 		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;
+		flash_info[cfi_flash_num_flash_banks].addr_size = size;
 		cfi_flash_num_flash_banks++;
 	}
 	gd->bd->bi_flashstart = flash_info[0].base;
diff --git a/include/flash.h b/include/flash.h
index 95992fa689..3710a2731b 100644
--- a/include/flash.h
+++ b/include/flash.h
@@ -46,6 +46,7 @@ typedef struct {
 #ifdef CONFIG_CFI_FLASH			/* DM-specific parts */
 	struct udevice *dev;
 	phys_addr_t base;
+	phys_size_t addr_size;
 #endif
 } flash_info_t;
 
-- 
2.39.5