Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 984e976f authored by Patrick McHardy's avatar Patrick McHardy Committed by Herbert Xu
Browse files

[HWRNG]: move status polling loop to data_present callbacks



Handle waiting for new random within the drivers themselves, this allows to
use better suited timeouts for the individual rngs.

Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Acked-by: default avatarMichael Buesch <mb@bu3sch.de>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 2407d608
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/hw_random.h>
#include <linux/delay.h>
#include <asm/io.h>


@@ -52,11 +53,18 @@ MODULE_DEVICE_TABLE(pci, pci_tbl);
static struct pci_dev *amd_pdev;


static int amd_rng_data_present(struct hwrng *rng)
static int amd_rng_data_present(struct hwrng *rng, int wait)
{
	u32 pmbase = (u32)rng->priv;
	int data, i;

      	return !!(inl(pmbase + 0xF4) & 1);
	for (i = 0; i < 20; i++) {
		data = !!(inl(pmbase + 0xF4) & 1);
		if (data || !wait)
			break;
		udelay(10);
	}
	return data;
}

static int amd_rng_data_read(struct hwrng *rng, u32 *data)
+6 −18
Original line number Diff line number Diff line
@@ -66,11 +66,11 @@ static inline void hwrng_cleanup(struct hwrng *rng)
		rng->cleanup(rng);
}

static inline int hwrng_data_present(struct hwrng *rng)
static inline int hwrng_data_present(struct hwrng *rng, int wait)
{
	if (!rng->data_present)
		return 1;
	return rng->data_present(rng);
	return rng->data_present(rng, wait);
}

static inline int hwrng_data_read(struct hwrng *rng, u32 *data)
@@ -94,8 +94,7 @@ static ssize_t rng_dev_read(struct file *filp, char __user *buf,
{
	u32 data;
	ssize_t ret = 0;
	int i, err = 0;
	int data_present;
	int err = 0;
	int bytes_read;

	while (size) {
@@ -107,21 +106,10 @@ static ssize_t rng_dev_read(struct file *filp, char __user *buf,
			err = -ENODEV;
			goto out;
		}
		if (filp->f_flags & O_NONBLOCK) {
			data_present = hwrng_data_present(current_rng);
		} else {
			/* Some RNG require some time between data_reads to gather
			 * new entropy. Poll it.
			 */
			for (i = 0; i < 20; i++) {
				data_present = hwrng_data_present(current_rng);
				if (data_present)
					break;
				udelay(10);
			}
		}

		bytes_read = 0;
		if (data_present)
		if (hwrng_data_present(current_rng,
				       !(filp->f_flags & O_NONBLOCK)))
			bytes_read = hwrng_data_read(current_rng, &data);
		mutex_unlock(&rng_mutex);

+10 −2
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/hw_random.h>
#include <linux/delay.h>
#include <asm/io.h>


@@ -61,11 +62,18 @@ static int geode_rng_data_read(struct hwrng *rng, u32 *data)
	return 4;
}

static int geode_rng_data_present(struct hwrng *rng)
static int geode_rng_data_present(struct hwrng *rng, int wait)
{
	void __iomem *mem = (void __iomem *)rng->priv;
	int data, i;

	return !!(readl(mem + GEODE_RNG_STATUS_REG));
	for (i = 0; i < 20; i++) {
		data = !!(readl(mem + GEODE_RNG_STATUS_REG));
		if (data || !wait)
			break;
		udelay(10);
	}
	return data;
}


+12 −3
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/stop_machine.h>
#include <linux/delay.h>
#include <asm/io.h>


@@ -162,11 +163,19 @@ static inline u8 hwstatus_set(void __iomem *mem,
	return hwstatus_get(mem);
}

static int intel_rng_data_present(struct hwrng *rng)
static int intel_rng_data_present(struct hwrng *rng, int wait)
{
	void __iomem *mem = (void __iomem *)rng->priv;

	return !!(readb(mem + INTEL_RNG_STATUS) & INTEL_RNG_DATA_PRESENT);
	int data, i;

	for (i = 0; i < 20; i++) {
		data = !!(readb(mem + INTEL_RNG_STATUS) &
			  INTEL_RNG_DATA_PRESENT);
		if (data || !wait)
			break;
		udelay(10);
	}
	return data;
}

static int intel_rng_data_read(struct hwrng *rng, u32 *data)
+11 −2
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/hw_random.h>
#include <linux/delay.h>

#include <asm/io.h>

@@ -65,9 +66,17 @@ static void omap_rng_write_reg(int reg, u32 val)
}

/* REVISIT: Does the status bit really work on 16xx? */
static int omap_rng_data_present(struct hwrng *rng)
static int omap_rng_data_present(struct hwrng *rng, int wait)
{
	return omap_rng_read_reg(RNG_STAT_REG) ? 0 : 1;
	int data, i;

	for (i = 0; i < 20; i++) {
		data = omap_rng_read_reg(RNG_STAT_REG) ? 0 : 1;
		if (data || !wait)
			break;
		udelay(10);
	}
	return data;
}

static int omap_rng_data_read(struct hwrng *rng, u32 *data)
Loading