drivers/nvmem/jz4780-efuse.c

Source file repositories/reference/linux-study-clean/drivers/nvmem/jz4780-efuse.c

File Facts

System
Linux kernel
Corpus path
drivers/nvmem/jz4780-efuse.c
Extension
.c
Size
6276 bytes
Lines
238
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 jz4780_efuse {
	struct device *dev;
	struct regmap *map;
	struct clk *clk;
};

/* main entry point */
static int jz4780_efuse_read(void *context, unsigned int offset,
			     void *val, size_t bytes)
{
	struct jz4780_efuse *efuse = context;

	while (bytes > 0) {
		size_t start = offset & ~(JZ_EFU_READ_SIZE - 1);
		size_t chunk = min(bytes, (start + JZ_EFU_READ_SIZE)
				    - offset);
		char buf[JZ_EFU_READ_SIZE];
		unsigned int tmp;
		u32 ctrl;
		int ret;

		ctrl = (start << EFUCTRL_ADDR_SHIFT)
			| ((JZ_EFU_READ_SIZE - 1) << EFUCTRL_LEN_SHIFT)
			| EFUCTRL_RD_EN;

		regmap_update_bits(efuse->map, JZ_EFUCTRL,
				   (EFUCTRL_ADDR_MASK << EFUCTRL_ADDR_SHIFT) |
				   (EFUCTRL_LEN_MASK << EFUCTRL_LEN_SHIFT) |
				   EFUCTRL_PG_EN | EFUCTRL_WR_EN |
				   EFUCTRL_RD_EN,
				   ctrl);

		ret = regmap_read_poll_timeout(efuse->map, JZ_EFUSTATE,
					       tmp, tmp & EFUSTATE_RD_DONE,
					       1 * MSEC_PER_SEC,
					       50 * MSEC_PER_SEC);
		if (ret < 0) {
			dev_err(efuse->dev, "Time out while reading efuse data");
			return ret;
		}

		ret = regmap_bulk_read(efuse->map, JZ_EFUDATA(0),
				       buf, JZ_EFU_READ_SIZE / sizeof(u32));
		if (ret < 0)
			return ret;

		memcpy(val, &buf[offset - start], chunk);

		val += chunk;
		offset += chunk;
		bytes -= chunk;
	}

	return 0;
}

static struct nvmem_config jz4780_efuse_nvmem_config = {
	.name = "jz4780-efuse",
	.size = 1024,
	.word_size = 1,
	.stride = 1,
	.owner = THIS_MODULE,
	.reg_read = jz4780_efuse_read,
};

static const struct regmap_config jz4780_efuse_regmap_config = {
	.reg_bits = 32,
	.val_bits = 32,
	.reg_stride = 4,
	.max_register = JZ_EFUDATA(7),
};

static void clk_disable_unprepare_helper(void *clock)
{
	clk_disable_unprepare(clock);
}

static int jz4780_efuse_probe(struct platform_device *pdev)
{
	struct nvmem_device *nvmem;
	struct jz4780_efuse *efuse;
	struct nvmem_config cfg;
	unsigned long clk_rate;
	unsigned long rd_adj;
	unsigned long rd_strobe;
	struct device *dev = &pdev->dev;
	void __iomem *regs;
	int ret;

	efuse = devm_kzalloc(dev, sizeof(*efuse), GFP_KERNEL);

Annotation

Implementation Notes