drivers/char/hw_random/exynos-trng.c
Source file repositories/reference/linux-study-clean/drivers/char/hw_random/exynos-trng.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/char/hw_random/exynos-trng.c- Extension
.c- Size
- 8143 bytes
- Lines
- 346
- Domain
- Driver Families
- Bucket
- drivers/char
- 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.
- 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/arm-smccc.hlinux/clk.hlinux/crypto.hlinux/delay.hlinux/err.hlinux/hw_random.hlinux/io.hlinux/iopoll.hlinux/kernel.hlinux/module.hlinux/mod_devicetable.hlinux/platform_device.hlinux/pm_runtime.hlinux/property.h
Detected Declarations
struct exynos_trng_devfunction exynos_trng_do_read_regfunction exynos_trng_do_read_smcfunction exynos_trng_init_regfunction exynos_trng_init_smcfunction exynos_trng_probefunction exynos_trng_removefunction exynos_trng_suspendfunction exynos_trng_resume
Annotated Snippet
struct exynos_trng_dev {
struct device *dev;
void __iomem *mem;
struct clk *clk; /* operating clock */
struct clk *pclk; /* bus clock */
struct hwrng rng;
unsigned long flags;
};
static int exynos_trng_do_read_reg(struct hwrng *rng, void *data, size_t max,
bool wait)
{
struct exynos_trng_dev *trng = (struct exynos_trng_dev *)rng->priv;
int val;
max = min_t(size_t, max, (EXYNOS_TRNG_FIFO_LEN * 4));
writel_relaxed(max * 8, trng->mem + EXYNOS_TRNG_FIFO_CTRL);
val = readl_poll_timeout(trng->mem + EXYNOS_TRNG_FIFO_CTRL, val,
val == 0, 200, 1000000);
if (val < 0)
return val;
memcpy_fromio(data, trng->mem + EXYNOS_TRNG_FIFO_0, max);
return max;
}
static int exynos_trng_do_read_smc(struct hwrng *rng, void *data, size_t max,
bool wait)
{
struct arm_smccc_res res;
unsigned int copied = 0;
u32 *buf = data;
int tries = 0;
while (copied < max) {
arm_smccc_smc(SMC_CMD_RANDOM, HWRNG_GET_DATA, 0, 0, 0, 0, 0, 0,
&res);
switch (res.a0) {
case HWRNG_RET_OK:
*buf++ = res.a2;
*buf++ = res.a3;
copied += 8;
tries = 0;
break;
case HWRNG_RET_RETRY_ERROR:
if (!wait)
return copied;
if (++tries >= HWRNG_MAX_TRIES)
return copied;
cond_resched();
break;
default:
return -EIO;
}
}
return copied;
}
static int exynos_trng_init_reg(struct hwrng *rng)
{
struct exynos_trng_dev *trng = (struct exynos_trng_dev *)rng->priv;
unsigned long sss_rate;
u32 val;
sss_rate = clk_get_rate(trng->clk);
/*
* For most TRNG circuits the clock frequency of under 500 kHz
* is safe.
*/
val = sss_rate / (EXYNOS_TRNG_CLOCK_RATE * 2);
if (val > 0x7fff) {
dev_err(trng->dev, "clock divider too large: %d\n", val);
return -ERANGE;
}
val = val << 1;
writel_relaxed(val, trng->mem + EXYNOS_TRNG_CLKDIV);
/* Enable the generator. */
val = EXYNOS_TRNG_CTRL_RNGEN;
writel_relaxed(val, trng->mem + EXYNOS_TRNG_CTRL);
/*
* Disable post-processing. /dev/hwrng is supposed to deliver
* unprocessed data.
*/
writel_relaxed(0, trng->mem + EXYNOS_TRNG_POST_CTRL);
Annotation
- Immediate include surface: `linux/arm-smccc.h`, `linux/clk.h`, `linux/crypto.h`, `linux/delay.h`, `linux/err.h`, `linux/hw_random.h`, `linux/io.h`, `linux/iopoll.h`.
- Detected declarations: `struct exynos_trng_dev`, `function exynos_trng_do_read_reg`, `function exynos_trng_do_read_smc`, `function exynos_trng_init_reg`, `function exynos_trng_init_smc`, `function exynos_trng_probe`, `function exynos_trng_remove`, `function exynos_trng_suspend`, `function exynos_trng_resume`.
- Atlas domain: Driver Families / drivers/char.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.