static int jz4780_efuse_read()

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