nvmem: rockchip-efuse: Add mutex lock for rk1808 efuse read

The rk1808 efuse read has some issues when several threads start to read
efuse through nvmem file node.

Thread1                                    thread2
1. timing_init
2.  write auto_ctrl
3.    delay                                  timing_init
4.      read status                            write auto_ctrl
5.        if error goto to timing_deinit         delay

The thread1 will read no finish bit and then goto error, the user will
see a "Input/Output Error".

The thread1 do timing deinit will cause thread2 halt on read status, and
the user will never success to do read efuse again.

Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
Change-Id: I3f462afd844686aac153acc0c33215fbd96827a3
This commit is contained in:
Finley Xiao
2020-10-19 14:59:41 +08:00
parent bd2d7d615f
commit e621ca5fd6

View File

@@ -99,6 +99,7 @@ struct rockchip_efuse_chip {
struct clk_bulk_data *clks;
int num_clks;
phys_addr_t phys;
struct mutex mutex;
};
static void rk1808_efuse_timing_init(void __iomem *base)
@@ -148,10 +149,12 @@ static int rockchip_rk1808_efuse_read(void *context, unsigned int offset,
u8 *buf;
int ret, i = 0;
mutex_lock(&efuse->mutex);
ret = clk_bulk_prepare_enable(efuse->num_clks, efuse->clks);
if (ret < 0) {
dev_err(efuse->dev, "failed to prepare/enable efuse clk\n");
return ret;
goto out;
}
addr_start = rounddown(offset, RK1808_NBYTES) / RK1808_NBYTES;
@@ -190,6 +193,8 @@ err:
nomem:
rk1808_efuse_timing_deinit(efuse->base);
clk_bulk_disable_unprepare(efuse->num_clks, efuse->clks);
out:
mutex_unlock(&efuse->mutex);
return ret;
}
@@ -563,6 +568,8 @@ static int rockchip_efuse_probe(struct platform_device *pdev)
if (efuse->num_clks < 1)
return -ENODEV;
mutex_init(&efuse->mutex);
efuse->dev = dev;
if (of_property_read_u32(dev->of_node, "rockchip,efuse-size",
&econfig.size))