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

Heiko Schocher hs at denx.de
Thu Oct 29 07:04:46 CET 2015


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 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(-)

Reviewed-by: Heiko Schocher <hs at 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


More information about the U-Boot mailing list