From 7acd4de7f2427c326776d49d630bd3530dd54ea6 Mon Sep 17 00:00:00 2001 From: Rick Altherr Date: Wed, 5 Apr 2017 16:20:58 -0700 Subject: hwrng: timeriomem - Migrate to new API Preserves the existing behavior of only returning 32-bits per call. Signed-off-by: Rick Altherr Signed-off-by: Herbert Xu --- drivers/char/hw_random/timeriomem-rng.c | 60 ++++++++++++++++----------------- 1 file changed, 30 insertions(+), 30 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/hw_random/timeriomem-rng.c b/drivers/char/hw_random/timeriomem-rng.c index cf37db263ecd..17574452fd35 100644 --- a/drivers/char/hw_random/timeriomem-rng.c +++ b/drivers/char/hw_random/timeriomem-rng.c @@ -20,18 +20,16 @@ * TODO: add support for reading sizes other than 32bits and masking */ -#include -#include -#include -#include +#include #include #include +#include +#include +#include +#include #include #include -#include -#include #include -#include struct timeriomem_rng_private_data { void __iomem *io_base; @@ -45,32 +43,36 @@ struct timeriomem_rng_private_data { struct hwrng timeriomem_rng_ops; }; -#define to_rng_priv(rng) \ - ((struct timeriomem_rng_private_data *)rng->priv) - -/* - * have data return 1, however return 0 if we have nothing - */ -static int timeriomem_rng_data_present(struct hwrng *rng, int wait) +static int timeriomem_rng_read(struct hwrng *hwrng, void *data, + size_t max, bool wait) { - struct timeriomem_rng_private_data *priv = to_rng_priv(rng); + struct timeriomem_rng_private_data *priv = + container_of(hwrng, struct timeriomem_rng_private_data, + timeriomem_rng_ops); + unsigned long cur; + s32 delay; - if (!wait || priv->present) - return priv->present; + /* The RNG provides 32-bit per read. Ensure there is enough space. */ + if (max < sizeof(u32)) + return 0; - wait_for_completion(&priv->completion); + /* + * There may not have been enough time for new data to be generated + * since the last request. If the caller doesn't want to wait, let them + * bail out. Otherwise, wait for the completion. If the new data has + * already been generated, the completion should already be available. + */ + if (!wait && !priv->present) + return 0; - return 1; -} - -static int timeriomem_rng_data_read(struct hwrng *rng, u32 *data) -{ - struct timeriomem_rng_private_data *priv = to_rng_priv(rng); - unsigned long cur; - s32 delay; + wait_for_completion(&priv->completion); - *data = readl(priv->io_base); + *(u32 *)data = readl(priv->io_base); + /* + * Block any new callers until the RNG has had time to generate new + * data. + */ cur = jiffies; delay = cur - priv->expires; @@ -154,9 +156,7 @@ static int timeriomem_rng_probe(struct platform_device *pdev) setup_timer(&priv->timer, timeriomem_rng_trigger, (unsigned long)priv); priv->timeriomem_rng_ops.name = dev_name(&pdev->dev); - priv->timeriomem_rng_ops.data_present = timeriomem_rng_data_present; - priv->timeriomem_rng_ops.data_read = timeriomem_rng_data_read; - priv->timeriomem_rng_ops.priv = (unsigned long)priv; + priv->timeriomem_rng_ops.read = timeriomem_rng_read; priv->io_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(priv->io_base)) { -- cgit