drivers/mtd/nand/raw/atmel/pmecc.c
Source file repositories/reference/linux-study-clean/drivers/mtd/nand/raw/atmel/pmecc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mtd/nand/raw/atmel/pmecc.c- Extension
.c- Size
- 25394 bytes
- Lines
- 1013
- Domain
- Driver Families
- Bucket
- drivers/mtd
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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/genalloc.hlinux/iopoll.hlinux/module.hlinux/mtd/rawnand.hlinux/of_irq.hlinux/of_platform.hlinux/platform_device.hlinux/slab.hpmecc.h
Detected Declarations
struct atmel_pmecc_gf_tablesstruct atmel_pmecc_capsstruct atmel_pmeccstruct atmel_pmecc_user_conf_cachestruct atmel_pmecc_userfunction degfunction atmel_pmecc_build_gf_tablesfunction atmel_pmecc_create_gf_tablesfunction atmel_pmecc_get_gf_tablesfunction atmel_pmecc_prepare_user_reqfunction atmel_pmecc_create_userfunction get_strengthfunction get_sectorsizefunction atmel_pmecc_gen_syndromefunction atmel_pmecc_substitutefunction atmel_pmecc_get_sigmafunction atmel_pmecc_err_locationfunction atmel_pmecc_correct_sectorfunction atmel_pmecc_correct_erased_chunksfunction atmel_pmecc_get_generated_eccbytesfunction atmel_pmecc_resetfunction atmel_pmecc_enablefunction atmel_pmecc_disablefunction atmel_pmecc_wait_rdyfunction devm_atmel_pmecc_putfunction atmel_pmecc_probeexport atmel_pmecc_create_userexport atmel_pmecc_correct_sectorexport atmel_pmecc_correct_erased_chunksexport atmel_pmecc_get_generated_eccbytesexport atmel_pmecc_resetexport atmel_pmecc_enableexport atmel_pmecc_disableexport atmel_pmecc_wait_rdyexport devm_atmel_pmecc_get
Annotated Snippet
struct atmel_pmecc_gf_tables {
u16 *alpha_to;
u16 *index_of;
};
struct atmel_pmecc_caps {
const int *strengths;
int nstrengths;
int el_offset;
bool correct_erased_chunks;
bool clk_ctrl;
};
struct atmel_pmecc {
struct device *dev;
const struct atmel_pmecc_caps *caps;
struct {
void __iomem *base;
void __iomem *errloc;
} regs;
struct mutex lock;
};
struct atmel_pmecc_user_conf_cache {
u32 cfg;
u32 sarea;
u32 saddr;
u32 eaddr;
};
struct atmel_pmecc_user {
struct atmel_pmecc_user_conf_cache cache;
struct atmel_pmecc *pmecc;
const struct atmel_pmecc_gf_tables *gf_tables;
int eccbytes;
s16 *partial_syn;
s16 *si;
s16 *lmu;
s16 *smu;
s32 *mu;
s32 *dmu;
s32 *delta;
u32 isr;
};
static DEFINE_MUTEX(pmecc_gf_tables_lock);
static const struct atmel_pmecc_gf_tables *pmecc_gf_tables_512;
static const struct atmel_pmecc_gf_tables *pmecc_gf_tables_1024;
static inline int deg(unsigned int poly)
{
/* polynomial degree is the most-significant bit index */
return fls(poly) - 1;
}
static int atmel_pmecc_build_gf_tables(int mm, unsigned int poly,
struct atmel_pmecc_gf_tables *gf_tables)
{
unsigned int i, x = 1;
const unsigned int k = BIT(deg(poly));
unsigned int nn = BIT(mm) - 1;
/* primitive polynomial must be of degree m */
if (k != (1u << mm))
return -EINVAL;
for (i = 0; i < nn; i++) {
gf_tables->alpha_to[i] = x;
gf_tables->index_of[x] = i;
if (i && (x == 1))
/* polynomial is not primitive (a^i=1 with 0<i<2^m-1) */
return -EINVAL;
x <<= 1;
if (x & k)
x ^= poly;
}
gf_tables->alpha_to[nn] = 1;
gf_tables->index_of[0] = 0;
return 0;
}
static const struct atmel_pmecc_gf_tables *
atmel_pmecc_create_gf_tables(const struct atmel_pmecc_user_req *req)
{
struct atmel_pmecc_gf_tables *gf_tables;
unsigned int poly, degree, table_size;
int ret;
Annotation
- Immediate include surface: `linux/genalloc.h`, `linux/iopoll.h`, `linux/module.h`, `linux/mtd/rawnand.h`, `linux/of_irq.h`, `linux/of_platform.h`, `linux/platform_device.h`, `linux/slab.h`.
- Detected declarations: `struct atmel_pmecc_gf_tables`, `struct atmel_pmecc_caps`, `struct atmel_pmecc`, `struct atmel_pmecc_user_conf_cache`, `struct atmel_pmecc_user`, `function deg`, `function atmel_pmecc_build_gf_tables`, `function atmel_pmecc_create_gf_tables`, `function atmel_pmecc_get_gf_tables`, `function atmel_pmecc_prepare_user_req`.
- Atlas domain: Driver Families / drivers/mtd.
- Implementation status: integration 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.