[U-Boot] [PATCH 1/8] sf: Add MTD support to spi_flash
Jagan Teki
jteki at openedev.com
Mon Oct 12 21:54:08 CEST 2015
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.
Signed-off-by: Jagan Teki <jteki at openedev.com>
---
drivers/mtd/spi/sf_ops.c | 45 +++++++++++++++++++++++++--------------------
drivers/mtd/spi/sf_probe.c | 26 ++++++++++++++++++--------
include/spi_flash.h | 9 +++++----
3 files changed, 48 insertions(+), 32 deletions(-)
diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c
index 703099f..f5ee376 100644
--- a/drivers/mtd/spi/sf_ops.c
+++ b/drivers/mtd/spi/sf_ops.c
@@ -146,7 +146,7 @@ static int spi_flash_read_bar(struct spi_flash *flash, u8 idcode0)
u8 curr_bank = 0;
int ret;
- if (flash->size <= SPI_FLASH_16MB_BOUN)
+ if (flash->mtd->size <= SPI_FLASH_16MB_BOUN)
goto bank_end;
switch (idcode0) {
@@ -176,8 +176,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;
@@ -303,7 +303,7 @@ static int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset,
u8 cmd[SPI_FLASH_CMD_LEN];
int ret = -1;
- erase_size = flash->erase_size;
+ erase_size = mtd->erasesize;
if (offset % erase_size || len % erase_size) {
debug("SF: Erase offset/length not multiple of erase size\n");
return -1;
@@ -693,7 +693,7 @@ int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash)
return 0;
}
- if (flash->size != size) {
+ if (flash->mtd->size != size) {
debug("%s: Memory map must cover entire device\n", __func__);
return -1;
}
@@ -705,6 +705,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];
@@ -754,24 +755,27 @@ 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;
/* 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 (params->flags & SST_WR)
flash->flags |= SNOR_F_SST_WR;
if (params->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;
/* Compute the flash size */
flash->shift = (flash->dual_flash & SF_DUAL_PARALLEL_FLASH) ? 1 : 0;
@@ -790,27 +794,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);
@@ -882,8 +887,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");
@@ -891,9 +896,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 87ac33e..b8704e2 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -14,9 +14,15 @@
#include <malloc.h>
#include <spi.h>
#include <spi_flash.h>
+#include <linux/mtd/mtd.h>
#include "sf_internal.h"
+struct spi_flash_priv {
+ struct spi_flash flash;
+ struct mtd_info mtd;
+};
+
#ifndef CONFIG_DM_SPI_FLASH
struct spi_flash *spi_flash_probe_tail(struct spi_slave *bus)
{
@@ -123,12 +129,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_uclass_priv(dev);
struct spi_slave *slave = dev_get_parentdata(dev);
+ struct spi_flash *flash;
int ret;
- flash->dev = dev;
+ flash = &priv->flash;
+ 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 +156,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 +187,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 0732172..d0af8d3 100644
--- a/include/spi_flash.h
+++ b/include/spi_flash.h
@@ -17,6 +17,7 @@
#include <dm.h> /* Because we dereference struct udevice here */
#include <linux/types.h>
+#include <linux/mtd/mtd.h>
#ifndef CONFIG_SF_DEFAULT_SPEED
# define CONFIG_SF_DEFAULT_SPEED 1000000
@@ -36,16 +37,15 @@ struct spi_slave;
/**
* struct spi_flash - SPI flash structure
*
+ * @mtd: point to a mtd_info structure
* @spi: SPI slave
* @dev: SPI flash device
* @name: Name of SPI flash
* @dual_flash: Indicates dual flash memories - dual stacked, parallel
* @shift: Flash shift useful in dual parallel
* @flags: Indication of spi flash flags
- * @size: Total flash size
* @page_size: Write (page) size
* @sector_size: Sector size
- * @erase_size: Erase size
* @bank_read_cmd: Bank read cmd
* @bank_write_cmd: Bank write cmd
* @bank_curr: Current flash bank
@@ -54,6 +54,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
* @read: Flash read ops: Read len bytes at offset into buf
* Supported cmds: Fast Array Read
* @write: Flash write ops: Write len bytes from buf into offset
@@ -63,6 +64,7 @@ struct spi_slave;
* return 0 - Success, 1 - Failure
*/
struct spi_flash {
+ struct mtd_info *mtd;
struct spi_slave *spi;
#ifdef CONFIG_DM_SPI_FLASH
struct udevice *dev;
@@ -72,10 +74,8 @@ struct spi_flash {
u8 shift;
u16 flags;
- u32 size;
u32 page_size;
u32 sector_size;
- u32 erase_size;
#ifdef CONFIG_SPI_FLASH_BAR
u8 bank_read_cmd;
u8 bank_write_cmd;
@@ -87,6 +87,7 @@ struct spi_flash {
u8 dummy_byte;
void *memory_map;
+ void *priv;
int (*read)(struct spi_flash *flash, u32 offset, size_t len, void *buf);
int (*write)(struct spi_flash *flash, u32 offset, size_t len,
const void *buf);
--
1.9.1
More information about the U-Boot
mailing list