sandbox_sf_bind_emul() binds the SPI NOR flash emulator for every slave
on the sandbox SPI bus, whatever that slave is, so a device of another
kind cannot be emulated and cannot be tested.

As with I2C and PCI, a slave can point to an emulation node via a
sandbox,emul phandle. Its compatible selects the driver. Without the
property, the flash emulator remains bound to the slave node as before.

Rename sandbox_sf_unbind_emul() to sandbox_spi_unbind_emul() while
here. It is no longer specific to SPI NOR, and the old name would
mislead every new caller.

Signed-off-by: Heiko Schocher <[email protected]>
---
checkpatch warns "strlcpy is preferred over strncpy" on
drivers/mtd/spi/sandbox.c:562. That line is not new, it is there since
since commit b6c2956defb4 ("dm: sf: sandbox: Convert SPI flash driver
to driver model"). So ignoring this warning.

Changes in v2:
Added comments from Simon:
- sandbox,emul is a phandle to an emulation node whose compatible
  selects the driver, instead of a string naming a U-Boot driver. That
  property is already a phandle for I2C and PCI, and dtoc treats it as
  one, so v1 would have given the same name two meanings.
- Renamed sandbox_sf_unbind_emul() to sandbox_spi_unbind_emul(), it is
  no longer specific to SPI NOR.
- The error paths name the driver or the node that could not be bound.

 drivers/mtd/spi/sandbox.c | 65 +++++++++++++++++++++++++++++++--------
 include/spi_flash.h       |  2 +-
 test/dm/sf.c              |  4 +--
 test/dm/spi.c             | 10 +++---
 4 files changed, 61 insertions(+), 20 deletions(-)

diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c
index e5ebc3479fb..66c72ed02e1 100644
--- a/drivers/mtd/spi/sandbox.c
+++ b/drivers/mtd/spi/sandbox.c
@@ -26,6 +26,8 @@
 #include <dm/lists.h>
 #include <dm/uclass-internal.h>
 
+#define SANDBOX_SF_EMUL                "sandbox_sf_emul"
+
 /*
  * The different states that our SPI flash transitions between.
  * We need to keep track of this across multiple xfer calls since
@@ -518,39 +520,78 @@ static const struct dm_spi_emul_ops sandbox_sf_emul_ops = 
{
 };
 
 #ifdef CONFIG_SPI_FLASH
-int sandbox_sf_bind_emul(struct sandbox_state *state, int busnum, int cs,
-                        struct udevice *bus, ofnode node, const char *spec)
+/**
+ * sandbox_spi_emul_lookup() - bind the emulator standing in for a slave
+ *
+ * A slave points at its emulation with a "sandbox,emul" phandle, the way
+ * the I2C and PCI emulations do, and the compatible of that node selects
+ * the driver. Without the property the SPI NOR flash emulator is bound on
+ * the slave's own node, which is what every existing node relies on.
+ *
+ * @bus:       SPI bus the emulator becomes a child of
+ * @node:      device tree node of the slave
+ * @spec:      name of the slave, used to name the flash emulator
+ * @emulp:     returns the bound emulator
+ * Return: 0 on success, negative on error
+ */
+static int sandbox_spi_emul_lookup(struct udevice *bus, ofnode node,
+                                  const char *spec, struct udevice **emulp)
 {
-       struct udevice *emul;
+       struct ofnode_phandle_args args;
        char name[20], *str;
        struct driver *drv;
        int ret;
 
-       /* now the emulator */
-       strncpy(name, spec, sizeof(name) - 6);
-       name[sizeof(name) - 6] = '\0';
-       strcat(name, "-emul");
-       drv = lists_driver_lookup_name("sandbox_sf_emul");
+       if (!ofnode_parse_phandle_with_args(node, "sandbox,emul", NULL, 0, 0,
+                                           &args)) {
+               ret = lists_bind_fdt(bus, args.node, emulp, NULL, false);
+               if (ret)
+                       printf("Cannot bind emulator from node '%s' (err=%d)\n",
+                              ofnode_get_name(args.node), ret);
+
+               return ret;
+       }
+
+       drv = lists_driver_lookup_name(SANDBOX_SF_EMUL);
        if (!drv) {
-               puts("Cannot find sandbox_sf_emul driver\n");
+               printf("Cannot find SPI emulation driver '%s'\n",
+                      SANDBOX_SF_EMUL);
                return -ENOENT;
        }
+
+       strncpy(name, spec, sizeof(name) - 6);
+       name[sizeof(name) - 6] = '\0';
+       strcat(name, "-emul");
        str = strdup(name);
        if (!str)
                return -ENOMEM;
-       ret = device_bind(bus, drv, str, NULL, node, &emul);
+
+       ret = device_bind(bus, drv, str, NULL, node, emulp);
        if (ret) {
                free(str);
                printf("Cannot create emul device for spec '%s' (err=%d)\n",
                       spec, ret);
-               return ret;
        }
+
+       return ret;
+}
+
+int sandbox_sf_bind_emul(struct sandbox_state *state, int busnum, int cs,
+                        struct udevice *bus, ofnode node, const char *spec)
+{
+       struct udevice *emul;
+       int ret;
+
+       ret = sandbox_spi_emul_lookup(bus, node, spec, &emul);
+       if (ret)
+               return ret;
+
        state->spi[busnum][cs].emul = emul;
 
        return 0;
 }
 
-void sandbox_sf_unbind_emul(struct sandbox_state *state, int busnum, int cs)
+void sandbox_spi_unbind_emul(struct sandbox_state *state, int busnum, int cs)
 {
        struct udevice *dev;
 
diff --git a/include/spi_flash.h b/include/spi_flash.h
index 2e703e85250..d5a20ea815c 100644
--- a/include/spi_flash.h
+++ b/include/spi_flash.h
@@ -136,7 +136,7 @@ struct sandbox_state;
 int sandbox_sf_bind_emul(struct sandbox_state *state, int busnum, int cs,
                         struct udevice *bus, ofnode node, const char *spec);
 
-void sandbox_sf_unbind_emul(struct sandbox_state *state, int busnum, int cs);
+void sandbox_spi_unbind_emul(struct sandbox_state *state, int busnum, int cs);
 
 #else
 /* Compatibility functions for when DM_SPI_FLASH is disabled */
diff --git a/test/dm/sf.c b/test/dm/sf.c
index 3684d021709..5959ebb349d 100644
--- a/test/dm/sf.c
+++ b/test/dm/sf.c
@@ -68,7 +68,7 @@ static int dm_test_spi_flash(struct unit_test_state *uts)
         * Since we are about to destroy all devices, we must tell sandbox
         * to forget the emulation device
         */
-       sandbox_sf_unbind_emul(state_get_current(), 0, 0);
+       sandbox_spi_unbind_emul(state_get_current(), 0, 0);
 
        return 0;
 }
@@ -96,7 +96,7 @@ static int dm_test_spi_flash_func(struct unit_test_state *uts)
         * Since we are about to destroy all devices, we must tell sandbox
         * to forget the emulation device
         */
-       sandbox_sf_unbind_emul(state_get_current(), 0, 0);
+       sandbox_spi_unbind_emul(state_get_current(), 0, 0);
 
        return 0;
 }
