spi, sf: add mtdparts feature to spi and sf commands
v2 cover spi, sf: add mtdparts feature to spi and sf commands
This patchserie add the popssibility to define mtd partitions on spi nor flash, and use this settings with the sf commands.
steps:
- add MTD layer driver for spi, original patch from:
http://git.denx.de/?p=u-boot/u-boot-mips.git;a=commitdiff;h=bb246819cdc90493dd7089eaa51b9e639765cced
and addapted it to current mainline.
- move common functions to get offset and size from cmdline nand command to extract offset and size from a mtd partition to common place "drivers/mtd/mtd_uboot.c" maybe another place is better?
- add to the sf command the possibility to use offset and size from the settings in mtdparts
With this patchset, the sf command looks now:
=> sf
sf - SPI flash sub-system
Usage:
sf probe [[bus:]cs] [hz] [mode] - init flash device on given SPI bus
and chip select
sf read addr offset|partition len - read `len' bytes starting at
offset' to memory at addr'
sf write addr offset|partition len - write `len' bytes from memory
at addr' to flash at offset'
sf erase offset|partition [+]len - erase len' bytes from offset'
+len' round up len' to block size
sf update addr offset|partition len - erase and write `len' bytes from memory
at addr' to flash at offset'
=>
for example "env" is defined in mtdparts:
=> sf read 13000000 env
device 0 offset 0xd0000, size 0x10000
SF: 65536 bytes @ 0xd0000 Read: OK
=>
There are the followings checkpatch warnings:
CHECK: Alignment should match open parenthesis
#153: FILE: common/cmd_nand.c:217:
+ if (arg_off(argv[2], &idx, &addr, &maxsize, &maxsize,
+ MTD_DEV_TYPE_NAND, nand_info[idx].size)) {
CHECK: Alignment should match open parenthesis
#179: FILE: common/cmd_nand.c:557:
+ if (arg_off(argv[3], &dev, &off, &size, &maxsize,
+ MTD_DEV_TYPE_NAND, nand_info[dev].size))
CHECK: Alignment should match open parenthesis
#193: FILE: common/cmd_nand.c:576:
+ if (arg_off_size(argc - 3, argv + 3, &dev, &off, &size,
+ &maxsize, MTD_DEV_TYPE_NAND,
total: 0 errors, 0 warnings, 3 checks, 361 lines checked
NOTE: Ignored message types: COMPLEX_MACRO CONSIDER_KSTRTO MINMAX MULTISTATEMENT_MACRO_USE_DO_WHILE NETWORKING_BLOCK_COMMENT_STYLE USLEEP_RANGE
20140714_ml_mtdparts/0002-mtd-nand-move-common-functions-from-cmd_nand.c-to-co.patch has style problems, please review.
I see not, why this warning pops up ...
- changes for v2:
- mtd-spi-add-MTD-layer-driver.patch
- add comment from Daniel Schwierzeck:
fix compile error from original patch with "static inline" rather than "static __maybe_unused"
Daniel Schwierzeck (1):
mtd, spi: add MTD layer driver
Heiko Schocher (2):
mtd, nand: move common functions from cmd_nand.c to common place spi, sf: use offset and size in sf cmd from mtdpartition
README | 3 + common/cmd_nand.c | 140 ++++++++---------------------------------- common/cmd_onenand.c | 19 ++---- common/cmd_sf.c | 59 +++++++++--------- drivers/mtd/Makefile | 4 +- drivers/mtd/mtd_uboot.c | 114 ++++++++++++++++++++++++++++++++++ drivers/mtd/spi/Makefile | 1 + drivers/mtd/spi/sf_internal.h | 13 ++++ drivers/mtd/spi/sf_mtd.c | 104 +++++++++++++++++++++++++++++++ drivers/mtd/spi/sf_probe.c | 5 ++ include/linux/mtd/mtd.h | 7 +++ 11 files changed, 310 insertions(+), 159 deletions(-) create mode 100644 drivers/mtd/mtd_uboot.c create mode 100644 drivers/mtd/spi/sf_mtd.c
Signature · 1 line
1.8.3.1
PATCH v2 1/3 mtd, spi: add MTD layer driver
From: Daniel Schwierzeck <[email protected]>
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.odrivers/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.
---
MAKEALL for ar, mips, powerc compiles clean
- changes for v2:
- add comment from Daniel Schwierzeck:
fix compile error from original patch with "static inline" rather than "static __maybe_unused"
README | 3 ++ common/cmd_sf.c | 9 ++-- drivers/mtd/spi/Makefile | 1 + drivers/mtd/spi/sf_internal.h | 13 ++++++ drivers/mtd/spi/sf_mtd.c | 104 ++++++++++++++++++++++++++++++++++++++++++ drivers/mtd/spi/sf_probe.c | 5 ++ 6 files changed, 131 insertions(+), 4 deletions(-) create mode 100644 drivers/mtd/spi/sf_mtd.c
README +3 -0
@@ -2926,6 +2926,9 @@ CBFS (Coreboot Filesystem) support memories can be connected with a given cs line. currently Xilinx Zynq qspi support these type of connections. + CONFIG_SPI_FLASH_MTD + add MTD translation layer driver. + - SystemACE Support: CONFIG_SYSTEMACE
common/cmd_sf.c +5 -4
@@ -121,16 +121,17 @@ static int do_spi_flash_probe(int argc, char * const argv[])return -1 ; } +if (flash) +spi_flash_free (flash); + new =spi_flash_probe (bus, cs, speed, mode); + flash = new; +if (!new) {printf ("Failed to initialize SPI flash at %u:%u\n" , bus, cs);return 1 ; } -if (flash) -spi_flash_free (flash); - flash = new; -return 0 ; }
drivers/mtd/spi/Makefile +1 -0
@@ -12,6 +12,7 @@ endif obj-$(CONFIG_CMD_SF) += sf.o obj-$(CONFIG_SPI_FLASH) += sf_params.o sf_probe.o sf_ops.o +obj-$(CONFIG_SPI_FLASH_MTD) += sf_mtd.o obj-$(CONFIG_SPI_FRAM_RAMTRON) += ramtron.o obj-$(CONFIG_SPI_FLASH_SANDBOX) += sandbox.o obj-$(CONFIG_SPI_M95XXX) += eeprom_m95xxx.o
drivers/mtd/spi/sf_internal.h +13 -0
@@ -156,4 +156,17 @@ int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd,int spi_flash_cmd_read_ops (struct spi_flash *flash,u32 offset,size_t len,void *data); +#ifdef CONFIG_SPI_FLASH_MTD +int spi_flash_mtd_register (struct spi_flash *flash); +void spi_flash_mtd_unregister (void ); +#else +static inline int spi_flash_mtd_register (struct spi_flash *flash) +{ +return 0 ; +} +static inline void spi_flash_mtd_unregister (void ) +{ +} +#endif +#endif /* _SF_INTERNAL_H_ */
drivers/mtd/spi/sf_mtd.c new file +104 -0
104 lines not on this page · raw message
drivers/mtd/spi/sf_probe.c +5 -0
@@ -355,6 +355,10 @@ static struct spi_flash *spi_flash_probe_slave(struct spi_slave *spi)/* Release spi bus */ spi_release_bus (spi); + ret =spi_flash_mtd_register (flash); +if (ret) + goto err_claim_bus; +return flash; err_read_id:
@@ -386,6 +390,7 @@ struct spi_flash *spi_flash_probe_fdt(const void *blob, int slave_node,void spi_flash_free (struct spi_flash *flash) { +spi_flash_mtd_unregister ();spi_free_slave (flash->spi);free (flash); }
Signature · 1 line
1.8.3.1
PATCH v2 2/3 mtd, nand: move common functions from cmd_nand.c to common place
In reply to Heiko Schochermove common functions from cmd_nand.c (for calculating offset and size from cmdline paramter) to common place, so they could used from other commands which use mtd partitions.
For onenand the arg_off_size() is left in common/cmd_onenand.c. It should use now the common arg_off() function, but as I could not test onenand I let it there ...
---
- changes for v2:
none
common/cmd_nand.c | 140 +++++++++--------------------------------------- common/cmd_onenand.c | 19 +++---- drivers/mtd/Makefile | 4 +- drivers/mtd/mtd_uboot.c | 114 +++++++++++++++++++++++++++++++++++++++ include/linux/mtd/mtd.h | 7 +++ 5 files changed, 154 insertions(+), 130 deletions(-) create mode 100644 drivers/mtd/mtd_uboot.c
common/cmd_nand.c +25 -115
@@ -133,115 +133,6 @@ static int set_dev(int dev)return 0 ; } -static inline int str2off (const char *p,loff_t *num) -{ -char *endptr; - - *num =simple_strtoull (p, &endptr,16 ); -return *p !='\0' && *endptr =='\0' ; -} - -static inline int str2long (const char *p,ulong *num) -{ -char *endptr; - - *num =simple_strtoul (p, &endptr,16 ); -return *p !='\0' && *endptr =='\0' ; -} - -static int get_part (const char *partname,int *idx,loff_t *off,loff_t *size, -loff_t *maxsize) -{ -#ifdef CONFIG_CMD_MTDPARTS -struct mtd_device *dev; -struct part_info *part; -u8 pnum; -int ret; - - ret =mtdparts_init (); -if (ret) -return ret; - - ret =find_dev_and_part (partname, &dev, &pnum, &part); -if (ret) -return ret; - -if (dev->id->type !=MTD_DEV_TYPE_NAND ) { -puts ("not a NAND device\n" ); -return -1 ; - } - - *off = part->offset; - *size = part->size; - *maxsize = part->size; - *idx = dev->id->num; - - ret =set_dev (*idx); -if (ret) -return ret; - -return 0 ; -#else -puts ("offset is not a number\n" ); -return -1 ; -#endif -} - -static int arg_off (const char *arg,int *idx,loff_t *off,loff_t *size, -loff_t *maxsize) -{ -if (!str2off (arg, off)) -return get_part (arg, idx, off, size, maxsize); - -if (*off >= nand_info[*idx].size) { -puts ("Offset exceeds device limit\n" ); -return -1 ; - } - - *maxsize = nand_info[*idx].size - *off; - *size = *maxsize; -return 0 ; -} - -static int arg_off_size (int argc,char *const argv[],int *idx, -loff_t *off,loff_t *size,loff_t *maxsize) -{ -int ret; - -if (argc ==0 ) { - *off =0 ; - *size = nand_info[*idx].size; - *maxsize = *size; - goto print; - } - - ret =arg_off (argv[0 ], idx, off, size, maxsize); -if (ret) -return ret; - -if (argc ==1 ) - goto print; - -if (!str2off (argv[1 ], size)) { -printf ("'%s' is not a number\n" , argv[1 ]); -return -1 ; - } - -if (*size > *maxsize) { -puts ("Size exceeds partition or device limit\n" ); -return -1 ; - } - -print: -printf ("device %d " , *idx); -if (*size == nand_info[*idx].size) -puts ("whole chip\n" ); -else -printf ("offset 0x%llx, size 0x%llx\n" , - (unsigned long long )*off, (unsigned long long )*size); -return 0 ; -} -#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK static void print_status (ulong start,ulong end,ulong erasesize,int status) {
@@ -322,7 +213,12 @@ int do_nand_env_oob(cmd_tbl_t *cmdtp, int argc, char *const argv[]) goto usage;/* We don't care about size, or maxsize. */ -if (arg_off (argv[2 ], &idx, &addr, &maxsize, &maxsize)) { +if (arg_off (argv[2 ], &idx, &addr, &maxsize, &maxsize, +MTD_DEV_TYPE_NAND , nand_info[idx].size)) { +puts ("Offset or partition name expected\n" ); +return 1 ; + } +if (set_dev (idx)) {puts ("Offset or partition name expected\n" );return 1 ; }
@@ -592,7 +488,10 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])printf ("\nNAND %s: " , cmd);/* skip first two or three arguments, look for offset and size */ if (arg_off_size (argc - o, argv + o, &dev, &off, &size, - &maxsize) !=0 ) + &maxsize,MTD_DEV_TYPE_NAND , nand_info[dev].size) !=0 ) +return 1 ; + +if (set_dev (dev))return 1 ; nand = &nand_info[dev];
@@ -654,7 +553,11 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])if (s && !strcmp (s,".raw" )) { raw =1 ; -if (arg_off (argv[3 ], &dev, &off, &size, &maxsize)) +if (arg_off (argv[3 ], &dev, &off, &size, &maxsize, +MTD_DEV_TYPE_NAND , nand_info[dev].size)) +return 1 ; + +if (set_dev (dev))return 1 ;if (argc >4 && !str2long (argv[4 ], &pagecount)) {
@@ -669,8 +572,12 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) rwsize = pagecount * (nand->writesize + nand->oobsize); }else { -if (arg_off_size (argc -3 , argv +3 , &dev, - &off, &size, &maxsize) !=0 ) +if (arg_off_size (argc -3 , argv +3 , &dev, &off, &size, + &maxsize,MTD_DEV_TYPE_NAND , + nand_info[dev].size) !=0 ) +return 1 ; + +if (set_dev (dev))return 1 ;/* size is unspecified */
@@ -816,7 +723,10 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) allexcept =1 ;if (arg_off_size (argc -2 , argv +2 , &dev, &off, &size, - &maxsize) <0 ) + &maxsize,MTD_DEV_TYPE_NAND , nand_info[dev].size) <0 ) +return 1 ; + +if (set_dev (dev))return 1 ;if (!nand_unlock (&nand_info[dev], off, size, allexcept)) {
common/cmd_onenand.c +6 -13
@@ -24,15 +24,8 @@ static struct mtd_info *mtd;static loff_t next_ofs;static loff_t skip_ofs; -static inline int str2long (char *p,ulong *num) -{ -char *endptr; - - *num =simple_strtoul (p, &endptr,16 ); -return (*p !='\0' && *endptr =='\0' ) ?1 :0 ; -} - -static int arg_off_size (int argc,char *const argv[],ulong *off,size_t *size) +static int arg_off_size_onenand (int argc,char *const argv[],ulong *off, +size_t *size) {if (argc >=1 ) {if (!(str2long (argv[0 ], off))) {
@@ -399,7 +392,7 @@ static int do_onenand_read(cmd_tbl_t * cmdtp, int flag, int argc, char * const a addr = (ulong )simple_strtoul (argv[1 ],NULL ,16 );printf ("\nOneNAND read: " ); -if (arg_off_size (argc -2 , argv +2 , &ofs, &len) !=0 ) +if (arg_off_size_onenand (argc -2 , argv +2 , &ofs, &len) !=0 )return 1 ; ret =onenand_block_read (ofs, len, &retlen, (u8 *)addr, oob);
@@ -425,7 +418,7 @@ static int do_onenand_write(cmd_tbl_t * cmdtp, int flag, int argc, char * const addr = (ulong )simple_strtoul (argv[1 ],NULL ,16 );printf ("\nOneNAND write: " ); -if (arg_off_size (argc -2 , argv +2 , &ofs, &len) !=0 ) +if (arg_off_size_onenand (argc -2 , argv +2 , &ofs, &len) !=0 )return 1 ; ret =onenand_block_write (ofs, len, &retlen, (u8 *)addr, withoob);
@@ -461,7 +454,7 @@ static int do_onenand_erase(cmd_tbl_t * cmdtp, int flag, int argc, char * constprintf ("\nOneNAND erase: " );/* skip first two or three arguments, look for offset and size */ -if (arg_off_size (argc, argv, &ofs, &len) !=0 ) +if (arg_off_size_onenand (argc, argv, &ofs, &len) !=0 )return 1 ; ret =onenand_block_erase (ofs, len, force);
@@ -486,7 +479,7 @@ static int do_onenand_test(cmd_tbl_t * cmdtp, int flag, int argc, char * const aprintf ("\nOneNAND test: " );/* skip first two or three arguments, look for offset and size */ -if (arg_off_size (argc -1 , argv +1 , &ofs, &len) !=0 ) +if (arg_off_size_onenand (argc -1 , argv +1 , &ofs, &len) !=0 )return 1 ; ret =onenand_block_test (ofs, len);
drivers/mtd/Makefile +2 -2
@@ -5,8 +5,8 @@ # SPDX-License-Identifier: GPL-2.0+ # -ifneq (,$(findstring y,$(CONFIG_MTD_DEVICE)$(CONFIG_CMD_NAND)$(CONFIG_CMD_ONENAND))) -obj-y += mtdcore.o +ifneq (,$(findstring y,$(CONFIG_MTD_DEVICE)$(CONFIG_CMD_NAND)$(CONFIG_CMD_ONENAND)$(CONFIG_CMD_SF))) +obj-y += mtdcore.o mtd_uboot.o endif obj-$(CONFIG_MTD_PARTITIONS) += mtdpart.o obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o
drivers/mtd/mtd_uboot.c new file +114 -0
114 lines not on this page · raw message
include/linux/mtd/mtd.h +7 -0
@@ -482,5 +482,12 @@ static inline int mtd_is_bitflip_or_eccerr(int err) {int add_mtd_device (struct mtd_info *mtd);int add_mtd_partitions (struct mtd_info *,const struct mtd_partition *,int );int del_mtd_partitions (struct mtd_info *); + +int str2off (const char *p,loff_t *num); +int str2long (const char *p,ulong *num); +int arg_off (const char *arg,int *idx,loff_t *off,loff_t *size, +loff_t *maxsize,int devtype,int chipsize); +int arg_off_size (int argc,char *const argv[],int *idx,loff_t *off, +loff_t *size,loff_t *maxsize,int devtype,int chipsize);#endif #endif /* __MTD_MTD_H__ */
Signature · 1 line
1.8.3.1
PATCH v2 3/3 spi, sf: use offset and size in sf cmd from mtdpartition
In reply to Heiko Schocherwith this patch, it is possible to get the offset and size information from the mtdpartiton setting in "mtdparts", similiar to the "nand" commandos.
=> sf
sf - SPI flash sub-system
Usage:
sf probe [[bus:]cs] [hz] [mode] - init flash device on given SPI bus
and chip select
sf read addr offset|partition len - read `len' bytes starting at
offset' to memory at addr'
sf write addr offset|partition len - write `len' bytes from memory
at addr' to flash at offset'
sf erase offset|partition [+]len - erase len' bytes from offset'
+len' round up len' to block size
sf update addr offset|partition len - erase and write `len' bytes from memory
at addr' to flash at offset'
=>
for example "env" is defined in mtdparts:
=> sf read 13000000 env
device 0 offset 0xd0000, size 0x10000
SF: 65536 bytes @ 0xd0000 Read: OK
=>
---
- changes for v2:
none
common/cmd_sf.c | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-)
common/cmd_sf.c +25 -25
@@ -10,6 +10,8 @@#include <div64.h> #include <malloc.h> #include <spi_flash.h> +#include <jffs2/jffs2.h> +#include <linux/mtd/mtd.h> #include <asm/io.h>
@@ -244,23 +246,21 @@ static int spi_flash_update(struct spi_flash *flash, u32 offset,static int do_spi_flash_read_write (int argc,char *const argv[]) {unsigned long addr; -unsigned long offset; -unsigned long len;void *buf;char *endp;int ret =1 ; +int dev =0 ; +loff_t offset, len, maxsize; -if (argc <4 ) +if (argc <3 )return -1 ; addr =simple_strtoul (argv[1 ], &endp,16 );if (*argv[1 ] ==0 || *endp !=0 )return -1 ; - offset =simple_strtoul (argv[2 ], &endp,16 ); -if (*argv[2 ] ==0 || *endp !=0 ) -return -1 ; - len =simple_strtoul (argv[3 ], &endp,16 ); -if (*argv[3 ] ==0 || *endp !=0 ) + +if (arg_off_size (argc -2 , &argv[2 ], &dev, &offset, &len, &maxsize, +MTD_DEV_TYPE_NOR , flash->size))return -1 ;/* Consistency checking */
@@ -299,31 +299,31 @@ static int do_spi_flash_read_write(int argc, char * const argv[])static int do_spi_flash_erase (int argc,char *const argv[]) { -unsigned long offset; -unsigned long len; -char *endp;int ret; +int dev =0 ; +loff_t offset, len, maxsize; +ulong size;if (argc <3 )return -1 ; - offset =simple_strtoul (argv[1 ], &endp,16 ); -if (*argv[1 ] ==0 || *endp !=0 ) +if (arg_off (argv[1 ], &dev, &offset, &len, &maxsize, +MTD_DEV_TYPE_NOR , flash->size))return -1 ; - ret =sf_parse_len_arg (argv[2 ], &len); + ret =sf_parse_len_arg (argv[2 ], &size);if (ret !=1 )return -1 ;/* Consistency checking */ -if (offset + len > flash->size) { +if (offset + size > flash->size) {printf ("ERROR: attempting %s past flash size (%#x)\n" , argv[0 ], flash->size);return 1 ; } - ret =spi_flash_erase (flash, offset, len); -printf ("SF: %zu bytes @ %#x Erased: %s\n" , (size_t )len, (u32 )offset, + ret =spi_flash_erase (flash, offset, size); +printf ("SF: %zu bytes @ %#x Erased: %s\n" , (size_t )size, (u32 )offset, ret ?"ERROR" :"OK" );return ret ==0 ?0 :1 ;
@@ -545,13 +545,13 @@ U_BOOT_CMD("SPI flash sub-system" ,"probe [[bus:]cs] [hz] [mode] - init flash device on given SPI bus\n" " and chip select\n" -"sf read addr offset len - read `len' bytes starting at\n" -" `offset' to memory at `addr'\n" -"sf write addr offset len - write `len' bytes from memory\n" -" at `addr' to flash at `offset'\n" -"sf erase offset [+]len - erase `len' bytes from `offset'\n" -" `+len' round up `len' to block size\n" -"sf update addr offset len - erase and write `len' bytes from memory\n" -" at `addr' to flash at `offset'" +"sf read addr offset|partition len - read `len' bytes starting at\n" +" `offset' to memory at `addr'\n" +"sf write addr offset|partition len - write `len' bytes from memory\n" +" at `addr' to flash at `offset'\n" +"sf erase offset|partition [+]len - erase `len' bytes from `offset'\n" +" `+len' round up `len' to block size\n" +"sf update addr offset|partition len - erase and write `len' bytes from memory\n" +" at `addr' to flash at `offset'" SF_TEST_HELP );
Signature · 1 line
1.8.3.1