[U-Boot] [PATCH 1/8] sf: Add MTD support to spi_flash

Heiko Schocher
2015-10-29T06:04:46Z

Hello Jgan,

Am 12.10.2015 um 21:54 schrieb Jagan Teki:
> 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@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(-)

Reviewed-by: Heiko Schocher <hs@denx.de>

bye,
Heiko
>
> 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);
>

--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany