static int sprd_efuse_raw_prog()

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;
}