drivers/clocksource/timer-ep93xx.c
Source file repositories/reference/linux-study-clean/drivers/clocksource/timer-ep93xx.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/clocksource/timer-ep93xx.c- Extension
.c- Size
- 5361 bytes
- Lines
- 190
- Domain
- Driver Families
- Bucket
- drivers/clocksource
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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/clockchips.hlinux/clocksource.hlinux/init.hlinux/interrupt.hlinux/io.hlinux/io-64-nonatomic-lo-hi.hlinux/irq.hlinux/kernel.hlinux/of_address.hlinux/of_irq.hlinux/sched_clock.hasm/mach/time.h
Detected Declarations
struct ep93xx_tcufunction ep93xx_clocksource_readfunction ep93xx_read_sched_clockfunction ep93xx_clkevt_set_next_eventfunction ep93xx_clkevt_shutdownfunction ep93xx_timer_interruptfunction ep93xx_timer_of_init
Annotated Snippet
struct ep93xx_tcu {
void __iomem *base;
};
static struct ep93xx_tcu *ep93xx_tcu;
static u64 ep93xx_clocksource_read(struct clocksource *c)
{
struct ep93xx_tcu *tcu = ep93xx_tcu;
return lo_hi_readq(tcu->base + EP93XX_TIMER4_VALUE_LOW) & GENMASK_ULL(39, 0);
}
static u64 notrace ep93xx_read_sched_clock(void)
{
return ep93xx_clocksource_read(NULL);
}
static int ep93xx_clkevt_set_next_event(unsigned long next,
struct clock_event_device *evt)
{
struct ep93xx_tcu *tcu = ep93xx_tcu;
/* Default mode: periodic, off, 508 kHz */
u32 tmode = EP93XX_TIMER123_CONTROL_MODE |
EP93XX_TIMER123_CONTROL_CLKSEL;
/* Clear timer */
writel(tmode, tcu->base + EP93XX_TIMER3_CONTROL);
/* Set next event */
writel(next, tcu->base + EP93XX_TIMER3_LOAD);
writel(tmode | EP93XX_TIMER123_CONTROL_ENABLE,
tcu->base + EP93XX_TIMER3_CONTROL);
return 0;
}
static int ep93xx_clkevt_shutdown(struct clock_event_device *evt)
{
struct ep93xx_tcu *tcu = ep93xx_tcu;
/* Disable timer */
writel(0, tcu->base + EP93XX_TIMER3_CONTROL);
return 0;
}
static struct clock_event_device ep93xx_clockevent = {
.name = "timer1",
.features = CLOCK_EVT_FEAT_ONESHOT,
.set_state_shutdown = ep93xx_clkevt_shutdown,
.set_state_oneshot = ep93xx_clkevt_shutdown,
.tick_resume = ep93xx_clkevt_shutdown,
.set_next_event = ep93xx_clkevt_set_next_event,
.rating = 300,
};
static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id)
{
struct ep93xx_tcu *tcu = ep93xx_tcu;
struct clock_event_device *evt = dev_id;
/* Writing any value clears the timer interrupt */
writel(1, tcu->base + EP93XX_TIMER3_CLEAR);
evt->event_handler(evt);
return IRQ_HANDLED;
}
static int __init ep93xx_timer_of_init(struct device_node *np)
{
int irq;
unsigned long flags = IRQF_TIMER | IRQF_IRQPOLL;
struct ep93xx_tcu *tcu;
int ret;
tcu = kzalloc_obj(*tcu);
if (!tcu)
return -ENOMEM;
tcu->base = of_iomap(np, 0);
if (!tcu->base) {
pr_err("Can't remap registers\n");
ret = -ENXIO;
goto out_free;
}
ep93xx_tcu = tcu;
irq = irq_of_parse_and_map(np, 0);
if (!irq) {
Annotation
- Immediate include surface: `linux/clockchips.h`, `linux/clocksource.h`, `linux/init.h`, `linux/interrupt.h`, `linux/io.h`, `linux/io-64-nonatomic-lo-hi.h`, `linux/irq.h`, `linux/kernel.h`.
- Detected declarations: `struct ep93xx_tcu`, `function ep93xx_clocksource_read`, `function ep93xx_read_sched_clock`, `function ep93xx_clkevt_set_next_event`, `function ep93xx_clkevt_shutdown`, `function ep93xx_timer_interrupt`, `function ep93xx_timer_of_init`.
- Atlas domain: Driver Families / drivers/clocksource.
- Implementation status: source implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.