Skip to content

Commit

Permalink
hwrng: nomadik - keep clock enabled while hwrng is registered
Browse files Browse the repository at this point in the history
[ Upstream commit 039980d ]

The nomadik 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, nomadik's clock is disabled in the remove function. There's a
short timeframe where nomadik 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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
martin-kaiser authored and gregkh committed Sep 13, 2023
1 parent 73d9750 commit 79a8ea5
Showing 1 changed file with 3 additions and 9 deletions.
12 changes: 3 additions & 9 deletions drivers/char/hw_random/nomadik-rng.c
Expand Up @@ -13,8 +13,6 @@
#include <linux/clk.h>
#include <linux/err.h>

static struct clk *rng_clk;

static int nmk_rng_read(struct hwrng *rng, void *data, size_t max, bool wait)
{
void __iomem *base = (void __iomem *)rng->priv;
Expand All @@ -36,21 +34,20 @@ static struct hwrng nmk_rng = {

static int nmk_rng_probe(struct amba_device *dev, const struct amba_id *id)
{
struct clk *rng_clk;
void __iomem *base;
int ret;

rng_clk = devm_clk_get(&dev->dev, NULL);
rng_clk = devm_clk_get_enabled(&dev->dev, NULL);
if (IS_ERR(rng_clk)) {
dev_err(&dev->dev, "could not get rng clock\n");
ret = PTR_ERR(rng_clk);
return ret;
}

clk_prepare_enable(rng_clk);

ret = amba_request_regions(dev, dev->dev.init_name);
if (ret)
goto out_clk;
return ret;
ret = -ENOMEM;
base = devm_ioremap(&dev->dev, dev->res.start,
resource_size(&dev->res));
Expand All @@ -64,15 +61,12 @@ static int nmk_rng_probe(struct amba_device *dev, const struct amba_id *id)

out_release:
amba_release_regions(dev);
out_clk:
clk_disable_unprepare(rng_clk);
return ret;
}

static void nmk_rng_remove(struct amba_device *dev)
{
amba_release_regions(dev);
clk_disable_unprepare(rng_clk);
}

static const struct amba_id nmk_rng_ids[] = {
Expand Down

0 comments on commit 79a8ea5

Please sign in to comment.