[1/2] mtd: spi: Separate dm vs nodm SF code

Message ID 20200514180941.21542-1-jagan@amarulasolutions.com
State New
Headers show
Series
  • [1/2] mtd: spi: Separate dm vs nodm SF code
Related show

Commit Message

Jagan Teki May 14, 2020, 6:09 p.m.
Right now, the sf have common driver to handle
both dm and nodm code, where nondm has spi_flash
probe and dm has U_BOOT_DRIVER for dm spi flash.

Having a common code base for dm and nodm with
ifdef make it difficult to extend functionalities
and also difficult to read.

So, keep them separate and give scope to dm code
for further enhancements.

Cc: Simon Glass <sjg at chromium.org>
Cc: Vignesh R <vigneshr at ti.com>
Cc: Daniel Schwierzeck <daniel.schwierzeck at gmail.com>
Signed-off-by: Jagan Teki <jagan at amarulasolutions.com>
---
 drivers/mtd/spi/Makefile    |   8 ++-
 drivers/mtd/spi/sf-nodm.c   |  76 +++++++++++++++++++++
 drivers/mtd/spi/sf-uclass.c | 128 ++++++++++++++++++++++++++++++++++++
 3 files changed, 210 insertions(+), 2 deletions(-)
 create mode 100644 drivers/mtd/spi/sf-nodm.c

Patch

diff --git a/drivers/mtd/spi/Makefile b/drivers/mtd/spi/Makefile
index b5dfa300de..b3ae74dbe8 100644
--- a/drivers/mtd/spi/Makefile
+++ b/drivers/mtd/spi/Makefile
@@ -3,8 +3,12 @@ 
 # (C) Copyright 2006
 # Wolfgang Denk, DENX Software Engineering, wd at denx.de.
 
-obj-$(CONFIG_DM_SPI_FLASH) += sf-uclass.o
-spi-nor-y := sf_probe.o spi-nor-ids.o
+ifdef CONFIG_DM_SPI_FLASH
+spi-nor-y += sf-uclass.o
+else
+spi-nor-y += sf-nodm.o
+endif
+spi-nor-y += spi-nor-ids.o
 
 ifdef CONFIG_SPL_BUILD
 obj-$(CONFIG_SPL_SPI_BOOT)	+= fsl_espi_spl.o
diff --git a/drivers/mtd/spi/sf-nodm.c b/drivers/mtd/spi/sf-nodm.c
new file mode 100644
index 0000000000..b23014c2a8
--- /dev/null
+++ b/drivers/mtd/spi/sf-nodm.c
@@ -0,0 +1,76 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * SPI flash probing
+ *
+ * Copyright (C) 2008 Atmel Corporation
+ * Copyright (C) 2010 Reinhard Meyer, EMK Elektronik
+ * Copyright (C) 2013 Jagannadha Sutradharudu Teki, Xilinx Inc.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <malloc.h>
+#include <spi.h>
+#include <spi_flash.h>
+
+#include "sf_internal.h"
+
+struct spi_flash *spi_flash_probe(unsigned int busnum, unsigned int cs,
+				  unsigned int max_hz, unsigned int spi_mode)
+{
+	struct spi_slave *bus;
+	struct spi_flash *flash;
+	int ret;
+
+	/* Allocate space if needed (not used by sf-uclass) */
+	flash = calloc(1, sizeof(*flash));
+	if (!flash) {
+		debug("SF: Failed to allocate spi_flash\n");
+		return NULL;
+	}
+
+	bus = spi_setup_slave(busnum, cs, max_hz, spi_mode);
+	if (!bus) {
+		printf("SF: Failed to set up slave\n");
+		goto err_free;
+	}
+
+	flash->spi = bus;
+
+	/* Claim spi bus */
+	ret = spi_claim_bus(bus);
+	if (ret) {
+		debug("SF: Failed to claim SPI bus: %d\n", ret);
+		goto err_free_slave;
+	}
+
+	ret = spi_nor_scan(flash);
+	if (ret)
+		goto err_read_id;
+
+	if (CONFIG_IS_ENABLED(SPI_FLASH_MTD)) {
+		ret = spi_flash_mtd_register(flash);
+		if (ret)
+			goto err_read_id;
+	}
+
+	return flash;
+
+err_read_id:
+	spi_release_bus(bus);
+err_free_slave:
+	spi_free_slave(bus);
+err_free:
+	free(flash);
+	return NULL;
+}
+
+void spi_flash_free(struct spi_flash *flash)
+{
+	if (CONFIG_IS_ENABLED(SPI_FLASH_MTD))
+		spi_flash_mtd_unregister();
+
+	spi_free_slave(flash->spi);
+	free(flash);
+}
diff --git a/drivers/mtd/spi/sf-uclass.c b/drivers/mtd/spi/sf-uclass.c
index 5a42ab83c8..97a3f5d2c7 100644
--- a/drivers/mtd/spi/sf-uclass.c
+++ b/drivers/mtd/spi/sf-uclass.c
@@ -95,6 +95,134 @@  static int spi_flash_post_bind(struct udevice *dev)
 	return 0;
 }
 
