* 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
ulong map_base;
uint map_size;
uint offset;
+ ofnode node;
u32 reg[2];
int ret;
* 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);
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;
}