[PATCH v4 0/6] Introduce UBI block device

Hello!
This series adds support for the UBI block device, which allows to read/write data block by block. For example, it can now be used for BCB or Android AB command:
$ bcb load ubi 0 part_name
Tested only on SPI NAND, so bind is made only for SPI NAND drivers. Can be used with mtdblock device [1].
---
Changes V1 -> V2 [2]:
- Rebased over mtdblock v2 patchset [3]. - Compile UBI partitions support only if CONFIG_BLK option is enabled.
Changes V2 -> V3 [4]:
- Fix build warnings: use LBAF printf format string for lbaint_t types.
Changes V3 -> V4 [5]:
- Rebased over u-boot/master. - Fix build errors and warnings if CONFIG_BLK isn't enabled. - Fix failed tests in cases is ubiblock device isn't binded.
Links:
[1] https://lore.kernel.org/all/20240227100441.1811047-1-avromanov@salutedevices... [2] https://lore.kernel.org/all/20240306134906.1179285-1-avromanov@salutedevices... [3] https://lore.kernel.org/all/20240307130726.1582487-1-avromanov@salutedevices... [4] https://lore.kernel.org/all/20240325144148.3738195-1-avromanov@salutedevices... [5] https://lore.kernel.org/all/20240524111319.3512009-1-avromanov@salutedevices...
Alexey Romanov (6): ubi: allow to read from volume with offset ubi: allow to write to volume with offset drivers: introduce UBI block abstraction disk: don't try search for partition type if already set disk: support UBI partitions spinand: bind UBI block
cmd/ubi.c | 77 +++++++++++++++++++-- disk/part.c | 7 ++ drivers/block/blk-uclass.c | 1 + drivers/mtd/nand/spi/core.c | 8 ++- drivers/mtd/ubi/Makefile | 1 + drivers/mtd/ubi/block.c | 130 ++++++++++++++++++++++++++++++++++++ drivers/mtd/ubi/part.c | 99 +++++++++++++++++++++++++++ env/ubi.c | 16 ++--- include/part.h | 2 + include/ubi_uboot.h | 8 ++- 10 files changed, 332 insertions(+), 17 deletions(-) create mode 100644 drivers/mtd/ubi/block.c create mode 100644 drivers/mtd/ubi/part.c

