Commit 9fe6d8716e090f3b2dd3f4604acfced124b8a2fc

Authored by Daniel Schwierzeck
Committed by Jagan Teki
1 parent ecfbaa869a

mtd, spi: Add MTD layer driver

Add MTD layer driver for spi, original patch from:
http://git.denx.de/?p=u-boot/u-boot-mips.git;a=commitdiff;h=bb246819cdc90493dd7089eaa51b9e639765cced

Changes from Heiko Schocher against this patch:
- Remove compile error if not defining CONFIG_SPI_FLASH_MTD:

  LD      drivers/mtd/spi/built-in.o
drivers/mtd/spi/sf_probe.o: In function `spi_flash_mtd_unregister':
/home/hs/abb/imx6/u-boot/drivers/mtd/spi/sf_internal.h:168: multiple definition of `spi_flash_mtd_unregister'
drivers/mtd/spi/sf_params.o:/home/hs/abb/imx6/u-boot/drivers/mtd/spi/sf_internal.h:168: first defined here
drivers/mtd/spi/sf_ops.o: In function `spi_flash_mtd_unregister':
/home/hs/abb/imx6/u-boot/drivers/mtd/spi/sf_internal.h:168: multiple definition of `spi_flash_mtd_unregister'
drivers/mtd/spi/sf_params.o:/home/hs/abb/imx6/u-boot/drivers/mtd/spi/sf_internal.h:168: first defined here
make[1]: *** [drivers/mtd/spi/built-in.o] Fehler 1
make: *** [drivers/mtd/spi] Fehler 2

- Add a README entry.
- Add correct writebufsize, to fit with Linux v3.14
  MTD, UBI/UBIFS sync.

Note (From Jagan): For testing raw mtd parition erase/read/write operations
using cmd_sf, sf_mtd should be required to register the spi flash device to
MTD layer but the sf_mtd_info ops were not required until and unless if we
use any flash filesystem layer say for example UBI. Due to this the foot-print
got increased ~290bytes in non-UBI case here that should be acceptible.

Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
Signed-off-by: Heiko Schocher <hs@denx.de>
Tested-by: Jagannadh Teki <jteki@openedev.com>
Reviewed-by: Jagannadh Teki <jteki@openedev.com>

Showing 6 changed files with 125 additions and 7 deletions Side-by-side Diff

... ... @@ -3090,6 +3090,15 @@
3090 3090 memories can be connected with a given cs line.
3091 3091 Currently Xilinx Zynq qspi supports these type of connections.
3092 3092  
  3093 + CONFIG_SPI_FLASH_MTD spi-flash MTD layer
  3094 +
  3095 + Define this option to use mtd support for spi flash layer, this
  3096 + adapter is for translating mtd_read/mtd_write commands into
  3097 + spi_flash_read/spi_flash_write commands. It is not intended to
  3098 + use it within sf_cmd or the SPI flash subsystem. Such an adapter
  3099 + is needed for subsystems like UBI which can only operate on top
  3100 + of the MTD layer.
  3101 +
3093 3102 - SystemACE Support:
3094 3103 CONFIG_SYSTEMACE
3095 3104  
... ... @@ -139,8 +139,6 @@
139 139 return 1;
140 140 }
141 141  
142   - if (flash)
143   - spi_flash_free(flash);
144 142 flash = new;
145 143 #endif
146 144  
drivers/mtd/spi/Makefile
... ... @@ -18,6 +18,7 @@
18 18 obj-$(CONFIG_SF_DATAFLASH) += sf_dataflash.o
19 19 obj-$(CONFIG_CMD_SF) += sf.o
20 20 obj-$(CONFIG_SPI_FLASH) += sf_ops.o sf_params.o
  21 +obj-$(CONFIG_SPI_FLASH_MTD) += sf_mtd.o
21 22 obj-$(CONFIG_SPI_FLASH_SANDBOX) += sandbox.o
22 23 obj-$(CONFIG_SPI_M95XXX) += eeprom_m95xxx.o
drivers/mtd/spi/sf_internal.h
... ... @@ -218,5 +218,10 @@
218 218 int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
219 219 size_t len, void *data);
220 220  
  221 +#ifdef CONFIG_SPI_FLASH_MTD
  222 +int spi_flash_mtd_register(struct spi_flash *flash);
  223 +void spi_flash_mtd_unregister(void);
  224 +#endif
  225 +
