+
+void sandbox_sf_unbind_emul(struct sandbox_state *state, int busnum, int cs)
+{
+ struct udevice *dev;
+
+ dev = state->spi[busnum][cs].emul;
+ device_remove(dev, DM_REMOVE_NORMAL);
+ device_unbind(dev);
+ state->spi[busnum][cs].emul = NULL;
+}
+
+int sandbox_spi_get_emul(struct sandbox_state *state,
+ struct udevice *bus, struct udevice *slave,
+ struct udevice **emulp)
+{
+ struct sandbox_spi_info *info;
+ int busnum = bus->seq;
+ int cs = spi_chip_select(slave);
+ int ret;
+
+ info = &state->spi[busnum][cs];
+ if (!info->emul) {
+ /* Use the same device tree node as the SPI flash device */
+ debug("%s: busnum=%u, cs=%u: binding SPI flash emulation: ",
+ __func__, busnum, cs);
+ ret = sandbox_sf_bind_emul(state, busnum, cs, bus,
+ dev_ofnode(slave), slave->name);
+ if (ret) {
+ debug("failed (err=%d)\n", ret);
+ return ret;
+ }
+ debug("OK\n");
+ }
+ *emulp = info->emul;
+
+ return 0;
+}
+#endif
+
+static const struct udevice_id sandbox_sf_ids[] = {
+ { .compatible = "sandbox,spi-flash" },
+ { }
+};
+
+U_BOOT_DRIVER(sandbox_sf_emul) = {
+ .name = "sandbox_sf_emul",
+ .id = UCLASS_SPI_EMUL,
+ .of_match = sandbox_sf_ids,
+ .ofdata_to_platdata = sandbox_sf_ofdata_to_platdata,
+ .probe = sandbox_sf_probe,
+ .remove = sandbox_sf_remove,
+ .priv_auto_alloc_size = sizeof(struct sandbox_spi_flash),
+ .platdata_auto_alloc_size = sizeof(struct sandbox_spi_flash_plat_data),
+ .ops = &sandbox_sf_emul_ops,
+};