in jz4780-efuse.c [69:116]
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;
}