Now user can pass an additional parameter 'offset' to ubi_volume_read() function.
Signed-off-by: Alexey Romanov avromanov@salutedevices.com Reviewed-by: Heiko Schocher hs@denx.de Acked-by: Heiko Schocher hs@denx.de --- cmd/ubi.c | 6 +++--- env/ubi.c | 6 +++--- include/ubi_uboot.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/cmd/ubi.c b/cmd/ubi.c index 0a6a80bdd1..2257f68498 100644 --- a/cmd/ubi.c +++ b/cmd/ubi.c @@ -420,13 +420,13 @@ int ubi_volume_write(char *volume, void *buf, size_t size) return ubi_volume_begin_write(volume, buf, size, size); }
-int ubi_volume_read(char *volume, char *buf, size_t size) +int ubi_volume_read(char *volume, char *buf, loff_t offset, size_t size) { int err, lnum, off, len, tbuf_size; void *tbuf; unsigned long long tmp; struct ubi_volume *vol; - loff_t offp = 0; + loff_t offp = offset; size_t len_read;
vol = ubi_find_volume(volume); @@ -787,7 +787,7 @@ static int do_ubi(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) }
if (argc == 3) { - return ubi_volume_read(argv[3], (char *)addr, size); + return ubi_volume_read(argv[3], (char *)addr, 0, size); } }
diff --git a/env/ubi.c b/env/ubi.c index 445d34fedb..661801d5a9 100644 --- a/env/ubi.c +++ b/env/ubi.c @@ -135,13 +135,13 @@ static int env_ubi_load(void) return -EIO; }
- read1_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)tmp_env1, + read1_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)tmp_env1, 0, CONFIG_ENV_SIZE); if (read1_fail) printf("\n** Unable to read env from %s:%s **\n", CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
- read2_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME_REDUND, + read2_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME_REDUND, 0, (void *)tmp_env2, CONFIG_ENV_SIZE); if (read2_fail) printf("\n** Unable to read redundant env from %s:%s **\n", @@ -172,7 +172,7 @@ static int env_ubi_load(void) return -EIO; }
- if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, buf, CONFIG_ENV_SIZE)) { + if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, buf, 0, CONFIG_ENV_SIZE)) { printf("\n** Unable to read env from %s:%s **\n", CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME); env_set_default(NULL, 0); diff --git a/include/ubi_uboot.h b/include/ubi_uboot.h index d7a8851094..a4be0feabb 100644 --- a/include/ubi_uboot.h +++ b/include/ubi_uboot.h @@ -49,7 +49,7 @@ extern int ubi_init(void); extern void ubi_exit(void); extern int ubi_part(char *part_name, const char *vid_header_offset); extern int ubi_volume_write(char *volume, void *buf, size_t size); -extern int ubi_volume_read(char *volume, char *buf, size_t size); +extern int ubi_volume_read(char *volume, char *buf, loff_t offset, size_t size);
extern struct ubi_device *ubi_devices[]; int cmd_ubifs_mount(char *vol_name);

Introduce ubi_volume_offset_write() helper, which allow to write to ubi volume with specified offset.
Signed-off-by: Alexey Romanov avromanov@salutedevices.com Reviewed-by: Heiko Schocher hs@denx.de Acked-by: Heiko Schocher hs@denx.de --- cmd/ubi.c | 71 +++++++++++++++++++++++++++++++++++++++++++-- env/ubi.c | 10 +++---- include/ubi_uboot.h | 2 +- 3 files changed, 74 insertions(+), 9 deletions(-)
diff --git a/cmd/ubi.c b/cmd/ubi.c index 2257f68498..df235829b9 100644 --- a/cmd/ubi.c +++ b/cmd/ubi.c @@ -415,9 +415,74 @@ int ubi_volume_begin_write(char *volume, void *buf, size_t size, return ubi_volume_continue_write(volume, buf, size); }
-int ubi_volume_write(char *volume, void *buf, size_t size) +static int ubi_volume_offset_write(char *volume, void *buf, loff_t offset, + size_t size) { - return ubi_volume_begin_write(volume, buf, size, size); + int lnum, len, tbuf_size, ret; + struct ubi_volume *vol; + loff_t off = offset; + void *tbuf; + + vol = ubi_find_volume(volume); + if (!vol) + return -ENODEV; + + if (size > vol->reserved_pebs * (ubi->leb_size - vol->data_pad)) + return -EINVAL; + + tbuf_size = vol->usable_leb_size; + tbuf = malloc_cache_aligned(tbuf_size); + if (!tbuf) + return -ENOMEM; + + lnum = off; + off = do_div(lnum, vol->usable_leb_size); + + do { + struct ubi_volume_desc desc = { + .vol = vol, + .mode = UBI_READWRITE, + }; + + len = size > tbuf_size ? tbuf_size : size; + if (off + len >= vol->usable_leb_size) + len = vol->usable_leb_size - off; + + ret = ubi_read(&desc, lnum, tbuf, 0, tbuf_size); + if (ret) { + pr_err("Failed to read leb %d (%d)\n", lnum, ret); + goto exit; + } + + memcpy(tbuf + off, buf, len); + + ret = ubi_leb_change(&desc, lnum, tbuf, tbuf_size); + if (ret) { + pr_err("Failed to write leb %d (%d)\n", lnum, ret); + goto exit; + } + + off += len; + if (off >= vol->usable_leb_size) { + lnum++; + off -= vol->usable_leb_size; + } + + buf += len; + size -= len; + } while (size); + +exit: + free(tbuf); + return ret; +} + +int ubi_volume_write(char *volume, void *buf, loff_t offset, size_t size) +{ + if (!offset) + return ubi_volume_begin_write(volume, buf, size, size); + + return ubi_volume_offset_write(volume, buf, offset, size); }
int ubi_volume_read(char *volume, char *buf, loff_t offset, size_t size) @@ -761,7 +826,7 @@ static int do_ubi(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) (void *)addr, size, full_size); } } else { - ret = ubi_volume_write(argv[3], (void *)addr, size); + ret = ubi_volume_write(argv[3], (void *)addr, 0, size); } if (!ret) { printf("%lld bytes written to volume %s\n", size, diff --git a/env/ubi.c b/env/ubi.c index 661801d5a9..6ae74a500b 100644 --- a/env/ubi.c +++ b/env/ubi.c @@ -54,7 +54,7 @@ static int env_ubi_save(void) if (gd->env_valid == ENV_VALID) { puts("Writing to redundant UBI... "); if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME_REDUND, - (void *)env_new, CONFIG_ENV_SIZE)) { + (void *)env_new, 0, CONFIG_ENV_SIZE)) { printf("\n** Unable to write env to %s:%s **\n", CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME_REDUND); @@ -63,7 +63,7 @@ static int env_ubi_save(void) } else { puts("Writing to UBI... "); if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, - (void *)env_new, CONFIG_ENV_SIZE)) { + (void *)env_new, 0, CONFIG_ENV_SIZE)) { printf("\n** Unable to write env to %s:%s **\n", CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME); @@ -93,7 +93,7 @@ static int env_ubi_save(void) return 1; }
- if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, (void *)env_new, + if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, (void *)env_new, 0, CONFIG_ENV_SIZE)) { printf("\n** Unable to write env to %s:%s **\n", CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME); @@ -197,7 +197,7 @@ static int env_ubi_erase(void) memset(env_buf, 0x0, CONFIG_ENV_SIZE);
if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, - (void *)env_buf, CONFIG_ENV_SIZE)) { + (void *)env_buf, 0, CONFIG_ENV_SIZE)) { printf("\n** Unable to erase env to %s:%s **\n", CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME); @@ -205,7 +205,7 @@ static int env_ubi_erase(void) } if (IS_ENABLED(CONFIG_SYS_REDUNDAND_ENVIRONMENT)) { if (ubi_volume_write(ENV_UBI_VOLUME_REDUND, - (void *)env_buf, CONFIG_ENV_SIZE)) { + (void *)env_buf, 0, CONFIG_ENV_SIZE)) { printf("\n** Unable to erase env to %s:%s **\n", CONFIG_ENV_UBI_PART, ENV_UBI_VOLUME_REDUND); diff --git a/include/ubi_uboot.h b/include/ubi_uboot.h index a4be0feabb..d36bb92348 100644 --- a/include/ubi_uboot.h +++ b/include/ubi_uboot.h @@ -48,7 +48,7 @@ extern int ubi_mtd_param_parse(const char *val, struct kernel_param *kp); extern int ubi_init(void); extern void ubi_exit(void); extern int ubi_part(char *part_name, const char *vid_header_offset); -extern int ubi_volume_write(char *volume, void *buf, size_t size); +extern int ubi_volume_write(char *volume, void *buf, loff_t offset, size_t size); extern int ubi_volume_read(char *volume, char *buf, loff_t offset, size_t size);
extern struct ubi_device *ubi_devices[];

UBI block is an virtual device, that runs on top of the MTD layer. The blocks are UBI volumes. Intended to be used in combination with other MTD drivers.
Despite the fact that it, like mtdblock abstraction, it used with UCLASS_MTD, they can be used together on the system without conflicting. For example, using bcb command:
# Trying to load bcb via mtdblock: $ bcb load mtd 0 mtd_partition_name
# Trying to load bcb via UBI block: $ bcb load ubi 1 ubi_volume_name
User always must attach UBI layer (for example, using ubi_part()) before using UBI block device.
Signed-off-by: Alexey Romanov avromanov@salutedevices.com Reviewed-by: Heiko Schocher hs@denx.de Acked-by: Heiko Schocher hs@denx.de --- drivers/block/blk-uclass.c | 1 + drivers/mtd/ubi/Makefile | 1 + drivers/mtd/ubi/block.c | 130 +++++++++++++++++++++++++++++++++++++ include/ubi_uboot.h | 4 ++ 4 files changed, 136 insertions(+) create mode 100644 drivers/mtd/ubi/block.c
diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c index ab0a9105c9..8a457e9f70 100644 --- a/drivers/block/blk-uclass.c +++ b/drivers/block/blk-uclass.c @@ -38,6 +38,7 @@ static struct { { UCLASS_BLKMAP, "blkmap" }, { UCLASS_RKMTD, "rkmtd" }, { UCLASS_MTD, "mtd" }, + { UCLASS_MTD, "ubi" }, };
static enum uclass_id uclass_name_to_iftype(const char *uclass_idname) diff --git a/drivers/mtd/ubi/Makefile b/drivers/mtd/ubi/Makefile index 30d00fbdfe..67b1a05348 100644 --- a/drivers/mtd/ubi/Makefile +++ b/drivers/mtd/ubi/Makefile @@ -7,3 +7,4 @@ obj-y += attach.o build.o vtbl.o vmt.o upd.o kapi.o eba.o io.o wl.o crc32.o obj-$(CONFIG_MTD_UBI_FASTMAP) += fastmap.o obj-y += misc.o obj-y += debug.o +obj-$(CONFIG_BLK) += block.o diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c new file mode 100644 index 0000000000..2464decb81 --- /dev/null +++ b/drivers/mtd/ubi/block.c @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2024 SaluteDevices, Inc. + * + * Author: Alexey Romanov avromanov@salutedevices.com + */ + +#include <blk.h> +#include <part.h> +#include <ubi_uboot.h> +#include <dm/device.h> +#include <dm/device-internal.h> + +int ubi_bind(struct udevice *dev) +{ + struct blk_desc *bdesc; + struct udevice *bdev; + int ret; + + ret = blk_create_devicef(dev, "ubi_blk", "blk", UCLASS_MTD, + dev_seq(dev), 512, 0, &bdev); + if (ret) { + pr_err("Cannot create block device"); + return ret; + } + + bdesc = dev_get_uclass_plat(bdev); + + bdesc->bdev = bdev; + bdesc->part_type = PART_TYPE_UBI; + + return 0; +} + +static struct ubi_device *get_ubi_device(void) +{ + return ubi_devices[0]; +} + +static char *get_volume_name(int vol_id) +{ + struct ubi_device *ubi = get_ubi_device(); + int i; + + for (i = 0; i < (ubi->vtbl_slots + 1); i++) { + struct ubi_volume *volume = ubi->volumes[i]; + + if (!volume) + continue; + + if (volume->vol_id >= UBI_INTERNAL_VOL_START) + continue; + + if (volume->vol_id == vol_id) + return volume->name; + } + + return NULL; +} + +static ulong ubi_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, + void *dst) +{ + struct blk_desc *block_dev = dev_get_uclass_plat(dev); + char *volume_name = get_volume_name(block_dev->hwpart); + unsigned int size = blkcnt * block_dev->blksz; + loff_t offset = start * block_dev->blksz; + int ret; + + if (!volume_name) { + pr_err("%s: failed to find volume name for blk=" LBAF "\n", __func__, start); + return -EINVAL; + } + + ret = ubi_volume_read(volume_name, dst, offset, size); + if (ret) { + pr_err("%s: failed to read from %s UBI volume\n", __func__, volume_name); + return ret; + } + + return blkcnt; +} + +static ulong ubi_bwrite(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, + const void *src) +{ + struct blk_desc *block_dev = dev_get_uclass_plat(dev); + char *volume_name = get_volume_name(block_dev->hwpart); + unsigned int size = blkcnt * block_dev->blksz; + loff_t offset = start * block_dev->blksz; + int ret; + + if (!volume_name) { + pr_err("%s: failed to find volume for blk=" LBAF "\n", __func__, start); + return -EINVAL; + } + + ret = ubi_volume_write(volume_name, (void *)src, offset, size); + if (ret) { + pr_err("%s: failed to write from %s UBI volume\n", __func__, volume_name); + return ret; + } + + return blkcnt; +} + +static int ubi_blk_probe(struct udevice *dev) +{ + int ret; + + ret = device_probe(dev); + if (ret) { + pr_err("Probing %s failed (err=%d)\n", dev->name, ret); + return ret; + } + + return 0; +} + +static const struct blk_ops ubi_blk_ops = { + .read = ubi_bread, + .write = ubi_bwrite, +}; + +U_BOOT_DRIVER(ubi_blk) = { + .name = "ubi_blk", + .id = UCLASS_BLK, + .ops = &ubi_blk_ops, + .probe = ubi_blk_probe, +}; diff --git a/include/ubi_uboot.h b/include/ubi_uboot.h index d36bb92348..59491f95c7 100644 --- a/include/ubi_uboot.h +++ b/include/ubi_uboot.h @@ -55,4 +55,8 @@ extern struct ubi_device *ubi_devices[]; int cmd_ubifs_mount(char *vol_name); int cmd_ubifs_umount(void);
+#if IS_ENABLED(CONFIG_BLK) +int ubi_bind(struct udevice *dev); +#endif + #endif

Block devices can already set partition type at initialization stage, so, in this case is no point in searching for partition type.
Signed-off-by: Alexey Romanov avromanov@salutedevices.com Reviewed-by: Heiko Schocher hs@denx.de --- disk/part.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/disk/part.c b/disk/part.c index 3f0fce5cfa..0aced6eb72 100644 --- a/disk/part.c +++ b/disk/part.c @@ -286,6 +286,13 @@ void part_init(struct blk_desc *desc)
blkcache_invalidate(desc->uclass_id, desc->devnum);
+ if (desc->part_type != PART_TYPE_UNKNOWN) { + for (entry = drv; entry != drv + n_ents; entry++) { + if (entry->part_type == desc->part_type && !entry->test(desc)) + return; + } + } + desc->part_type = PART_TYPE_UNKNOWN; for (entry = drv; entry != drv + n_ents; entry++) { int ret;

UBI partition is abstraction over UBI volumes. Can be used by UBI block device.
Signed-off-by: Alexey Romanov avromanov@salutedevices.com Reviewed-by: Heiko Schocher hs@denx.de --- drivers/mtd/ubi/Makefile | 2 +- drivers/mtd/ubi/part.c | 99 ++++++++++++++++++++++++++++++++++++++++ include/part.h | 2 + 3 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 drivers/mtd/ubi/part.c
diff --git a/drivers/mtd/ubi/Makefile b/drivers/mtd/ubi/Makefile index 67b1a05348..63dc428813 100644 --- a/drivers/mtd/ubi/Makefile +++ b/drivers/mtd/ubi/Makefile @@ -7,4 +7,4 @@ obj-y += attach.o build.o vtbl.o vmt.o upd.o kapi.o eba.o io.o wl.o crc32.o obj-$(CONFIG_MTD_UBI_FASTMAP) += fastmap.o obj-y += misc.o obj-y += debug.o -obj-$(CONFIG_BLK) += block.o +obj-$(CONFIG_BLK) += block.o part.o diff --git a/drivers/mtd/ubi/part.c b/drivers/mtd/ubi/part.c new file mode 100644 index 0000000000..8dd7b874af --- /dev/null +++ b/drivers/mtd/ubi/part.c @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2024 SaluteDevices, Inc. + * + * Author: Alexey Romanov avromanov@salutedevices.com + */ + +#include <memalign.h> +#include <part.h> +#include <ubi_uboot.h> + +static inline struct ubi_device *get_ubi_device(void) +{ + return ubi_devices[0]; +} + +static struct ubi_volume *ubi_get_volume_by_index(int vol_id) +{ + struct ubi_device *ubi = get_ubi_device(); + int i; + + for (i = 0; i < (ubi->vtbl_slots + 1); i++) { + struct ubi_volume *volume = ubi->volumes[i]; + + if (!volume) + continue; + + if (volume->vol_id >= UBI_INTERNAL_VOL_START) + continue; + + if (volume->vol_id == vol_id) + return volume; + } + + return NULL; +} + +static int __maybe_unused part_get_info_ubi(struct blk_desc *dev_desc, int part_idx, + struct disk_partition *info) +{ + struct ubi_volume *vol; + + /* + * We must use part_idx - 1 instead of part_idx, because + * part_get_info_by_name() start indexing at 1, not 0. + * ubi volumes idexed starting at 0 + */ + vol = ubi_get_volume_by_index(part_idx - 1); + if (!vol) + return 0; + + snprintf(info->name, PART_NAME_LEN, vol->name); + + info->start = 0; + info->size = vol->used_bytes / dev_desc->blksz; + info->blksz = dev_desc->blksz; + + /* Save UBI volume ID in blk device descriptor */ + dev_desc->hwpart = vol->vol_id; + + return 0; +} + +static void __maybe_unused part_print_ubi(struct blk_desc *dev_desc) +{ + struct ubi_device *ubi = get_ubi_device(); + int i; + + for (i = 0; i < (ubi->vtbl_slots + 1); i++) { + struct ubi_volume *volume = ubi->volumes[i]; + + if (!volume) + continue; + + if (volume->vol_id >= UBI_INTERNAL_VOL_START) + continue; + + printf("%d: %s\n", volume->vol_id, volume->name); + } +} + +static int part_test_ubi(struct blk_desc *dev_desc) +{ + ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz); + + if (blk_dread(dev_desc, 0, 1, (ulong *)buffer) != 1) + return -1; + + return 0; +} + +U_BOOT_PART_TYPE(ubi) = { + .name = "ubi", + .part_type = PART_TYPE_UBI, + .max_entries = UBI_ENTRY_NUMBERS, + .get_info = part_get_info_ptr(part_get_info_ubi), + .print = part_print_ptr(part_print_ubi), + .test = part_test_ubi, +}; diff --git a/include/part.h b/include/part.h index 40419fdf2f..72b98b3512 100644 --- a/include/part.h +++ b/include/part.h @@ -31,6 +31,7 @@ struct block_drvr { #define PART_TYPE_AMIGA 0x04 #define PART_TYPE_EFI 0x05 #define PART_TYPE_MTD 0x06 +#define PART_TYPE_UBI 0x07
/* maximum number of partition entries supported by search */ #define DOS_ENTRY_NUMBERS 8 @@ -38,6 +39,7 @@ struct block_drvr { #define MAC_ENTRY_NUMBERS 64 #define AMIGA_ENTRY_NUMBERS 8 #define MTD_ENTRY_NUMBERS 64 +#define UBI_ENTRY_NUMBERS UBI_MAX_VOLUMES
/* * Type string for U-Boot bootable partitions

UBI block is virtual block device, which is an abstraction over MTD layer. Therefore it is logical to use it in combination with MTD drivers.
Signed-off-by: Alexey Romanov avromanov@salutedevices.com --- drivers/mtd/nand/spi/core.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index 8edb468aed..db71e0627b 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -26,6 +26,7 @@ #include <watchdog.h> #include <spi.h> #include <spi-mem.h> +#include <ubi_uboot.h> #include <dm/device_compat.h> #include <dm/devres.h> #include <linux/bitops.h> @@ -1181,8 +1182,13 @@ static int spinand_bind(struct udevice *dev) { if (blk_enabled()) { struct spinand_plat *plat = dev_get_plat(dev); + int ret; + + ret = mtd_bind(dev, &plat->mtd); + if (ret) + return ret;
- return mtd_bind(dev, &plat->mtd); + return ubi_bind(dev); }
return 0;

On 03.06.24 5:57 PM, Alexey Romanov wrote:
UBI block is virtual block device, which is an abstraction over MTD layer. Therefore it is logical to use it in combination with MTD drivers.
Signed-off-by: Alexey Romanov avromanov@salutedevices.com
I think I already sent a review tag for v2, but anyway:
Reviewed-by: Frieder Schrempf frieder.schrempf@kontron.de
drivers/mtd/nand/spi/core.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index 8edb468aed..db71e0627b 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -26,6 +26,7 @@ #include <watchdog.h> #include <spi.h> #include <spi-mem.h> +#include <ubi_uboot.h> #include <dm/device_compat.h> #include <dm/devres.h> #include <linux/bitops.h> @@ -1181,8 +1182,13 @@ static int spinand_bind(struct udevice *dev) { if (blk_enabled()) { struct spinand_plat *plat = dev_get_plat(dev);
int ret;
ret = mtd_bind(dev, &plat->mtd);
if (ret)
return ret;
return mtd_bind(dev, &plat->mtd);
return ubi_bind(dev);
}
return 0;
participants (2)
-
Alexey Romanov
-
Frieder Schrempf