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
