in rockchip-otp.c [135:181]
static int rockchip_otp_read(void *context, unsigned int offset,
void *val, size_t bytes)
{
struct rockchip_otp *otp = context;
u8 *buf = val;
int ret = 0;
ret = clk_bulk_prepare_enable(otp->num_clks, otp->clks);
if (ret < 0) {
dev_err(otp->dev, "failed to prepare/enable clks\n");
return ret;
}
ret = rockchip_otp_reset(otp);
if (ret) {
dev_err(otp->dev, "failed to reset otp phy\n");
goto disable_clks;
}
ret = rockchip_otp_ecc_enable(otp, false);
if (ret < 0) {
dev_err(otp->dev, "rockchip_otp_ecc_enable err\n");
goto disable_clks;
}
writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
udelay(5);
while (bytes--) {
writel(offset++ | OTPC_USER_ADDR_MASK,
otp->base + OTPC_USER_ADDR);
writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK,
otp->base + OTPC_USER_ENABLE);
ret = rockchip_otp_wait_status(otp, OTPC_USER_DONE);
if (ret < 0) {
dev_err(otp->dev, "timeout during read setup\n");
goto read_end;
}
*buf++ = readb(otp->base + OTPC_USER_Q);
}
read_end:
writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
disable_clks:
clk_bulk_disable_unprepare(otp->num_clks, otp->clks);
return ret;
}