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.

Dependency Surface

Detected Declarations

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

Implementation Notes