Browse Source

linux: mtd: physmap_of: allow a flash based at physical 0 on noMMU

Without an MMU ioremap() hands the physical address back unchanged, so a
flash mapped at 0 comes out of devm_ioremap() as NULL and the probe fails
with -ENOMEM ("ioremap failed for resource [mem 0x00000000-...]"). Zero
is a perfectly good address there -- it is where the boot flash sits on
the EDOSK2674 and on most other noMMU boards.

Request the region and map it by hand instead of using
devm_ioremap_resource(), and only treat a NULL result as a failure where
it cannot be the mapping that was asked for.

Needed to mount a squashfs root off -pflash under qemu-system-h8300. Use
"mtd-rom" rather than "cfi-flash" there: the CFI probe leaves the chip in
query mode, and on h8300 the interrupt vector table lives at address 0 in
that same chip, so the next timer interrupt fetches CFI data instead of a
vector.

Signed-off-by: Ramin Moussavi <ramin.moussavi@yacoub.de>
Signed-off-by: Waldemar Brodkorb <wbx@openadk.org>
ramin 3 days ago
parent
commit
6f1208d095
1 changed files with 30 additions and 0 deletions
  1. 30 0
      target/linux/patches/4.4.302/h8300-mtd-physmap-nommu-zero.patch

+ 30 - 0
target/linux/patches/4.4.302/h8300-mtd-physmap-nommu-zero.patch

@@ -0,0 +1,30 @@
+diff -Nur linux-4.4.302.orig/drivers/mtd/maps/physmap_of.c linux-4.4.302/drivers/mtd/maps/physmap_of.c
+--- linux-4.4.302.orig/drivers/mtd/maps/physmap_of.c	2022-02-03 09:27:54.000000000 +0100
++++ linux-4.4.302/drivers/mtd/maps/physmap_of.c	2026-08-31 00:23:11.785855166 +0200
+@@ -214,9 +214,23 @@
+ 
+ 		err = -EBUSY;
+ 		res_size = resource_size(&res);
+-		info->list[i].map.virt = devm_ioremap_resource(&dev->dev, &res);
+-		if (IS_ERR(info->list[i].map.virt)) {
+-			err = PTR_ERR(info->list[i].map.virt);
++		if (!devm_request_mem_region(&dev->dev, res.start, res_size,
++					     dev_name(&dev->dev)))
++			goto err_out;
++
++		info->list[i].map.virt = devm_ioremap(&dev->dev, res.start,
++						      res_size);
++		/*
++		 * Without an MMU ioremap() hands the physical address back
++		 * unchanged, so a flash based at 0 maps to NULL -- a valid
++		 * address here, not a failure.  Only treat NULL as an error
++		 * where it cannot be the mapping we asked for.
++		 */
++		if (!info->list[i].map.virt &&
++		    (IS_ENABLED(CONFIG_MMU) || res.start != 0)) {
++			dev_err(&dev->dev, "ioremap failed for resource %pR\n",
++				&res);
++			err = -ENOMEM;
+ 			goto err_out;
+ 		}
+