in sprd-efuse.c [194:252]
static int sprd_efuse_raw_prog(struct sprd_efuse *efuse, u32 blk, bool doub,
bool lock, u32 *data)
{
u32 status;
int ret = 0;
/*
* We need set the correct magic number before writing the efuse to
* allow programming, and block other programming until we clear the
* magic number.
*/
writel(SPRD_EFUSE_MAGIC_NUMBER,
efuse->base + SPRD_EFUSE_MAGIC_NUM);
/*
* Power on the efuse, enable programme and enable double data
* if asked.
*/
sprd_efuse_set_prog_power(efuse, true);
sprd_efuse_set_prog_en(efuse, true);
sprd_efuse_set_data_double(efuse, doub);
/*
* Enable the auto-check function to validate if the programming is
* successful.
*/
if (lock)
sprd_efuse_set_auto_check(efuse, true);
writel(*data, efuse->base + SPRD_EFUSE_MEM(blk));
/* Disable auto-check and data double after programming */
if (lock)
sprd_efuse_set_auto_check(efuse, false);
sprd_efuse_set_data_double(efuse, false);
/*
* Check the efuse error status, if the programming is successful,
* we should lock this efuse block to avoid programming again.
*/
status = readl(efuse->base + SPRD_EFUSE_ERR_FLAG);
if (status) {
dev_err(efuse->dev,
"write error status %u of block %d\n", status, blk);
writel(SPRD_EFUSE_ERR_CLR_MASK,
efuse->base + SPRD_EFUSE_ERR_CLR);
ret = -EBUSY;
} else if (lock) {
sprd_efuse_set_prog_lock(efuse, lock);
writel(0, efuse->base + SPRD_EFUSE_MEM(blk));
sprd_efuse_set_prog_lock(efuse, false);
}
sprd_efuse_set_prog_power(efuse, false);
writel(0, efuse->base + SPRD_EFUSE_MAGIC_NUM);
return ret;
}