From e621ca5fd6592dfdb931cd579438adf76a0f0161 Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Mon, 19 Oct 2020 14:59:41 +0800 Subject: [PATCH] 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 Change-Id: I3f462afd844686aac153acc0c33215fbd96827a3 --- drivers/nvmem/rockchip-efuse.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/nvmem/rockchip-efuse.c b/drivers/nvmem/rockchip-efuse.c index d9c65583f05a..f8901837698a 100644 --- a/drivers/nvmem/rockchip-efuse.c +++ b/drivers/nvmem/rockchip-efuse.c @@ -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))