diff --git a/test/dm/spi.c b/test/dm/spi.c
index a0da12ab6bc..1f70ce1a467 100644
--- a/test/dm/spi.c
+++ b/test/dm/spi.c
@@ -57,7 +57,7 @@ static int dm_test_spi_find(struct unit_test_state *uts)
        ut_asserteq(-ENOENT, _spi_get_bus_and_cs(busnum, cs, speed, mode,
                                                 "jedec_spi_nor", "name", &bus,
                                                 &slave));
-       sandbox_sf_unbind_emul(state_get_current(), busnum, cs);
+       sandbox_spi_unbind_emul(state_get_current(), busnum, cs);
        ut_assertok(spi_cs_info(bus, cs, &info));
        ut_asserteq_ptr(NULL, info.dev);
 
@@ -84,8 +84,8 @@ static int dm_test_spi_find(struct unit_test_state *uts)
         * Since we are about to destroy all devices, we must tell sandbox
         * to forget the emulation device
         */
-       sandbox_sf_unbind_emul(state_get_current(), busnum, cs);
-       sandbox_sf_unbind_emul(state_get_current(), busnum, cs_b);
+       sandbox_spi_unbind_emul(state_get_current(), busnum, cs);
+       sandbox_spi_unbind_emul(state_get_current(), busnum, cs_b);
 
        return 0;
 }
@@ -210,7 +210,7 @@ static int dm_test_spi_xfer(struct unit_test_state *uts)
         * to forget the emulation device
         */
 #if CONFIG_IS_ENABLED(DM_SPI_FLASH)
-       sandbox_sf_unbind_emul(state_get_current(), busnum, cs);
+       sandbox_spi_unbind_emul(state_get_current(), busnum, cs);
 #endif
 
        return 0;
@@ -249,7 +249,7 @@ static int dm_test_spi_xfer_no_rx_tx(struct unit_test_state 
*uts)
         * to forget the emulation device
         */
 #if CONFIG_IS_ENABLED(DM_SPI_FLASH)
-       sandbox_sf_unbind_emul(state_get_current(), busnum, cs);
+       sandbox_spi_unbind_emul(state_get_current(), busnum, cs);
 #endif
 
        return 0;
-- 
2.55.0

Reply via email to