221 226 #endif /* _SF_INTERNAL_H_ */
drivers/mtd/spi/sf_mtd.c
  1 +/*
  2 + * Copyright (C) 2012-2014 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
  3 + *
  4 + * SPDX-License-Identifier: GPL-2.0+
  5 + */
  6 +
  7 +#include <common.h>
  8 +#include <malloc.h>
  9 +#include <asm/errno.h>
  10 +#include <linux/mtd/mtd.h>
  11 +#include <spi_flash.h>
  12 +
  13 +static struct mtd_info sf_mtd_info;
  14 +static char sf_mtd_name[8];
  15 +
  16 +static int spi_flash_mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
  17 +{
  18 + struct spi_flash *flash = mtd->priv;
  19 + int err;
  20 +
  21 + instr->state = MTD_ERASING;
  22 +
  23 + err = spi_flash_erase(flash, instr->addr, instr->len);
  24 + if (err) {
  25 + instr->state = MTD_ERASE_FAILED;
  26 + instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
  27 + return -EIO;
  28 + }
  29 +
  30 + instr->state = MTD_ERASE_DONE;
  31 + mtd_erase_callback(instr);
  32 +
  33 + return 0;
  34 +}
  35 +
  36 +static int spi_flash_mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
  37 + size_t *retlen, u_char *buf)
  38 +{
  39 + struct spi_flash *flash = mtd->priv;
  40 + int err;
  41 +
  42 + err = spi_flash_read(flash, from, len, buf);
  43 + if (!err)
  44 + *retlen = len;
  45 +
  46 + return err;
  47 +}
  48 +
  49 +static int spi_flash_mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
  50 + size_t *retlen, const u_char *buf)
  51 +{
  52 + struct spi_flash *flash = mtd->priv;
  53 + int err;
  54 +
  55 + err = spi_flash_write(flash, to, len, buf);
  56 + if (!err)
  57 + *retlen = len;
  58 +
  59 + return err;
  60 +}
  61 +
  62 +static void spi_flash_mtd_sync(struct mtd_info *mtd)
  63 +{
  64 +}
  65 +
  66 +static int spi_flash_mtd_number(void)
  67 +{
  68 +#ifdef CONFIG_SYS_MAX_FLASH_BANKS
  69 + return CONFIG_SYS_MAX_FLASH_BANKS;
  70 +#else
  71 + return 0;
  72 +#endif
  73 +}
  74 +
  75 +int spi_flash_mtd_register(struct spi_flash *flash)
  76 +{
  77 + memset(&sf_mtd_info, 0, sizeof(sf_mtd_info));
  78 + sprintf(sf_mtd_name, "nor%d", spi_flash_mtd_number());
  79 +
  80 + sf_mtd_info.name = sf_mtd_name;
  81 + sf_mtd_info.type = MTD_NORFLASH;
  82 + sf_mtd_info.flags = MTD_CAP_NORFLASH;
  83 + sf_mtd_info.writesize = 1;
  84 + sf_mtd_info.writebufsize = flash->page_size;
  85 +
  86 + sf_mtd_info._erase = spi_flash_mtd_erase;
  87 + sf_mtd_info._read = spi_flash_mtd_read;
  88 + sf_mtd_info._write = spi_flash_mtd_write;
  89 + sf_mtd_info._sync = spi_flash_mtd_sync;
  90 +
  91 + sf_mtd_info.size = flash->size;
  92 + sf_mtd_info.priv = flash;
  93 +
  94 + /* Only uniform flash devices for now */
  95 + sf_mtd_info.numeraseregions = 0;
  96 + sf_mtd_info.erasesize = flash->sector_size;
  97 +
  98 + return add_mtd_device(&sf_mtd_info);
  99 +}
  100 +
  101 +void spi_flash_mtd_unregister(void)
  102 +{
  103 + del_mtd_device(&sf_mtd_info);
  104 +}
drivers/mtd/spi/sf_probe.c
... ... @@ -372,12 +372,10 @@
372 372 puts(" Full access #define CONFIG_SPI_FLASH_BAR\n");
373 373 }
374 374 #endif
  375 +#ifdef CONFIG_SPI_FLASH_MTD
  376 + ret = spi_flash_mtd_register(flash);
  377 +#endif
375 378  
376   - /* Release spi bus */
377   - spi_release_bus(spi);
378   -
379   - return 0;
380   -
381 379 err_read_id:
382 380 spi_release_bus(spi);
383 381 return ret;
... ... @@ -430,6 +428,9 @@
430 428  
431 429 void spi_flash_free(struct spi_flash *flash)
432 430 {
  431 +#ifdef CONFIG_SPI_FLASH_MTD
  432 + spi_flash_mtd_unregister();
  433 +#endif
433 434 spi_free_slave(flash->spi);
434 435 free(flash);
435 436 }