[U-Boot] [PATCH v6 1/4] mtd, spi: add MTD layer driver
Jagan Teki
jteki at openedev.com
Tue Jun 16 10:52:43 CEST 2015
Hi Heiko,
On 16 June 2015 at 14:13, Heiko Schocher denx <hs at denx.de> wrote:
> Hello Jagan,
>
>
> Am 16.06.2015 um 10:04 schrieb Jagan Teki:
>>
>> Hi Heiko,
>>
>> On 20 May 2015 at 12:16, Heiko Schocher <hs at denx.de> wrote:
>>>
>>> Hello Jagan,
>>>
>>> Am 19.05.2015 22:09, schrieb Jagan Teki:
>>>>
>>>>
>>>> Hi Heiko,
>>>>
>>>> I have tested this sf-mtd stuff, please see below and enabled prints
>>>> in all the func calls.
>>>
>>>
>>>
>>> Thanks for testing!
>>>
>>>
>>>> zynq-uboot> mtdparts add nor0 0x10000 at 0x0 env
>>>> mtdparts variable not set, see 'help mtdparts'
>>>> zynq-uboot> mtdparts
>>>>
>>>> device nor0 <zynq-sf.0>, # parts = 1
>>>> #: name size offset mask_flags
>>>> 0: env 0x00010000 0x00000000 0
>>>>
>>>> active partition: nor0,0 - (env) 0x00010000 @ 0x00000000
>>>>
>>>> defaults:
>>>> mtdids : nor0=zynq-sf.0
>>>> mtdparts: none
>>>> zynq-uboot> sf erase env 0x10000
>>>> spi_flash_erase
>>>> spi_flash_cmd_erase_ops
>>>> SF: erase d8 0 0 0 (0)
>>>> SF: 65536 bytes @ 0x0 Erased: OK
>>>> zynq-uboot> mw.b 0x100 0x44 0x10000
>>>> zynq-uboot> sf write 0x100 env
>>>> device 0 offset 0x0, size 0x10000
>>>> spi_flash_cmd_write_ops
>>>> SF: 65536 bytes @ 0x0 Written: OK
>>>> zynq-uboot> sf read 0x40000 env
>>>> device 0 offset 0x0, size 0x10000
>>>> spi_flash_cmd_read_ops
>>>> off = 0x10000, len = 0
>>>> SF: 65536 bytes @ 0x0 Read: OK
>>>> zynq-uboot> cmp.b 0x100 0x40000 0x10000
>>>> Total of 65536 byte(s) were the same
>>>
>>>
>>>
>>> Looks good ...
>>>
>>>> I wonder none of the sf_mtd_info._* getting called, why?
>>>
>>>
>>>
>>> Hmm.. good question .. you use the "sf ..." commands, they do not
>>> use the mtd interface, right?
>>
>>
>> I'm fine with the testing, but mtd code in sf seems used only for in UBI
>> only.
>
>
> a fast "grep mtd_read" in the u-boot source shows, that yaffs2
> also uses mtd_read ... I did no yaffs2 test, but I think, yaffs2 can
> be used also with spi flashes now ... if this is wise, I don;t know ...
>
> I tested with UBI on a spi flash, and that works ... in the same
> fashion it currently does on nand for example ...
>
>> I wouldn't see this is a better approach where mtd code is considered as
>> to
>> be unknown thing for sf.
>
>
> I do not understand you here complete ...
>
> drivers/mtd/spi/sf_mtd.c
>
> adds just spi flash specific functions to integrate spi flashes
> into mtd ... and mtd users can then read/write/erase
> with the mtd_* functions ...
>
> Maybe someone has time to convert common/sf.c to use them?
>
> So, the final question is, can this patches go into mainline?
The only point I'm concerned here is If I need to use sf with mtd support
without using ubifs or any flash filesystem, the code in sf_mtd.c ops becomes
unused.
This seems to be a code size increasing factor which is obviously not a good
point for bootloader atleast for u-boot, what do you think?
I agreed your concerned for someone may add support to common/cmd_sf.c
in future, but I'm bit worried to go this.
>
>>> I tested this functions with using UBI on the SPI NOR on the
>>> aristainetos and aristianetos2 boards... I added for example in
>>>
>>> diff --git a/drivers/mtd/spi/sf_mtd.c b/drivers/mtd/spi/sf_mtd.c
>>> index 0b9cb62..6063ed7 100644
>>> --- a/drivers/mtd/spi/sf_mtd.c
>>> +++ b/drivers/mtd/spi/sf_mtd.c
>>> @@ -39,6 +40,7 @@ static int spi_flash_mtd_read(struct mtd_info *mtd,
>>> loff_t
>>> from, size_t len,
>>> struct spi_flash *flash = mtd->priv;
>>> int err;
>>>
>>> +printf("%s ****\n", __func__);
>>> err = spi_flash_read(flash, from, len, buf);
>>> if (!err)
>>> *retlen = len;
>>>
>>> and see:
>>>
>>> => sf probe
>>> SF: Detected N25Q128A with page size 256 Bytes, erase size 64 KiB, total
>>> 16
>>> MiB
>>> => mtdparts
>>>
>>> device nor0 <spi3.1>, # parts = 4
>>> #: name size offset mask_flags
>>> 0: u-boot 0x000d0000 0x00000000 0
>>> 1: env 0x00010000 0x000d0000 0
>>> 2: env-red 0x00010000 0x000e0000 0
>>> 3: rescue-system 0x00f10000 0x000f0000 0
>>>
>>> device nand0 <gpmi-nand>, # parts = 1
>>> #: name size offset mask_flags
>>> 0: ubi 0x40000000 0x00000000 0
>>>
>>> active partition: nor0,0 - (u-boot) 0x000d0000 @ 0x00000000
>>>
>>> defaults:
>>> mtdids : none
>>> mtdparts: none
>>> => ubi part rescue-system
>>> UBI: default fastmap pool size: 10
>>> UBI: default fastmap WL pool size: 25
>>> UBI: attaching mtd2 to ubi0
>>> UBI DBG gen (pid 1): sizeof(struct ubi_ainf_peb) 48
>>> UBI DBG gen (pid 1): sizeof(struct ubi_wl_entry) 20
>>> UBI DBG gen (pid 1): min_io_size 1
>>> UBI DBG gen (pid 1): max_write_size 256
>>> UBI DBG gen (pid 1): hdrs_min_io_size 1
>>> UBI DBG gen (pid 1): ec_hdr_alsize 64
>>> UBI DBG gen (pid 1): vid_hdr_alsize 64
>>> UBI DBG gen (pid 1): vid_hdr_offset 64
>>> UBI DBG gen (pid 1): vid_hdr_aloffset 64
>>> UBI DBG gen (pid 1): vid_hdr_shift 0
>>> UBI DBG gen (pid 1): leb_start 128
>>> UBI DBG gen (pid 1): max_erroneous 24
>>> UBI DBG gen (pid 1): process PEB 0
>>> UBI DBG bld (pid 1): scan PEB 0
>>> UBI DBG io (pid 1): read EC header from PEB 0
>>> UBI DBG io (pid 1): read 64 bytes from PEB 0:0
>>> spi_flash_mtd_read ****
>>> UBI DBG io (pid 1): read VID header from PEB 0
>>> UBI DBG io (pid 1): read 64 bytes from PEB 0:64
>>> spi_flash_mtd_read ****
>>> [...]
>>>
>>> UBI uses the MTD layer ... the sf command not ...
>>> Hope this helps?
>>>
>>> bye,
>>> Heiko
>>>
>>>
>>>> On 27 April 2015 at 11:12, Heiko Schocher <hs at denx.de> wrote:
>>>>>
>>>>>
>>>>> From: Daniel Schwierzeck <daniel.schwierzeck at gmail.com>
>>>>>
>>>>> 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.
>>>>>
>>>>> Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck at gmail.com>
>>>>> Signed-off-by: Heiko Schocher <hs at denx.de>
>>>>>
>>>>> ---
>>>>>
>>>>> Changes in v6: None
>>>>> Changes in v2:
>>>>> - add comment from Daniel Schwierzeck:
>>>>> fix compile error from original patch with
>>>>> "static inline" rather than "static __maybe_unused"
>>>>> Series-changes: 3
>>>>> - rebase with d6c1ffc7d23f4fe4ae8c91101861055b8e1501b6
>>>>> Series-changes: 4
>>>>> - rebased against 385a08a60f042061b004642d6b9bb6cfb794ad5a
>>>>> Series-changes: 5
>>>>> - no changes
>>>>> Series-changes: 6
>>>>> - add comments from Jagan Teki:
>>>>> move code, which checks if flash pointer is used
>>>>> into a new patch.
>>>>> - use #ifdef in Code
>>>>> - call mtd register before the spi_release_bus
>>>>>
>>>>> README | 3 ++
>>>>> common/cmd_sf.c | 2 -
>>>>> drivers/mtd/spi/Makefile | 1 +
>>>>> drivers/mtd/spi/sf_internal.h | 5 ++
>>>>> drivers/mtd/spi/sf_mtd.c | 104
>>>>> ++++++++++++++++++++++++++++++++++++++++++
>>>>> drivers/mtd/spi/sf_probe.c | 10 ++--
>>>>> 6 files changed, 119 insertions(+), 6 deletions(-)
>>>>> create mode 100644 drivers/mtd/spi/sf_mtd.c
>>>>>
>>>>> diff --git a/README b/README
>>>>> index fc1fd52..36f6fc9 100644
>>>>> --- a/README
>>>>> +++ b/README
>>>>> @@ -3097,6 +3097,9 @@ CBFS (Coreboot Filesystem) support
>>>>> operation will not execute. The only way to exit this
>>>>> hardware-protected mode is to drive W#/VPP HIGH.
>>>>>
>>>>> + CONFIG_SPI_FLASH_MTD
>>>>> + add MTD translation layer driver.
>>>>> +
>>>>> - SystemACE Support:
>>>>> CONFIG_SYSTEMACE
>>>>>
>>>>> diff --git a/common/cmd_sf.c b/common/cmd_sf.c
>>>>> index 6aabf39..0250011 100644
>>>>> --- a/common/cmd_sf.c
>>>>> +++ b/common/cmd_sf.c
>>>>> @@ -139,8 +139,6 @@ static int do_spi_flash_probe(int argc, char *
>>>>> const
>>>>> argv[])
>>>>> return 1;
>>>>> }
>>>>>
>>>>> - if (flash)
>>>>> - spi_flash_free(flash);
>>>>> flash = new;
>>>>> #endif
>>>>>
>>>>> diff --git a/drivers/mtd/spi/Makefile b/drivers/mtd/spi/Makefile
>>>>> index c61b784e..f8580cd 100644
>>>>> --- a/drivers/mtd/spi/Makefile
>>>>> +++ b/drivers/mtd/spi/Makefile
>>>>> @@ -17,5 +17,6 @@ obj-$(CONFIG_SPI_FLASH) += sf_probe.o
>>>>> #endif
>>>>> obj-$(CONFIG_CMD_SF) += sf.o
>>>>> obj-$(CONFIG_SPI_FLASH) += sf_ops.o sf_params.o
>>>>> +obj-$(CONFIG_SPI_FLASH_MTD) += sf_mtd.o
>>>>> obj-$(CONFIG_SPI_FLASH_SANDBOX) += sandbox.o
>>>>> obj-$(CONFIG_SPI_M95XXX) += eeprom_m95xxx.o
>>>>> diff --git a/drivers/mtd/spi/sf_internal.h
>>>>> b/drivers/mtd/spi/sf_internal.h
>>>>> index 785f7a9..8a2eb6e 100644
>>>>> --- a/drivers/mtd/spi/sf_internal.h
>>>>> +++ b/drivers/mtd/spi/sf_internal.h
>>>>> @@ -221,4 +221,9 @@ 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);
>>>>> +#endif
>>>>> +
>>>>> #endif /* _SF_INTERNAL_H_ */
>>>>> diff --git a/drivers/mtd/spi/sf_mtd.c b/drivers/mtd/spi/sf_mtd.c
>>>>> new file mode 100644
>>>>> index 0000000..0b9cb62
>>>>> --- /dev/null
>>>>> +++ b/drivers/mtd/spi/sf_mtd.c
>>>>> @@ -0,0 +1,104 @@
>>>>> +/*
>>>>> + * Copyright (C) 2012-2014 Daniel Schwierzeck,
>>>>> daniel.schwierzeck at gmail.com
>>>>> + *
>>>>> + * SPDX-License-Identifier: GPL-2.0+
>>>>> + */
>>>>> +
>>>>> +#include <common.h>
>>>>> +#include <malloc.h>
>>>>> +#include <asm/errno.h>
>>>>> +#include <linux/mtd/mtd.h>
>>>>> +#include <spi_flash.h>
>>>>> +
>>>>> +static struct mtd_info sf_mtd_info;
>>>>> +static char sf_mtd_name[8];
>>>>> +
>>>>> +static int spi_flash_mtd_erase(struct mtd_info *mtd, struct erase_info
>>>>> *instr)
>>>>> +{
>>>>> + struct spi_flash *flash = mtd->priv;
>>>>> + int err;
>>>>> +
>>>>> + instr->state = MTD_ERASING;
>>>>> +
>>>>> + err = spi_flash_erase(flash, instr->addr, instr->len);
>>>>> + if (err) {
>>>>> + instr->state = MTD_ERASE_FAILED;
>>>>> + instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
>>>>> + return -EIO;
>>>>> + }
>>>>> +
>>>>> + instr->state = MTD_ERASE_DONE;
>>>>> + mtd_erase_callback(instr);
>>>>> +
>>>>> + return 0;
>>>>> +}
>>>>> +
>>>>> +static int spi_flash_mtd_read(struct mtd_info *mtd, loff_t from,
>>>>> size_t
>>>>> len,
>>>>> + size_t *retlen, u_char *buf)
>>>>> +{
>>>>> + struct spi_flash *flash = mtd->priv;
>>>>> + int err;
>>>>> +
>>>>> + err = spi_flash_read(flash, from, len, buf);
>>>>> + if (!err)
>>>>> + *retlen = len;
>>>>> +
>>>>> + return err;
>>>>> +}
>>>>> +
>>>>> +static int spi_flash_mtd_write(struct mtd_info *mtd, loff_t to, size_t
>>>>> len,
>>>>> + size_t *retlen, const u_char *buf)
>>>>> +{
>>>>> + struct spi_flash *flash = mtd->priv;
>>>>> + int err;
>>>>> +
>>>>> + err = spi_flash_write(flash, to, len, buf);
>>>>> + if (!err)
>>>>> + *retlen = len;
>>>>> +
>>>>> + return err;
>>>>> +}
>>>>> +
>>>>> +static void spi_flash_mtd_sync(struct mtd_info *mtd)
>>>>> +{
>>>>> +}
>>>>> +
>>>>> +static int spi_flash_mtd_number(void)
>>>>> +{
>>>>> +#ifdef CONFIG_SYS_MAX_FLASH_BANKS
>>>>> + return CONFIG_SYS_MAX_FLASH_BANKS;
>>>>> +#else
>>>>> + return 0;
>>>>> +#endif
>>>>> +}
>>>>> +
>>>>> +int spi_flash_mtd_register(struct spi_flash *flash)
>>>>> +{
>>>>> + memset(&sf_mtd_info, 0, sizeof(sf_mtd_info));
>>>>> + sprintf(sf_mtd_name, "nor%d", spi_flash_mtd_number());
>>>>> +
>>>>> + sf_mtd_info.name = sf_mtd_name;
>>>>> + sf_mtd_info.type = MTD_NORFLASH;
>>>>> + sf_mtd_info.flags = MTD_CAP_NORFLASH;
>>>>> + sf_mtd_info.writesize = 1;
>>>>> + sf_mtd_info.writebufsize = flash->page_size;
>>>>> +
>>>>> + sf_mtd_info._erase = spi_flash_mtd_erase;
>>>>> + sf_mtd_info._read = spi_flash_mtd_read;
>>>>> + sf_mtd_info._write = spi_flash_mtd_write;
>>>>> + sf_mtd_info._sync = spi_flash_mtd_sync;
>>>>
>>>>
>>>>
>>>> Even if I remove this every thing as usual, like "sf erase" will call
>>>> from cmd_sf
>>>> there it calls mtd_arg_off_size, to detected off and size from
>>>> partition and after
>>>> sf_flash will call erase ops from sf_ops.c.
>>>>
>>>> As it's a mtd call, I thought sf_mtd_into._erase will intern calls
>>>> erase ops from sf_ops.c
>>>> What is this behavior could you please help me?
>>>>
>>>>> +
>>>>> + sf_mtd_info.size = flash->size;
>>>>> + sf_mtd_info.priv = flash;
>>>>> +
>>>>> + /* Only uniform flash devices for now */
>>>>> + sf_mtd_info.numeraseregions = 0;
>>>>> + sf_mtd_info.erasesize = flash->sector_size;
>>>>> +
>>>>> + return add_mtd_device(&sf_mtd_info);
>>>>> +}
>>>>> +
>>>>> +void spi_flash_mtd_unregister(void)
>>>>> +{
>>>>> + del_mtd_device(&sf_mtd_info);
>>>>> +}
>>>>> diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
>>>>> index d19138d..2342972 100644
>>>>> --- a/drivers/mtd/spi/sf_probe.c
>>>>> +++ b/drivers/mtd/spi/sf_probe.c
>>>>> @@ -397,10 +397,9 @@ int spi_flash_probe_slave(struct spi_slave *spi,
>>>>> struct spi_flash *flash)
>>>>> if (spi_enable_wp_pin(flash))
>>>>> puts("Enable WP pin failed\n");
>>>>>
>>>>> - /* Release spi bus */
>>>>> - spi_release_bus(spi);
>>>>> -
>>>>> - return 0;
>>>>> +#ifdef CONFIG_SPI_FLASH_MTD
>>>>> + ret = spi_flash_mtd_register(flash);
>>>>> +#endif
>>>>>
>>>>> err_read_id:
>>>>> spi_release_bus(spi);
>>>>> @@ -450,6 +449,9 @@ struct spi_flash *spi_flash_probe_fdt(const void
>>>>> *blob, int slave_node,
>>>>>
>>>>> void spi_flash_free(struct spi_flash *flash)
>>>>> {
>>>>> +#ifdef CONFIG_SPI_FLASH_MTD
>>>>> + spi_flash_mtd_unregister();
>>>>> +#endif
>>>>> spi_free_slave(flash->spi);
>>>>> free(flash);
>>>>> }
>>>>> --
>>>>> 2.1.0
thanks!
--
Jagan | openedev.
More information about the U-Boot
mailing list