Conversation
Remove flash driver code that nothing builds or calls:
- py25q128ha.c and the py25q128ha/n25q flash region headers are not
referenced by any CMake or Kconfig file.
- flash_sleep_when_idle() and flash_get_sleep_when_idle() are hardcoded
no-ops, flash_enable_write_protection() is empty on every part and
flash_switch_mode() is unimplemented ("NYI") everywhere.
- flash_whoami(), flash_get_size(), flash_is_whoami_correct(),
debug_flash_dump_registers(), flash_use()/flash_release*() and
flash_erase_bulk() have no callers (the latter was already #if 0).
The "flash switchmode" and commented-out "format flash" prompt commands
go with them.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
The flash stack was four layers deep for one part: flash_api.c (global mutex, erase suspend/resume state machine, timers) over flash_impl.h (a global, single-instance driver interface) over qspi_flash.h (an instance API with a per-part command table) over the SoC qspi.c, plus a parallel coredump driver, a second async range-erase engine in flash_erase.c and a third, synchronous one in flash_region.c. Replace it with one device-based API in include/pbl/drivers/flash.h: - struct pbl_flash_device carries geometry, security register info and a pointer to struct pbl_flash_ops; struct pbl_flash_device_state holds the lock and the erase engine state. Drivers embed the device in their own struct and recover it with container_of(). Boards define the device and export it as FLASH. - flash.c is the only generic layer: locking, soft write protection, blank checks, CRC helpers and a single erase engine that serves both pbl_flash_erase() and pbl_flash_erase_async(). Ranges are split into sector and subsector erases, already-blank units are skipped, failed units are retried, and on parts that support it an in-flight erase is suspended for reads and writes and resumed from a timer, as before. - pbl_flash_coredump_init() switches the same API into a no-OS mode (no locks, timers or sleeping) instead of a separate cd_flash driver, so core_dump.c no longer needs the dual-driver switch. - Errors are -errno; write and erase assert on hardware failure as the old API did, since callers never checked. Three drivers implement the ops: nrf5_qspi.c (command tables from nor_part.h, formerly the QSPIFlashPart tables in gd25*.c), sf32lb52_mpi.c (SiFli HAL, XIP) and qemu.c. Drivers whose erase completes synchronously leave erase_status NULL, which also removes a latent slowdown: the old blocking erase slept for 7/8 of the typical erase time before its first poll even when the driver had already finished, so every sector erase on the SF32 boards cost an extra ~130 ms. Consumers now call pbl_flash_*(FLASH, ...). The four-argument "optimal range" erase helpers become pbl_flash_erase(addr, len); callers that relied on the upper bound to round to a sector pass the rounded length themselves. flash_prf_set_protection() becomes pbl_flash_protect()/pbl_flash_unprotect() on the PRF region. The SF32 deep-sleep path uses driver-specific pbl_flash_sf32lb52_mpi_dpd_*() instead of reaching into the QSPI port state. The fake flash and the flash driver tests are ported; the flash_region erase tests are dropped with the code they covered. Verified on asterix, obelix, getafix and the QEMU boards (build), with the full unit test suite, and by booting qemu_flint and exercising the erase and unprotect prompt commands. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
Boards no longer define the flash device. Each driver builds its own instance from Kconfig and exports it as FLASH, in the direction of Zephyr-style driver-owned instantiation: - nrf5_qspi.c takes the clock frequency, pins and read/program commands from FLASH_NRF5_QSPI_*. - sf32lb52_mpi.c takes the MPI instance, memory window size, clock divider and DMA channel/request from FLASH_SF32LB52_MPI_*. - qemu.c takes the flash size from FLASH_QEMU_SIZE. The NOR part becomes a Kconfig choice (FLASH_NOR_PART) and the part table now carries the geometry and erase timings as a struct pbl_flash_geometry, which the device points at, so a driver needs no board input beyond the part selection and its controller settings. The SF32 deep power-down latencies come from the part table too. The driver structs move into the .c files; only the SF32 deep power-down entry points remain in a public header, for the SoC idle code. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces the flash/QSPI driver stack with a single device-based API.
The old stack was four layers deep for one part:
flash_api.c(global mutex, erase suspend/resume state machine) overflash_impl.h(a global, single-instance driver interface) overqspi_flash.h(per-part command tables) over the SoCqspi.c, plus a parallel coredump driver, a second async range-erase engine inflash_erase.cand a third synchronous one inflash_region.c.Now:
include/pbl/drivers/flash.h:struct pbl_flash_device(geometry, security registers,ops,statewith lock + erase engine). Drivers embed the device in their own struct and usecontainer_of(). The driver exports its instance asFLASH.src/fw/drivers/flash/flash.cis the only generic layer: locking, soft write protection, blank checks, CRC helpers, and one erase engine behindpbl_flash_erase()andpbl_flash_erase_async()(sector/subsector splitting, blank skipping, retries, suspend-for-reads on parts that support it).pbl_flash_coredump_init()switches the same API into a no-OS mode, replacing the separate coredump driver and the dual-driver switch incore_dump.c.nrf5_qspi.c(command tables fromnor_part.h),sf32lb52_mpi.c(SiFli HAL, XIP; deep power-down helpers for the SoC idle path) andqemu.c.pbl_flash_*(FLASH, ...); errors are-errno.FLASH_NRF5_QSPI_*pins/clock/commands,FLASH_SF32LB52_MPI_*instance/DMA/window,FLASH_QEMU_SIZE) and theFLASH_NOR_PARTchoice, whose tables carry command sets, geometry and erase timings. Board files no longer mention the flash.Behaviour change: the old blocking erase slept for 7/8 of the typical erase time before polling even when the driver had finished synchronously, so every sector erase on the SF32 boards carried an extra ~130 ms. Synchronous drivers now complete immediately.
Stage 2 (a generic JEDEC NOR layer between an SoC bus driver and the flash ops) is not part of this PR; the nRF5 driver still carries the command logic.
Verification
test_flash_apirewritten against a fakeopstable.erase flashandflash unprotectprompt commands work over PULSE.🤖 Generated with Claude Code