Bind the SPI-NOR jedec_spi_nor device into the MTD block subsystem from a new jedec_spi_nor_bind() .bind() hook, matching the spinand_bind()/mmc_bind() precedent of creating blk children once at bind time rather than on every probe. Set the block descriptor's logical block size, log2blksz, and lba from a new CONFIG_MTD_BLOCK_SIZE Kconfig value (default 4 KB) instead of a DT property, matching the sector size GPT images are generated with.
No changes to mtd_bind()'s signature or behavior for existing callers. .bind() runs exactly once per device lifetime, so the mtdblock child is created unconditionally there. Probe-time only looks the child up via blk_find_from_parent() to refresh the mtd_info pointer and block geometry (blksz, log2blksz, lba, part_type), which must still happen on every probe since flash->mtd is only valid after spi_nor_scan() succeeds. If the lookup fails, that is a real error (the child failed to bind), reported via dev_err() and unwound through the existing err_read_id path, which is a generic post-spi_claim_bus() cleanup and not specific to ID-read failures. Wrap the block in a preprocessor '#if CONFIG_IS_ENABLED(MTD_BLOCK)' guard instead of a runtime check, since CONFIG_MTD_BLOCK_SIZE is only emitted to autoconf.h when MTD_BLOCK is enabled; referencing it unconditionally fails to build with MTD_BLOCK disabled. Signed-off-by: Vandhiadevan Karunamoorthy <[email protected]> --- drivers/mtd/Kconfig | 9 +++++++++ drivers/mtd/spi/sf_probe.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 21b8b21f6b2..41a4ee9aeea 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -39,6 +39,15 @@ config MTD_BLOCK Enable support for block device access to MTD devices using blk_ops abstraction. +config MTD_BLOCK_SIZE + hex "MTD logical block size" + depends on MTD_BLOCK + default 0x1000 + help + Logical block size exposed by mtdblock/ubiblock devices to the + block layer. This is the sector size used for GPT partitioning, + not the underlying flash erase size. + config SYS_MTDPARTS_RUNTIME bool "Allow MTDPARTS to be configured at runtime" depends on !COMPILE_TEST diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index 7100b64bf22..8143f53c3ae 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -9,12 +9,15 @@ #include <dm.h> #include <errno.h> +#include <linux/mtd/mtd.h> #include <linux/mtd/spi-nor.h> #include <log.h> #include <malloc.h> +#include <part.h> #include <spi.h> #include <spi_flash.h> #include <spi-mem.h> +#include <dm/device_compat.h> #include "sf_internal.h" @@ -100,6 +103,28 @@ static int spi_flash_probe_slave(struct spi_flash *flash) if (ret) goto err_read_id; +#if CONFIG_IS_ENABLED(MTD_BLOCK) + if (CONFIG_IS_ENABLED(DM_SPI_FLASH)) { + struct mtd_info **plat = dev_get_plat(flash->dev); + struct udevice *bdev; + struct blk_desc *bdesc; + + /* The mtdblock child is created by jedec_spi_nor_bind(). */ + ret = blk_find_from_parent(flash->dev, &bdev); + if (ret) { + dev_err(flash->dev, "mtdblock child not found: %d\n", ret); + goto err_read_id; + } + + bdesc = dev_get_uclass_plat(bdev); + *plat = &flash->mtd; + bdesc->blksz = CONFIG_MTD_BLOCK_SIZE; + bdesc->log2blksz = LOG2(bdesc->blksz); + bdesc->lba = lldiv(flash->mtd.size, bdesc->blksz); + bdesc->part_type = PART_TYPE_UNKNOWN; + } +#endif + if (CONFIG_IS_ENABLED(SPI_DIRMAP)) { ret = spi_nor_create_read_dirmap(flash); if (ret) @@ -251,13 +276,23 @@ static const struct udevice_id spi_flash_std_ids[] = { { } }; +static int jedec_spi_nor_bind(struct udevice *dev) +{ + if (!CONFIG_IS_ENABLED(MTD_BLOCK)) + return 0; + + return mtd_bind(dev, dev_get_plat(dev)); +} + U_BOOT_DRIVER(jedec_spi_nor) = { .name = "jedec_spi_nor", .id = UCLASS_SPI_FLASH, .of_match = spi_flash_std_ids, + .bind = jedec_spi_nor_bind, .probe = spi_flash_std_probe, .remove = spi_flash_std_remove, .priv_auto = sizeof(struct spi_nor), + .plat_auto = sizeof(struct mtd_info *), .ops = &spi_flash_std_ops, .flags = DM_FLAG_OS_PREPARE, }; -- 2.34.1
