Message ID | 20160907155743.6403-4-romain.perier@free-electrons.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Herbert Xu |
Headers | show |
On Wed, Sep 07, 2016 at 05:57:38PM +0200, Romain Perier wrote: > + > +static int omap_rng_do_read(struct hwrng *rng, void *data, size_t max, > + bool wait) > { > struct omap_rng_dev *priv; > - int data, i; > > priv = (struct omap_rng_dev *)rng->priv; > > - for (i = 0; i < 20; i++) { > - data = priv->pdata->data_present(priv); > - if (data || !wait) > - break; > - /* RNG produces data fast enough (2+ MBit/sec, even > - * during "rngtest" loads, that these delays don't > - * seem to trigger. We *could* use the RNG IRQ, but > - * that'd be higher overhead ... so why bother? > - */ > - udelay(10); So in the wait case you're changing the driver's behaviour. Instead of waiting for 1us you'll now wait for 1s if there is no data. Is this what really what you want? Cheers,
Hi, Le 13/09/2016 11:48, Herbert Xu a écrit : > On Wed, Sep 07, 2016 at 05:57:38PM +0200, Romain Perier wrote: >> + >> +static int omap_rng_do_read(struct hwrng *rng, void *data, size_t max, >> + bool wait) >> { >> struct omap_rng_dev *priv; >> - int data, i; >> >> priv = (struct omap_rng_dev *)rng->priv; >> >> - for (i = 0; i < 20; i++) { >> - data = priv->pdata->data_present(priv); >> - if (data || !wait) >> - break; >> - /* RNG produces data fast enough (2+ MBit/sec, even >> - * during "rngtest" loads, that these delays don't >> - * seem to trigger. We *could* use the RNG IRQ, but >> - * that'd be higher overhead ... so why bother? >> - */ >> - udelay(10); > > So in the wait case you're changing the driver's behaviour. Instead > of waiting for 1us you'll now wait for 1s if there is no data. Is > this what really what you want? > > Cheers, > Mhhh, you're right, in this specific case it will add more latency... with busy loop, on average, 20 retries will be enough to have data... Thanks!
diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c index 01d4be2..d47b24d 100644 --- a/drivers/char/hw_random/omap-rng.c +++ b/drivers/char/hw_random/omap-rng.c @@ -140,41 +140,27 @@ static inline void omap_rng_write(struct omap_rng_dev *priv, u16 reg, __raw_writel(val, priv->base + priv->pdata->regs[reg]); } -static int omap_rng_data_present(struct hwrng *rng, int wait) + +static int omap_rng_do_read(struct hwrng *rng, void *data, size_t max, + bool wait) { struct omap_rng_dev *priv; - int data, i; priv = (struct omap_rng_dev *)rng->priv; - for (i = 0; i < 20; i++) { - data = priv->pdata->data_present(priv); - if (data || !wait) - break; - /* RNG produces data fast enough (2+ MBit/sec, even - * during "rngtest" loads, that these delays don't - * seem to trigger. We *could* use the RNG IRQ, but - * that'd be higher overhead ... so why bother? - */ - udelay(10); - } - return data; -} - -static int omap_rng_data_read(struct hwrng *rng, u32 *data) -{ - struct omap_rng_dev *priv; - u32 data_size, i; + if (max < priv->pdata->data_size) + return 0; - priv = (struct omap_rng_dev *)rng->priv; - data_size = priv->pdata->data_size; + if (!priv->pdata->data_present(priv)) + return 0; - for (i = 0; i < data_size / sizeof(u32); i++) - data[i] = omap_rng_read(priv, RNG_OUTPUT_L_REG + i); + memcpy_fromio(data, priv->base + priv->pdata->regs[RNG_OUTPUT_L_REG], + priv->pdata->data_size); if (priv->pdata->regs[RNG_INTACK_REG]) omap_rng_write(priv, RNG_INTACK_REG, RNG_REG_INTACK_RDY_MASK); - return data_size; + + return priv->pdata->data_size; } static int omap_rng_init(struct hwrng *rng) @@ -195,8 +181,7 @@ static void omap_rng_cleanup(struct hwrng *rng) static struct hwrng omap_rng_ops = { .name = "omap", - .data_present = omap_rng_data_present, - .data_read = omap_rng_data_read, + .read = omap_rng_do_read, .init = omap_rng_init, .cleanup = omap_rng_cleanup, };
The ".data_present" and ".data_read" operations are marked as OBSOLETE in the hwrng API. We have to use the ".read" operation instead. It makes the driver simpler and removes the need to do a busy loop to wait until enough data is generated by the IP. We simplify this step by only checking the status of the engine, if there is data, we copy the data to the output buffer and the amout of copied data is returned to the caller, otherwise zero is returned. The hwrng core will re-call the read operation as many times as required until enough data has been copied. Signed-off-by: Romain Perier <romain.perier@free-electrons.com> --- drivers/char/hw_random/omap-rng.c | 39 ++++++++++++--------------------------- 1 file changed, 12 insertions(+), 27 deletions(-)