drivers/char/hw_random/ba431-rng.c
Source file repositories/reference/linux-study-clean/drivers/char/hw_random/ba431-rng.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/char/hw_random/ba431-rng.c- Extension
.c- Size
- 5307 bytes
- Lines
- 220
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/delay.hlinux/hw_random.hlinux/io.hlinux/iopoll.hlinux/kernel.hlinux/mod_devicetable.hlinux/module.hlinux/platform_device.hlinux/workqueue.h
Detected Declarations
struct ba431_trngenum ba431_statefunction ba431_trng_read_regfunction ba431_trng_write_regfunction ba431_trng_get_statefunction ba431_trng_is_in_errorfunction ba431_trng_resetfunction ba431_trng_reset_workfunction ba431_trng_schedule_resetfunction ba431_trng_readfunction ba431_trng_cleanupfunction ba431_trng_initfunction ba431_trng_probe
Annotated Snippet
struct ba431_trng {
struct device *dev;
void __iomem *base;
struct hwrng rng;
atomic_t reset_pending;
struct work_struct reset_work;
};
static inline u32 ba431_trng_read_reg(struct ba431_trng *ba431, u32 reg)
{
return ioread32(ba431->base + reg);
}
static inline void ba431_trng_write_reg(struct ba431_trng *ba431, u32 reg,
u32 val)
{
iowrite32(val, ba431->base + reg);
}
static inline enum ba431_state ba431_trng_get_state(struct ba431_trng *ba431)
{
u32 status = ba431_trng_read_reg(ba431, BA431_REG_STATUS);
return (status & BA431_STATUS_STATE_MASK) >> BA431_STATUS_STATE_OFFSET;
}
static int ba431_trng_is_in_error(struct ba431_trng *ba431)
{
enum ba431_state state = ba431_trng_get_state(ba431);
if ((state < BA431_STATE_STARTUP) ||
(state >= BA431_STATE_ERROR))
return 1;
return 0;
}
static int ba431_trng_reset(struct ba431_trng *ba431)
{
int ret;
/* Disable interrupts, random generation and enable the softreset */
ba431_trng_write_reg(ba431, BA431_REG_CTRL, BA431_CTRL_SOFTRESET);
udelay(BA431_RESET_DELAY);
ba431_trng_write_reg(ba431, BA431_REG_CTRL, BA431_CTRL_ENABLE);
/* Wait until the state changed */
if (readx_poll_timeout(ba431_trng_is_in_error, ba431, ret, !ret,
BA431_RESET_READ_STATUS_INTERVAL,
BA431_RESET_READ_STATUS_TIMEOUT)) {
dev_err(ba431->dev, "reset failed (state: %d)\n",
ba431_trng_get_state(ba431));
return -ETIMEDOUT;
}
dev_info(ba431->dev, "reset done\n");
return 0;
}
static void ba431_trng_reset_work(struct work_struct *work)
{
struct ba431_trng *ba431 = container_of(work, struct ba431_trng,
reset_work);
ba431_trng_reset(ba431);
atomic_set(&ba431->reset_pending, 0);
}
static void ba431_trng_schedule_reset(struct ba431_trng *ba431)
{
if (atomic_cmpxchg(&ba431->reset_pending, 0, 1))
return;
schedule_work(&ba431->reset_work);
}
static int ba431_trng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
{
struct ba431_trng *ba431 = container_of(rng, struct ba431_trng, rng);
u32 *data = buf;
unsigned int level, i;
int n = 0;
while (max > 0) {
level = ba431_trng_read_reg(ba431, BA431_REG_FIFO_LEVEL);
if (!level) {
if (ba431_trng_is_in_error(ba431)) {
ba431_trng_schedule_reset(ba431);
break;
}
Annotation
- Immediate include surface: `linux/delay.h`, `linux/hw_random.h`, `linux/io.h`, `linux/iopoll.h`, `linux/kernel.h`, `linux/mod_devicetable.h`, `linux/module.h`, `linux/platform_device.h`.
- Detected declarations: `struct ba431_trng`, `enum ba431_state`, `function ba431_trng_read_reg`, `function ba431_trng_write_reg`, `function ba431_trng_get_state`, `function ba431_trng_is_in_error`, `function ba431_trng_reset`, `function ba431_trng_reset_work`, `function ba431_trng_schedule_reset`, `function ba431_trng_read`.
- Atlas domain: Driver Families / drivers/char.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.