summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/cmd_sf.c25
-rw-r--r--drivers/mtd/spi/sf_probe.c66
2 files changed, 89 insertions, 2 deletions
diff --git a/common/cmd_sf.c b/common/cmd_sf.c
index 42d89d4f07..95a6f89a84 100644
--- a/common/cmd_sf.c
+++ b/common/cmd_sf.c
@@ -8,11 +8,13 @@
#include <common.h>
#include <div64.h>
+#include <dm.h>
#include <malloc.h>
#include <spi.h>
#include <spi_flash.h>
#include <asm/io.h>
+#include <dm/device-internal.h>
static struct spi_flash *flash;
@@ -81,7 +83,12 @@ static int do_spi_flash_probe(int argc, char * const argv[])
unsigned int speed = CONFIG_SF_DEFAULT_SPEED;
unsigned int mode = CONFIG_SF_DEFAULT_MODE;
char *endp;
+#ifdef CONFIG_DM_SPI_FLASH
+ struct udevice *new, *bus_dev;
+ int ret;
+#else
struct spi_flash *new;
+#endif
if (argc >= 2) {
cs = simple_strtoul(argv[1], &endp, 0);
@@ -109,6 +116,23 @@ static int do_spi_flash_probe(int argc, char * const argv[])
return -1;
}
+#ifdef CONFIG_DM_SPI_FLASH
+ /* Remove the old device, otherwise probe will just be a nop */
+ ret = spi_find_bus_and_cs(bus, cs, &bus_dev, &new);
+ if (!ret) {
+ device_remove(new);
+ device_unbind(new);
+ }
+ flash = NULL;
+ ret = spi_flash_probe_bus_cs(bus, cs, speed, mode, &new);
+ if (ret) {
+ printf("Failed to initialize SPI flash at %u:%u (error %d)\n",
+ bus, cs, ret);
+ return 1;
+ }
+
+ flash = new->uclass_priv;
+#else
new = spi_flash_probe(bus, cs, speed, mode);
if (!new) {
printf("Failed to initialize SPI flash at %u:%u\n", bus, cs);
@@ -118,6 +142,7 @@ static int do_spi_flash_probe(int argc, char * const argv[])
if (flash)
spi_flash_free(flash);
flash = new;
+#endif
return 0;
}
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
index 212a825ada..26364269be 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -9,6 +9,7 @@
*/
#include <common.h>
+#include <dm.h>
#include <errno.h>
#include <fdtdec.h>
#include <malloc.h>
@@ -131,13 +132,15 @@ static int spi_flash_validate_params(struct spi_slave *spi, u8 *idcode,
flash->dual_flash = flash->spi->option;
/* Assign spi_flash ops */
+#ifndef CONFIG_DM_SPI_FLASH
flash->write = spi_flash_cmd_write_ops;
-#ifdef CONFIG_SPI_FLASH_SST
+#if defined(CONFIG_SPI_FLASH_SST)
if (params->flags & SST_WP)
flash->write = sst_write_wp;
#endif
flash->erase = spi_flash_cmd_erase_ops;
flash->read = spi_flash_cmd_read_ops;
+#endif
/* Compute the flash size */
flash->shift = (flash->dual_flash & SF_DUAL_PARALLEL_FLASH) ? 1 : 0;
@@ -398,7 +401,8 @@ err_read_id:
return ret;
}
-static struct spi_flash *spi_flash_probe_tail(struct spi_slave *bus)
+#ifndef CONFIG_DM_SPI_FLASH
+struct spi_flash *spi_flash_probe_tail(struct spi_slave *bus)
{
struct spi_flash *flash;
@@ -443,3 +447,61 @@ void spi_flash_free(struct spi_flash *flash)
spi_free_slave(flash->spi);
free(flash);
}
+
+#else /* defined CONFIG_DM_SPI_FLASH */
+
+static int spi_flash_std_read(struct udevice *dev, u32 offset, size_t len,
+ void *buf)
+{
+ struct spi_flash *flash = dev->uclass_priv;
+
+ return spi_flash_cmd_read_ops(flash, offset, len, buf);
+}
+
+int spi_flash_std_write(struct udevice *dev, u32 offset, size_t len,
+ const void *buf)
+{
+ struct spi_flash *flash = dev->uclass_priv;
+
+ return spi_flash_cmd_write_ops(flash, offset, len, buf);
+}
+
+int spi_flash_std_erase(struct udevice *dev, u32 offset, size_t len)
+{
+ struct spi_flash *flash = dev->uclass_priv;
+
+ return spi_flash_cmd_erase_ops(flash, offset, len);
+}
+
+int spi_flash_std_probe(struct udevice *dev)
+{
+ struct spi_slave *slave = dev_get_parentdata(dev);
+ struct spi_flash *flash;
+
+ flash = dev->uclass_priv;
+ flash->dev = dev;
+ debug("%s: slave=%p, cs=%d\n", __func__, slave, slave->cs);
+ return spi_flash_probe_slave(slave, flash);
+}
+
+static const struct dm_spi_flash_ops spi_flash_std_ops = {
+ .read = spi_flash_std_read,
+ .write = spi_flash_std_write,
+ .erase = spi_flash_std_erase,
+};
+
+static const struct udevice_id spi_flash_std_ids[] = {
+ { .compatible = "spi-flash" },
+ { }
+};
+
+U_BOOT_DRIVER(spi_flash_std) = {
+ .name = "spi_flash_std",
+ .id = UCLASS_SPI_FLASH,
+ .of_match = spi_flash_std_ids,
+ .probe = spi_flash_std_probe,
+ .priv_auto_alloc_size = sizeof(struct spi_flash),
+ .ops = &spi_flash_std_ops,
+};
+
+#endif /* CONFIG_DM_SPI_FLASH */