drivers/mtd/nand/spi/esmt.c
Source file repositories/reference/linux-study-clean/drivers/mtd/nand/spi/esmt.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mtd/nand/spi/esmt.c- Extension
.c- Size
- 8817 bytes
- Lines
- 258
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/device.hlinux/kernel.hlinux/mtd/spinand.hlinux/spi/spi-mem.h
Detected Declarations
function mapfunction f50l1g41lb_ooblayout_freefunction f50l1g41lb_otp_infofunction f50l1g41lb_fact_otp_infofunction f50l1g41lb_user_otp_infofunction f50l1g41lb_otp_lock
Annotated Snippet
// SPDX-License-Identifier: GPL-2.0
/*
* Author:
* Chuanhong Guo <gch981213@gmail.com> - the main driver logic
* Martin Kurbanov <mmkurbanov@sberdevices.ru> - OOB layout
*/
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/mtd/spinand.h>
#include <linux/spi/spi-mem.h>
/* ESMT uses GigaDevice 0xc8 JECDEC ID on some SPI NANDs */
#define SPINAND_MFR_ESMT_C8 0xc8
#define SPINAND_MFR_ESMT_8C 0x8c
#define ESMT_F50L1G41LB_CFG_OTP_PROTECT BIT(7)
#define ESMT_F50L1G41LB_CFG_OTP_LOCK \
(CFG_OTP_ENABLE | ESMT_F50L1G41LB_CFG_OTP_PROTECT)
static SPINAND_OP_VARIANTS(read_cache_variants,
SPINAND_PAGE_READ_FROM_CACHE_1S_1S_4S_OP(0, 1, NULL, 0, 0),
SPINAND_PAGE_READ_FROM_CACHE_1S_1S_2S_OP(0, 1, NULL, 0, 0),
SPINAND_PAGE_READ_FROM_CACHE_FAST_1S_1S_1S_OP(0, 1, NULL, 0, 0),
SPINAND_PAGE_READ_FROM_CACHE_1S_1S_1S_OP(0, 1, NULL, 0, 0));
static SPINAND_OP_VARIANTS(write_cache_variants,
SPINAND_PROG_LOAD_1S_1S_4S_OP(true, 0, NULL, 0),
SPINAND_PROG_LOAD_1S_1S_1S_OP(true, 0, NULL, 0));
static SPINAND_OP_VARIANTS(update_cache_variants,
SPINAND_PROG_LOAD_1S_1S_4S_OP(false, 0, NULL, 0),
SPINAND_PROG_LOAD_1S_1S_1S_OP(false, 0, NULL, 0));
/*
* OOB spare area map (64 bytes)
*
* Bad Block Markers
* filled by HW and kernel Reserved
* | +-----------------------+-----------------------+
* | | | |
* | | OOB free data Area |non ECC protected |
* | +-------------|-----+-----------------|-----+-----------------|-----+
* | | | | | | | |
* +-|---|----------+--|-----|--------------+--|-----|--------------+--|-----|--------------+
* | | | section0 | | | section1 | | | section2 | | | section3 |
* +-v-+-v-+---+----+--v--+--v--+-----+-----+--v--+--v--+-----+-----+--v--+--v--+-----+-----+
* | | | | | | | | | | | | | | | | |
* |0:1|2:3|4:7|8:15|16:17|18:19|20:23|24:31|32:33|34:35|36:39|40:47|48:49|50:51|52:55|56:63|
* | | | | | | | | | | | | | | | | |
* +---+---+-^-+--^-+-----+-----+--^--+--^--+-----+-----+--^--+--^--+-----+-----+--^--+--^--+
* | | | | | | | |
* | +----------------|-----+-----------------|-----+-----------------|-----+
* | ECC Area|(Main + Spare) - filled|by ESMT NAND HW |
* | | | |
* +---------------------+-----------------------+-----------------------+
* OOB ECC protected Area - not used due to
* partial programming from some filesystems
* (like JFFS2 with cleanmarkers)
*/
#define ESMT_OOB_SECTION_COUNT 4
#define ESMT_OOB_SECTION_SIZE(nand) \
(nanddev_per_page_oobsize(nand) / ESMT_OOB_SECTION_COUNT)
#define ESMT_OOB_FREE_SIZE(nand) \
(ESMT_OOB_SECTION_SIZE(nand) / 2)
#define ESMT_OOB_ECC_SIZE(nand) \
(ESMT_OOB_SECTION_SIZE(nand) - ESMT_OOB_FREE_SIZE(nand))
#define ESMT_OOB_BBM_SIZE 2
static int f50l1g41lb_ooblayout_ecc(struct mtd_info *mtd, int section,
struct mtd_oob_region *region)
{
struct nand_device *nand = mtd_to_nanddev(mtd);
if (section >= ESMT_OOB_SECTION_COUNT)
return -ERANGE;
region->offset = section * ESMT_OOB_SECTION_SIZE(nand) +
ESMT_OOB_FREE_SIZE(nand);
region->length = ESMT_OOB_ECC_SIZE(nand);
return 0;
}
static int f50l1g41lb_ooblayout_free(struct mtd_info *mtd, int section,
struct mtd_oob_region *region)
{
struct nand_device *nand = mtd_to_nanddev(mtd);
Annotation
- Immediate include surface: `linux/device.h`, `linux/kernel.h`, `linux/mtd/spinand.h`, `linux/spi/spi-mem.h`.
- Detected declarations: `function map`, `function f50l1g41lb_ooblayout_free`, `function f50l1g41lb_otp_info`, `function f50l1g41lb_fact_otp_info`, `function f50l1g41lb_user_otp_info`, `function f50l1g41lb_otp_lock`.
- Atlas domain: Driver Families / drivers/mtd.
- Implementation status: source implementation candidate.
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.