__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;
+       int i, present;
 
        priv = (struct omap_rng_dev *)rng->priv;
 
+       if (max < priv->pdata->data_size)
+               return 0;
+
        for (i = 0; i < 20; i++) {
-               data = priv->pdata->data_present(priv);
-               if (data || !wait)
+               present = priv->pdata->data_present(priv);
+               if (present || !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;
-
-       priv = (struct omap_rng_dev *)rng->priv;
-       data_size = priv->pdata->data_size;
+       if (!present)
+               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)
 
 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,
 };