diff mbox series

[v2,4/4] x86: mrccache: Allow use before driver model is active

Message ID 20200527065838.v2.4.I69e7fffa9628a9ab43de362fc7ca6c3536cb8a2f@changeid
State Accepted
Commit 70c3c911cc29237fdb1a561ea64df05b35a6790a
Headers show
Series x86: Correct SPI memory-mapping query | expand

Commit Message

Simon Glass May 27, 2020, 12:58 p.m. UTC
The change to avoid searching the device tree does not work on boards
wich don't have driver model set up this early, for example minnowmax.
Put back the old code (converted to livetree) as a fallback for these
devices. Also update the documentation.

This is tested on minnowmax, link, samus and coral.

Fixes: 87f1084a630 (x86: Adjust mrccache_get_region() to use livetree)
Signed-off-by: Simon Glass <sjg at chromium.org>
---

Changes in v2:
- Add new patch to allow use before driver model is active

 arch/x86/include/asm/mrccache.h | 15 ++++----------
 arch/x86/lib/mrccache.c         | 35 +++++++++++++++++++++++----------
 2 files changed, 29 insertions(+), 21 deletions(-)

Comments

Bin Meng May 28, 2020, 7:36 a.m. UTC | #1
On Wed, May 27, 2020 at 8:58 PM Simon Glass <sjg at chromium.org> wrote:
>
> The change to avoid searching the device tree does not work on boards
> wich don't have driver model set up this early, for example minnowmax.
> Put back the old code (converted to livetree) as a fallback for these
> devices. Also update the documentation.
>
> This is tested on minnowmax, link, samus and coral.
>
> Fixes: 87f1084a630 (x86: Adjust mrccache_get_region() to use livetree)
> Signed-off-by: Simon Glass <sjg at chromium.org>
> ---
>
> Changes in v2:
> - Add new patch to allow use before driver model is active
>
>  arch/x86/include/asm/mrccache.h | 15 ++++----------
>  arch/x86/lib/mrccache.c         | 35 +++++++++++++++++++++++----------
>  2 files changed, 29 insertions(+), 21 deletions(-)
>

Reviewed-by: Bin Meng <bmeng.cn at gmail.com>
Tested-by: Bin Meng <bmeng.cn at gmail.com> (on Intel minnowmax)
Bin Meng May 28, 2020, 7:45 a.m. UTC | #2
On Thu, May 28, 2020 at 3:36 PM Bin Meng <bmeng.cn at gmail.com> wrote:
>
> On Wed, May 27, 2020 at 8:58 PM Simon Glass <sjg at chromium.org> wrote:
> >
> > The change to avoid searching the device tree does not work on boards
> > wich don't have driver model set up this early, for example minnowmax.
> > Put back the old code (converted to livetree) as a fallback for these
> > devices. Also update the documentation.
> >
> > This is tested on minnowmax, link, samus and coral.
> >
> > Fixes: 87f1084a630 (x86: Adjust mrccache_get_region() to use livetree)
> > Signed-off-by: Simon Glass <sjg at chromium.org>
> > ---
> >
> > Changes in v2:
> > - Add new patch to allow use before driver model is active
> >
> >  arch/x86/include/asm/mrccache.h | 15 ++++----------
> >  arch/x86/lib/mrccache.c         | 35 +++++++++++++++++++++++----------
> >  2 files changed, 29 insertions(+), 21 deletions(-)
> >
>
> Reviewed-by: Bin Meng <bmeng.cn at gmail.com>
> Tested-by: Bin Meng <bmeng.cn at gmail.com> (on Intel minnowmax)

applied to u-boot-x86, thanks!
diff mbox series

Patch

diff --git a/arch/x86/include/asm/mrccache.h b/arch/x86/include/asm/mrccache.h
index d6b7529073..b60d1171f7 100644
--- a/arch/x86/include/asm/mrccache.h
+++ b/arch/x86/include/asm/mrccache.h
@@ -66,19 +66,12 @@  int mrccache_reserve(void);
  * mrccache_get_region() - get MRC region on the SPI flash
  *
  * This gets MRC region whose offset and size are described in the device tree
