drivers/mtd/nand/spi/core.c
Source file repositories/reference/linux-study-clean/drivers/mtd/nand/spi/core.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mtd/nand/spi/core.c- Extension
.c- Size
- 54277 bytes
- Lines
- 2113
- Domain
- Driver Families
- Bucket
- drivers/mtd
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/device.hlinux/jiffies.hlinux/kernel.hlinux/module.hlinux/mtd/spinand.hlinux/of.hlinux/slab.hlinux/string.hlinux/spi/spi.hlinux/spi/spi-mem.h
Detected Declarations
function Copyrightfunction spinand_fill_readid_opfunction spinand_fill_wr_en_opfunction spinand_fill_wr_dis_opfunction spinand_fill_set_feature_opfunction spinand_fill_get_feature_opfunction spinand_fill_blk_erase_opfunction spinand_fill_page_read_opfunction spinand_fill_page_read_packed_opfunction spinand_fill_prog_exec_opfunction spinand_read_reg_opfunction spinand_write_reg_opfunction spinand_read_statusfunction spinand_get_cfgfunction spinand_set_cfgfunction spinand_upd_cfgfunction spinand_select_targetfunction spinand_read_cfgfunction spinand_init_cfg_cachefunction spinand_init_quad_enablefunction spinand_ecc_enablefunction spinand_cont_read_enablefunction spinand_check_ecc_statusfunction spinand_noecc_ooblayout_eccfunction spinand_noecc_ooblayout_freefunction spinand_ondie_ecc_init_ctxfunction spinand_ondie_ecc_cleanup_ctxfunction spinand_ondie_ecc_prepare_io_reqfunction spinand_ondie_ecc_finish_io_reqfunction spinand_ondie_ecc_save_statusfunction spinand_write_enable_opfunction spinand_load_page_opfunction spinand_read_from_cache_opfunction spinand_write_to_cache_opfunction spinand_program_opfunction spinand_erase_opfunction spinand_waitfunction spinand_read_id_opfunction spinand_reset_opfunction spinand_lock_blockfunction spinand_read_pagefunction spinand_write_pagefunction spinand_mtd_regular_page_readfunction nanddev_io_for_each_pagefunction spinand_mtd_continuous_page_readfunction spinand_cont_read_initfunction spinand_use_cont_readfunction spinand_mtd_read
Annotated Snippet
if (!buf) {
buf = spinand->oobbuf;
column = nanddev_page_size(nand);
}
}
rdesc = spinand->dirmaps[req->pos.plane].rdesc;
if (spinand->op_templates->cont_read_cache && req->continuous)
rdesc->info.op_tmpl = &rdesc->info.secondary_op_tmpl;
else
rdesc->info.op_tmpl = &rdesc->info.primary_op_tmpl;
if (nand->ecc.engine->integration == NAND_ECC_ENGINE_INTEGRATION_PIPELINED &&
req->mode != MTD_OPS_RAW)
rdesc->info.op_tmpl->data.ecc = true;
else
rdesc->info.op_tmpl->data.ecc = false;
if (spinand->flags & SPINAND_HAS_READ_PLANE_SELECT_BIT)
column |= req->pos.plane << fls(nanddev_page_size(nand));
while (nbytes) {
ret = spi_mem_dirmap_read(rdesc, column, nbytes, buf);
if (ret < 0)
return ret;
if (!ret || ret > nbytes)
return -EIO;
nbytes -= ret;
column += ret;
buf += ret;
/*
* Dirmap accesses are allowed to toggle the CS.
* Toggling the CS during a continuous read is forbidden.
*/
if (nbytes && req->continuous) {
/*
* Spi controller with broken support of continuous
* reading was detected. Disable future use of
* continuous reading and return -EAGAIN to retry
* reading within regular mode.
*/
spinand->cont_read_possible = false;
return -EAGAIN;
}
}
if (req->datalen)
memcpy(req->databuf.in, spinand->databuf + req->dataoffs,
req->datalen);
if (req->ooblen) {
if (req->mode == MTD_OPS_AUTO_OOB)
mtd_ooblayout_get_databytes(mtd, req->oobbuf.in,
spinand->oobbuf,
req->ooboffs,
req->ooblen);
else
memcpy(req->oobbuf.in, spinand->oobbuf + req->ooboffs,
req->ooblen);
}
return 0;
}
static int spinand_write_to_cache_op(struct spinand_device *spinand,
const struct nand_page_io_req *req)
{
struct nand_device *nand = spinand_to_nand(spinand);
struct mtd_info *mtd = spinand_to_mtd(spinand);
struct spi_mem_dirmap_desc *wdesc;
unsigned int nbytes, column = 0;
void *buf = spinand->databuf;
ssize_t ret;
/*
* Looks like PROGRAM LOAD (AKA write cache) does not necessarily reset
* the cache content to 0xFF (depends on vendor implementation), so we
* must fill the page cache entirely even if we only want to program
* the data portion of the page, otherwise we might corrupt the BBM or
* user data previously programmed in OOB area.
*
* Only reset the data buffer manually, the OOB buffer is prepared by
* ECC engines ->prepare_io_req() callback.
*/
nbytes = nanddev_page_size(nand) + nanddev_per_page_oobsize(nand);
memset(spinand->databuf, 0xff, nanddev_page_size(nand));
Annotation
- Immediate include surface: `linux/device.h`, `linux/jiffies.h`, `linux/kernel.h`, `linux/module.h`, `linux/mtd/spinand.h`, `linux/of.h`, `linux/slab.h`, `linux/string.h`.
- Detected declarations: `function Copyright`, `function spinand_fill_readid_op`, `function spinand_fill_wr_en_op`, `function spinand_fill_wr_dis_op`, `function spinand_fill_set_feature_op`, `function spinand_fill_get_feature_op`, `function spinand_fill_blk_erase_op`, `function spinand_fill_page_read_op`, `function spinand_fill_page_read_packed_op`, `function spinand_fill_prog_exec_op`.
- Atlas domain: Driver Families / drivers/mtd.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.