+static int spi_flash_std_read(struct udevice *dev, u32 offset, size_t len,
+			      void *buf)
+{
+	struct spi_flash *flash = dev_get_uclass_priv(dev);
+	struct mtd_info *mtd = &flash->mtd;
+	size_t retlen;
+
+	return log_ret(mtd->_read(mtd, offset, len, &retlen, buf));
+}
+
+static int spi_flash_std_write(struct udevice *dev, u32 offset, size_t len,
+			       const void *buf)
+{
+	struct spi_flash *flash = dev_get_uclass_priv(dev);
+	struct mtd_info *mtd = &flash->mtd;
+	size_t retlen;
+
+	return mtd->_write(mtd, offset, len, &retlen, buf);
+}
+
+static int spi_flash_std_erase(struct udevice *dev, u32 offset, size_t len)
+{
+	struct spi_flash *flash = dev_get_uclass_priv(dev);
+	struct mtd_info *mtd = &flash->mtd;
+	struct erase_info instr;
+
+	if (offset % mtd->erasesize || len % mtd->erasesize) {
+		printf("SF: Erase offset/length not multiple of erase size\n");
+		return -EINVAL;
+	}
+
+	memset(&instr, 0, sizeof(instr));
+	instr.addr = offset;
+	instr.len = len;
+
+	return mtd->_erase(mtd, &instr);
+}
+
+int spi_flash_std_probe(struct udevice *dev)
+{
+	struct spi_slave *slave = dev_get_parent_priv(dev);
+	struct spi_flash *flash;
+	int ret;
+
+	if (!slave) {
+		printf("SF: Failed to set up slave\n");
+		return -ENODEV;
+	}
+
+	flash = dev_get_uclass_priv(dev);
+	flash->dev = dev;
+	flash->spi = slave;
+
+	/* Claim spi bus */
+	ret = spi_claim_bus(slave);
+	if (ret) {
+		debug("SF: Failed to claim SPI bus: %d\n", ret);
+		return ret;
+	}
+
+	ret = spi_nor_scan(flash);
+	if (ret)
+		goto err_read_id;
+
+	if (CONFIG_IS_ENABLED(SPI_FLASH_MTD))
+		ret = spi_flash_mtd_register(flash);
+
+err_read_id:
+	spi_release_bus(slave);
+	return ret;
+}
+
+static int spi_flash_std_remove(struct udevice *dev)
+{
+	if (CONFIG_IS_ENABLED(SPI_FLASH_MTD))
+		spi_flash_mtd_unregister();
+
+	return 0;
+}
+
+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,
+};
+
+/*
+ * Manually set the parent of the SPI flash to SPI, since dtoc doesn't. We also
+ * need to allocate the parent_platdata since by the time this function is
+ * called device_bind() has already gone past that step.
+ */
+static int spi_flash_bind(struct udevice *dev)
+{
+	if (CONFIG_IS_ENABLED(OF_PLATDATA)) {
+		struct dm_spi_slave_platdata *plat;
+		struct udevice *spi;
+		int ret;
+
+		ret = uclass_first_device_err(UCLASS_SPI, &spi);
+		if (ret)
+			return ret;
+		dev->parent = spi;
+
+		plat = calloc(sizeof(*plat), 1);
+		if (!plat)
+			return -ENOMEM;
+		dev->parent_platdata = plat;
+	}
+
+	return 0;
+}
+
+static const struct udevice_id spi_flash_std_ids[] = {
+	{ .compatible = "jedec,spi-nor" },
+	{ }
+};
+
+U_BOOT_DRIVER(spi_flash_std) = {
+	.name		= "spi_flash_std",
+	.id		= UCLASS_SPI_FLASH,
+	.of_match	= spi_flash_std_ids,
+	.bind		= spi_flash_bind,
+	.probe		= spi_flash_std_probe,
+	.remove		= spi_flash_std_remove,
+	.priv_auto_alloc_size = sizeof(struct spi_flash),
+	.ops		= &spi_flash_std_ops,
+};
+
 UCLASS_DRIVER(spi_flash) = {
 	.id		= UCLASS_SPI_FLASH,
 	.name		= "spi_flash",