drivers/nvmem/microchip-otpc.c

Source file repositories/reference/linux-study-clean/drivers/nvmem/microchip-otpc.c

File Facts

System
Linux kernel
Corpus path
drivers/nvmem/microchip-otpc.c
Extension
.c
Size
7938 bytes
Lines
290
Domain
Driver Families
Bucket
drivers/nvmem
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct mchp_otpc {
	void __iomem *base;
	struct device *dev;
	struct list_head packets;
	u32 npackets;
};

/**
 * struct mchp_otpc_packet - OTPC packet data structure
 * @list: list head
 * @id: packet ID
 * @offset: packet offset (in words) in OTP memory
 */
struct mchp_otpc_packet {
	struct list_head list;
	u32 id;
	u32 offset;
};

static struct mchp_otpc_packet *mchp_otpc_id_to_packet(struct mchp_otpc *otpc,
						       u32 id)
{
	struct mchp_otpc_packet *packet;

	if (id >= otpc->npackets)
		return NULL;

	list_for_each_entry(packet, &otpc->packets, list) {
		if (packet->id == id)
			return packet;
	}

	return NULL;
}

static int mchp_otpc_prepare_read(struct mchp_otpc *otpc,
				  unsigned int offset)
{
	u32 tmp;

	/* Set address. */
	tmp = readl_relaxed(otpc->base + MCHP_OTPC_MR);
	tmp &= ~MCHP_OTPC_MR_ADDR;
	tmp |= FIELD_PREP(MCHP_OTPC_MR_ADDR, offset);
	writel_relaxed(tmp, otpc->base + MCHP_OTPC_MR);

	/* Set read. */
	tmp = readl_relaxed(otpc->base + MCHP_OTPC_CR);
	tmp |= MCHP_OTPC_CR_READ;
	writel_relaxed(tmp, otpc->base + MCHP_OTPC_CR);

	/* Wait for packet to be transferred into temporary buffers. */
	return read_poll_timeout(readl_relaxed, tmp, !(tmp & MCHP_OTPC_SR_READ),
				 10000, 2000, false, otpc->base + MCHP_OTPC_SR);
}

/*
 * OTPC memory is organized into packets. Each packets contains a header and
 * a payload. Header is 4 bytes long and contains the size of the payload.
 * Payload size varies. The memory footprint is something as follows:
 *
 * Memory offset  Memory footprint     Packet ID
 * -------------  ----------------     ---------
 *
 * 0x0            +------------+   <-- packet 0
 *                | header  0  |
 * 0x4            +------------+
 *                | payload 0  |
 *                .            .
 *                .    ...     .
 *                .            .
 * offset1        +------------+   <-- packet 1
 *                | header  1  |
 * offset1 + 0x4  +------------+
 *                | payload 1  |
 *                .            .
 *                .    ...     .
 *                .            .
 * offset2        +------------+   <-- packet 2
 *                .            .
 *                .    ...     .
 *                .            .
 * offsetN        +------------+   <-- packet N
 *                | header  N  |
 * offsetN + 0x4  +------------+
 *                | payload N  |
 *                .            .
 *                .    ...     .
 *                .            .
 *                +------------+

Annotation

Implementation Notes