[U-Boot] [PATCH v7 16/34] sf: Add MTD support to spi_flash

Jagan Teki
2015-11-26T12:04:00Z

This patch adds mtd_info support to spi_flash layer, MTD has
proven core for flash operations so adding MTD to spi_flash
will extends more functionality.

Reviewed-by: Heiko Schocher <hs@denx.de>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
drivers/mtd/spi/sf_ops.c | 40 +++++++++++++++++++++++-----------------
drivers/mtd/spi/sf_probe.c | 28 ++++++++++++++++++++--------
include/spi_flash.h | 4 ++++
3 files changed, 47 insertions(+), 25 deletions(-)

diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c
index 3705534..c9f0bbd 100644
--- a/drivers/mtd/spi/sf_ops.c
+++ b/drivers/mtd/spi/sf_ops.c
@@ -15,6 +15,7 @@
#include <spi.h>
#include <spi_flash.h>
#include <linux/log2.h>
+#include <linux/mtd/mtd.h>

#include "sf_internal.h"

@@ -177,8 +178,8 @@ static void spi_flash_dual(struct spi_flash *flash, u32 *addr)
{
switch (flash->dual_flash) {
case SF_DUAL_STACKED_FLASH:
- if (*addr >= (flash->size >> 1)) {
- *addr -= flash->size >> 1;
+ if (*addr >= (flash->mtd->size >> 1)) {
+ *addr -= flash->mtd->size >> 1;
flash->spi->flags |= SPI_XFER_U_PAGE;
} else {
flash->spi->flags &= ~SPI_XFER_U_PAGE;
@@ -898,6 +899,7 @@ int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash)

int spi_flash_scan(struct spi_flash *flash)
{
+ struct mtd_info *mtd = flash->mtd;
const struct spi_flash_params *params;
u16 jedec, ext_jedec;
u8 idcode[5];
@@ -947,6 +949,9 @@ int spi_flash_scan(struct spi_flash *flash)

/* Assign spi data */
flash->name = params->name;
+ mtd->type = MTD_NORFLASH;
+ mtd->writesize = 1;
+ mtd->flags = MTD_CAP_NORFLASH;
flash->memory_map = flash->spi->memory_map;
flash->dual_flash = flash->spi->option;

@@ -955,17 +960,17 @@ int spi_flash_scan(struct spi_flash *flash)
flash->flags |= SNOR_F_SST_WR;

/* Assign spi_flash ops */
- flash->write = spi_flash_cmd_write_ops;
+ mtd->_write = spi_flash_cmd_write_ops;
#if defined(CONFIG_SPI_FLASH_SST)
if (flash->flags & SNOR_F_SST_WR) {
if (flash->spi->op_mode_tx & SPI_OPM_TX_BP)
- flash->write = sst_write_bp;
+ mtd->_write = sst_write_bp;
else
- flash->write = sst_write_wp;
+ mtd->_write = sst_write_wp;
}
#endif
- flash->erase = spi_flash_cmd_erase_ops;
- flash->read = spi_flash_cmd_read_ops;
+ mtd->_erase = spi_flash_cmd_erase_ops;
+ mtd->_read = spi_flash_cmd_read_ops;

/* lock hooks are flash specific - assign them based on idcode0 */
switch (idcode[0]) {
@@ -998,27 +1003,28 @@ int spi_flash_scan(struct spi_flash *flash)
flash->page_size = 256;
}
flash->page_size <<= flash->shift;
+ mtd->writebufsize = flash->page_size;
flash->sector_size = params->sector_size << flash->shift;
- flash->size = flash->sector_size * params->nr_sectors << flash->shift;
+ mtd->size = flash->sector_size * params->nr_sectors << flash->shift;
#ifdef CONFIG_SF_DUAL_FLASH
if (flash->dual_flash & SF_DUAL_STACKED_FLASH)
- flash->size <<= 1;
+ mtd->size <<= 1;
#endif

/* Compute erase sector and command */
if (params->flags & SECT_4K) {
flash->erase_cmd = CMD_ERASE_4K;
- flash->erase_size = 4096 << flash->shift;
+ mtd->erasesize = 4096 << flash->shift;
} else if (params->flags & SECT_32K) {
flash->erase_cmd = CMD_ERASE_32K;
- flash->erase_size = 32768 << flash->shift;
+ mtd->erasesize = 32768 << flash->shift;
} else {
flash->erase_cmd = CMD_ERASE_64K;
- flash->erase_size = flash->sector_size;
+ mtd->erasesize = flash->sector_size;
}

/* Now erase size becomes valid sector size */
- flash->sector_size = flash->erase_size;
+ flash->sector_size = mtd->erasesize;

/* Look for the fastest read cmd */
cmd = fls(params->e_rd_cmd & flash->spi->op_mode_rx);
@@ -1090,8 +1096,8 @@ int spi_flash_scan(struct spi_flash *flash)
#ifndef CONFIG_SPL_BUILD
printf("SF: Detected %s with page size ", flash->name);
print_size(flash->page_size, ", erase size ");
- print_size(flash->erase_size, ", total ");
- print_size(flash->size, "");
+ print_size(mtd->erasesize, ", total ");
+ print_size(mtd->size, "");
if (flash->memory_map)
printf(", mapped at %p", flash->memory_map);
puts("\n");
@@ -1099,9 +1105,9 @@ int spi_flash_scan(struct spi_flash *flash)

#ifndef CONFIG_SPI_FLASH_BAR
if (((flash->dual_flash == SF_SINGLE_FLASH) &&
- (flash->size > SPI_FLASH_16MB_BOUN)) ||
+ (mtd->size > SPI_FLASH_16MB_BOUN)) ||
((flash->dual_flash > SF_SINGLE_FLASH) &&
- (flash->size > SPI_FLASH_16MB_BOUN << 1))) {
+ (mtd->size > SPI_FLASH_16MB_BOUN << 1))) {
puts("SF: Warning - Only lower 16MiB accessible,");
puts(" Full access #define CONFIG_SPI_FLASH_BAR\n");
}
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
index 603c6bc..a88d74e 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -14,9 +14,17 @@
#include <malloc.h>
#include <spi.h>
#include <spi_flash.h>
+#include <linux/mtd/mtd.h>

#include "sf_internal.h"

+struct spi_flash_priv {
+#ifndef CONFIG_DM_SPI_FLASH
+ struct spi_flash flash;
+#endif
+ struct mtd_info mtd;
+};
+
#ifndef CONFIG_DM_SPI_FLASH
struct spi_flash *spi_flash_probe_tail(struct spi_slave *bus)
{
@@ -123,12 +131,19 @@ int spi_flash_std_erase(struct udevice *dev, u32 offset, size_t len)

int spi_flash_std_probe(struct udevice *dev)
{
- struct spi_flash *flash = dev_get_uclass_priv(dev);
+ struct spi_flash_priv *priv = dev_get_priv(dev);
struct spi_slave *slave = dev_get_parent_priv(dev);
+ struct spi_flash *flash;
int ret;

- flash->dev = dev;
+ flash = dev_get_uclass_priv(dev);
+ flash->mtd = &priv->mtd;
+
flash->spi = slave;
+ flash->priv = priv;
+
+ priv->mtd.priv = flash;
+ flash->dev = dev;

/* Claim spi bus */
ret = spi_claim_bus(slave);
@@ -143,19 +158,16 @@ int spi_flash_std_probe(struct udevice *dev)
goto err_scan;
}

-#ifdef CONFIG_SPI_FLASH_MTD
- ret = spi_flash_mtd_register(flash);
+ ret = add_mtd_device(&priv->mtd);
if (ret) {
printf("SF: failed to register mtd device: %d\n", ret);
goto err_mtd;
}
-#endif
+
return ret;

-#ifdef CONFIG_SPI_FLASH_MTD
err_mtd:
spi_free_slave(slave);
-#endif
err_scan:
spi_release_bus(slave);
return ret;
@@ -177,7 +189,7 @@ U_BOOT_DRIVER(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),
+ .priv_auto_alloc_size = sizeof(struct spi_flash_priv),
.ops = &spi_flash_std_ops,
};

diff --git a/include/spi_flash.h b/include/spi_flash.h
index 721b358..15f7471 100644
--- a/include/spi_flash.h
+++ b/include/spi_flash.h
@@ -37,6 +37,7 @@ struct spi_slave;
* struct spi_flash - SPI flash structure
*
* @spi: SPI slave
+ * @mtd: point to a mtd_info structure
* @dev: SPI flash device
* @name: Name of SPI flash
* @dual_flash: Indicates dual flash memories - dual stacked, parallel
@@ -54,6 +55,7 @@ struct spi_slave;
* @write_cmd: Write cmd - page and quad program.
* @dummy_byte: Dummy cycles for read operation.
* @memory_map: Address of read-only SPI flash access
+ * @priv: the private data
* @flash_lock: lock a region of the SPI Flash
* @flash_unlock: unlock a region of the SPI Flash
* @flash_is_locked: check if a region of the SPI Flash is completely locked
@@ -67,6 +69,7 @@ struct spi_slave;
*/
struct spi_flash {
struct spi_slave *spi;
+ struct mtd_info *mtd;
#ifdef CONFIG_DM_SPI_FLASH
struct udevice *dev;
#endif
@@ -90,6 +93,7 @@ struct spi_flash {
u8 dummy_byte;

void *memory_map;
+ void *priv;

int (*flash_lock)(struct spi_flash *flash, u32 ofs, size_t len);
int (*flash_unlock)(struct spi_flash *flash, u32 ofs, size_t len);
--
1.9.1