Skip to content

Commit 501e197

Browse files
martin-kaiserherbertx
authored andcommitted
hwrng: st - keep clock enabled while hwrng is registered
The st-rng driver uses devres to register itself with the hwrng core, the driver will be unregistered from hwrng when its device goes out of scope. This happens after the driver's remove function is called. However, st-rng's clock is disabled in the remove function. There's a short timeframe where st-rng is still registered with the hwrng core although its clock is disabled. I suppose the clock must be active to access the hardware and serve requests from the hwrng core. Switch to devm_clk_get_enabled and let devres disable the clock and unregister the hwrng. This avoids the race condition. Fixes: 3e75241 ("hwrng: drivers - Use device-managed registration API") Signed-off-by: Martin Kaiser <martin@kaiser.cx> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
1 parent afa9d00 commit 501e197

File tree

1 file changed

+1
-20
lines changed

1 file changed

+1
-20
lines changed

drivers/char/hw_random/st-rng.c

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242

4343
struct st_rng_data {
4444
void __iomem *base;
45-
struct clk *clk;
4645
struct hwrng ops;
4746
};
4847

@@ -85,26 +84,18 @@ static int st_rng_probe(struct platform_device *pdev)
8584
if (IS_ERR(base))
8685
return PTR_ERR(base);
8786

88-
clk = devm_clk_get(&pdev->dev, NULL);
87+
clk = devm_clk_get_enabled(&pdev->dev, NULL);
8988
if (IS_ERR(clk))
9089
return PTR_ERR(clk);
9190

92-
ret = clk_prepare_enable(clk);
93-
if (ret)
94-
return ret;
95-
9691
ddata->ops.priv = (unsigned long)ddata;
9792
ddata->ops.read = st_rng_read;
9893
ddata->ops.name = pdev->name;
9994
ddata->base = base;
100-
ddata->clk = clk;
101-
102-
dev_set_drvdata(&pdev->dev, ddata);
10395

10496
ret = devm_hwrng_register(&pdev->dev, &ddata->ops);
10597
if (ret) {
10698
dev_err(&pdev->dev, "Failed to register HW RNG\n");
107-
clk_disable_unprepare(clk);
10899
return ret;
109100
}
110101

@@ -113,15 +104,6 @@ static int st_rng_probe(struct platform_device *pdev)
113104
return 0;
114105
}
115106

116-
static int st_rng_remove(struct platform_device *pdev)
117-
{
118-
struct st_rng_data *ddata = dev_get_drvdata(&pdev->dev);
119-
120-
clk_disable_unprepare(ddata->clk);
121-
122-
return 0;
123-
}
124-
125107
static const struct of_device_id st_rng_match[] __maybe_unused = {
126108
{ .compatible = "st,rng" },
127109
{},
@@ -134,7 +116,6 @@ static struct platform_driver st_rng_driver = {
134116
.of_match_table = of_match_ptr(st_rng_match),
135117
},
136118
.probe = st_rng_probe,
137-
.remove = st_rng_remove
138119
};
139120

140121
module_platform_driver(st_rng_driver);

0 commit comments

Comments
 (0)