Skip to content

Commit 718f98e

Browse files
committed
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. Change-Id: I3f462afd844686aac153acc0c33215fbd96827a3 Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com>
1 parent 9318ec9 commit 718f98e

1 file changed

Lines changed: 11 additions & 4 deletions

File tree

drivers/nvmem/rockchip-efuse.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ struct rockchip_efuse_chip {
111111
struct clk *clk;
112112
struct clk *sclk;
113113
phys_addr_t phys;
114+
struct mutex mutex;
114115
};
115116

116117
static void rk1808_efuse_timing_init(void __iomem *base)
@@ -160,17 +161,18 @@ static int rockchip_rk1808_efuse_read(void *context, unsigned int offset,
160161
u8 *buf;
161162
int ret, i = 0;
162163

164+
mutex_lock(&efuse->mutex);
165+
163166
ret = clk_prepare_enable(efuse->clk);
164167
if (ret < 0) {
165168
dev_err(efuse->dev, "failed to prepare/enable efuse pclk\n");
166-
return ret;
169+
goto out;
167170
}
168171

169172
ret = clk_prepare_enable(efuse->sclk);
170173
if (ret < 0) {
171-
clk_disable_unprepare(efuse->clk);
172174
dev_err(efuse->dev, "failed to prepare/enable efuse sclk\n");
173-
return ret;
175+
goto err_sclk;
174176
}
175177

176178
addr_start = rounddown(offset, RK1808_NBYTES) / RK1808_NBYTES;
@@ -207,8 +209,11 @@ static int rockchip_rk1808_efuse_read(void *context, unsigned int offset,
207209
rk1808_efuse_timing_deinit(efuse->base);
208210
kfree(buf);
209211
nomem:
210-
clk_disable_unprepare(efuse->clk);
211212
clk_disable_unprepare(efuse->sclk);
213+
err_sclk:
214+
clk_disable_unprepare(efuse->clk);
215+
out:
216+
mutex_unlock(&efuse->mutex);
212217

213218
return ret;
214219
}
@@ -632,6 +637,8 @@ static int __init rockchip_efuse_probe(struct platform_device *pdev)
632637
if (IS_ERR(efuse->sclk))
633638
return PTR_ERR(efuse->sclk);
634639

640+
mutex_init(&efuse->mutex);
641+
635642
efuse->dev = &pdev->dev;
636643
if (of_property_read_u32_index(dev->of_node,
637644
"rockchip,efuse-size",

0 commit comments

Comments
 (0)