drivers/crypto/qcom-rng.c

Source file repositories/reference/linux-study-clean/drivers/crypto/qcom-rng.c

File Facts

System
Linux kernel
Corpus path
drivers/crypto/qcom-rng.c
Extension
.c
Size
6283 bytes
Lines
277
Domain
Driver Families
Bucket
drivers/crypto
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct qcom_rng {
	struct mutex lock;
	void __iomem *base;
	struct clk *clk;
	struct hwrng hwrng;
	struct qcom_rng_match_data *match_data;
};

struct qcom_rng_ctx {
	struct qcom_rng *rng;
};

struct qcom_rng_match_data {
	bool skip_init;
	bool hwrng_support;
};

static struct qcom_rng *qcom_rng_dev;

static int qcom_rng_read(struct qcom_rng *rng, u8 *data, unsigned int max)
{
	unsigned int currsize = 0;
	u32 val;
	int ret;

	/* read random data from hardware */
	do {
		ret = readl_poll_timeout(rng->base + PRNG_STATUS, val,
					 val & PRNG_STATUS_DATA_AVAIL,
					 200, 10000);
		if (ret)
			return ret;

		val = readl_relaxed(rng->base + PRNG_DATA_OUT);
		if (!val)
			return -EINVAL;

		if ((max - currsize) >= WORD_SZ) {
			memcpy(data, &val, WORD_SZ);
			data += WORD_SZ;
			currsize += WORD_SZ;
		} else {
			/* copy only remaining bytes */
			memcpy(data, &val, max - currsize);
			currsize = max;
		}
	} while (currsize < max);

	return currsize;
}

static int qcom_rng_generate(struct crypto_rng *tfm,
			     const u8 *src, unsigned int slen,
			     u8 *dstn, unsigned int dlen)
{
	struct qcom_rng_ctx *ctx = crypto_rng_ctx(tfm);
	struct qcom_rng *rng = ctx->rng;
	int ret;

	ret = clk_prepare_enable(rng->clk);
	if (ret)
		return ret;

	mutex_lock(&rng->lock);

	ret = qcom_rng_read(rng, dstn, dlen);

	mutex_unlock(&rng->lock);
	clk_disable_unprepare(rng->clk);

	if (ret >= 0)
		ret = 0;

	return ret;
}

static int qcom_rng_seed(struct crypto_rng *tfm, const u8 *seed,
			 unsigned int slen)
{
	return 0;
}

static int qcom_hwrng_read(struct hwrng *hwrng, void *data, size_t max, bool wait)
{
	struct qcom_rng *qrng = container_of(hwrng, struct qcom_rng, hwrng);

	return qcom_rng_read(qrng, data, max);
}

static int qcom_rng_enable(struct qcom_rng *rng)

Annotation

Implementation Notes