[PATCH v2 0/3] mtd: point() for cfi_cmdset_0002, on simple maps only

From: Orgad Shaneh

Date: Sat Oct 10 2026 - 14:08:53 EST


jffs2 scans a flash in place through mtd_point() when the chip driver
offers it, and copies every used eraseblock through mtd_read()
otherwise. cfi_cmdset_0002 never had point(), so every jffs2 mount on
an AMD-style NOR copies the whole used area. On an Octeon CN6635 board
with a 100 MB jffs2 partition on an 8-bit M29EW that takes 15-30 s at
every boot.

1/3 tightens the existing gate first. map_is_linear() only checks for
a physical address, so cfi_cmdset_0001 already points at maps whose
own accessors swap bytes (IXP4xx), switch pins (Gemini) or lock the
bus (lantiq). The new map_is_simple() also requires the simple
accessors.

2/3 adds point()/unpoint() to cfi_cmdset_0002 behind the same gate,
modeled on cfi_cmdset_0001, and lists it in the cramfs documentation.

3/3 lets the Octeon flash map use the simple accessors when no eMMC
host shares its boot bus. Without it, 2/3 changes nothing on Octeon.
It builds without 1/3 and 2/3 but only pays off once they are in, so
taking all three through mtd with an ack from Thomas seems simplest.

Tested on that board with 7.2.9: the mount drops to 0.6-0.8 s. The
md5s of the images on the jffs2 partition held across reboots and
across ten 8 MB write/delete rounds. The series applies to v7.3-rc4
and to mtd/next.

Separately, for the MTD maintainers to judge: the write-buffer count
truncation that cfc5ebc9540e ("mtd: cfi_cmdset_0002: cap the
write-buffer chunk at 256 bytes on an x8 device") fixed in
cfi_cmdset_0002 has two siblings. do_write_buffer() in cfi_cmdset_0001
writes CMD(words) and the one in cfi_cmdset_0020 writes
CMD(len / map_bankwidth(map) - 1). On an x8 device CMD() keeps only
the low 8 bits of the count in each device lane, so a write buffer
larger than 256 bytes per device would be programmed with a truncated
count. I have no x8 Intel or ST part to test on, so I have not touched
either; I do not know whether such a part exists.

Changes in v2, all from sashiko's review of v1:
- 2/3: a point no longer suspends an erase in progress. cramfs holds its
point for the whole mount, so the erase - and the task waiting on it,
and the reboot reset - would stay suspended until umount.
- 3/3: the bank width is checked before ioremap(), and the iounmap()
calls v1 added are gone; flash_map is a single static instance, so
on a second probe they could unmap what the first one registered.
- Not changed: sashiko also asked about writers sleeping
uninterruptibly behind a long-held point. That is how
cfi_cmdset_0001 has always behaved, and 2/3 describes the cramfs
consequence: a cramfs mounted from /dev/mtdblockN on AMD flash
today falls back to the block device, and after this series it
takes the direct path, so writes to other partitions of the same
chip wait until it is unmounted. If you would rather not change
that, I can make point() in cfi_cmdset_0002 opt-in.

v1: https://lore.kernel.org/all/20261010172142.2138956-1-orgads@xxxxxxxxx/

Orgad Shaneh (3):
mtd: maps: only point() maps read through the simple accessors
mtd: cfi_cmdset_0002: implement point() for simple linear maps
MIPS: Octeon: flash: use the simple map accessors without a shared
eMMC

Documentation/filesystems/cramfs.rst | 11 +-
arch/mips/cavium-octeon/flash_setup.c | 36 +++++-
drivers/mtd/chips/cfi_cmdset_0001.c | 2 +-
drivers/mtd/chips/cfi_cmdset_0002.c | 162 +++++++++++++++++++++++++-
drivers/mtd/maps/map_funcs.c | 12 ++
include/linux/mtd/map.h | 2 +
6 files changed, 211 insertions(+), 14 deletions(-)

--
2.53.0