- * as a subnode to the SPI flash. If a non-NULL device pointer is supplied,
- * this also probes the SPI flash device and returns its device pointer for
- * the caller to use later.
- *
- * Be careful when calling this routine with a non-NULL device pointer:
- * - driver model initialization must be complete
- * - calling in the pre-relocation phase may bring some side effects during
- *   the SPI flash device probe (eg: for SPI controllers on a PCI bus, it
- *   triggers PCI bus enumeration during which insufficient memory issue
- *   might be exposed and it causes subsequent SPI flash probe fails).
+ * as a subnode to the SPI flash. This tries to find the SPI flash device
+ * (without probing it), falling back to looking for the devicetree node if
+ * driver model is not inited or the SPI flash is not found.
  *
  * @type:	Type of MRC data to use
- * @devp:	Returns pointer to the SPI flash device
+ * @devp:	Returns pointer to the SPI flash device, if found
  * @entry:	Position and size of MRC cache in SPI flash
  * @return 0 if success, -ENOENT if SPI flash node does not exist in the
  * device tree, -EPERM if MRC region subnode does not exist in the device
diff --git a/arch/x86/lib/mrccache.c b/arch/x86/lib/mrccache.c
index 21c71e036e..f181e8100c 100644
--- a/arch/x86/lib/mrccache.c
+++ b/arch/x86/lib/mrccache.c
@@ -233,6 +233,7 @@  int mrccache_get_region(enum mrc_type_t type, struct udevice **devp,
 	ulong map_base;
 	uint map_size;
 	uint offset;
+	ofnode node;
 	u32 reg[2];
 	int ret;
 
@@ -242,23 +243,36 @@  int mrccache_get_region(enum mrc_type_t type, struct udevice **devp,
 	 * memory map cannot be read.
 	 */
 	ret = uclass_find_first_device(UCLASS_SPI_FLASH, &dev);
-	if (!ret && !dev)
+	if (ret || !dev) {
+		/*
+		 * Fall back to searching the device tree since driver model
+		 * may not be ready yet (e.g. with FSPv1)
+		 */
+		node = ofnode_by_compatible(ofnode_null(), "jedec,spi-nor");
+		if (!ofnode_valid(node))
+			return log_msg_ret("Cannot find SPI flash\n", -ENOENT);
 		ret = -ENODEV;
-	if (ret)
-		return log_msg_ret("Cannot find SPI flash\n", ret);
-	ret = dm_spi_get_mmap(dev, &map_base, &map_size, &offset);
-	if (!ret) {
-		entry->base = map_base;
 	} else {
-		ret = dev_read_u32_array(dev, "memory-map", reg, 2);
+		ret = dm_spi_get_mmap(dev, &map_base, &map_size, &offset);
+		if (!ret)
+			entry->base = map_base;
+		node = dev_ofnode(dev);
+	}
+
+	/*
+	 * At this point we have entry->base if ret == 0. If not, then we have
+	 * the node and can look for memory-map
+	 */
+	if (ret) {
+		ret = ofnode_read_u32_array(node, "memory-map", reg, 2);
 		if (ret)
 			return log_msg_ret("Cannot find memory map\n", ret);
 		entry->base = reg[0];
 	}
 
 	/* Find the place where we put the MRC cache */
-	mrc_node = dev_read_subnode(dev, type == MRC_TYPE_NORMAL ?
-				    "rw-mrc-cache" : "rw-var-mrc-cache");
+	mrc_node = ofnode_find_subnode(node, type == MRC_TYPE_NORMAL ?
+				       "rw-mrc-cache" : "rw-var-mrc-cache");
 	if (!ofnode_valid(mrc_node))
 		return log_msg_ret("Cannot find node", -EPERM);
 
@@ -271,7 +285,8 @@  int mrccache_get_region(enum mrc_type_t type, struct udevice **devp,
 	if (devp)
 		*devp = dev;
 	debug("MRC cache type %d in '%s', offset %x, len %x, base %x\n",
-	      type, dev->name, entry->offset, entry->length, entry->base);
+	      type, dev ? dev->name : ofnode_get_name(node), entry->offset,
+	      entry->length, entry->base);
 
 	return 0;
 }