drivers/clocksource/timer-cadence-ttc.c
Source file repositories/reference/linux-study-clean/drivers/clocksource/timer-cadence-ttc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/clocksource/timer-cadence-ttc.c- Extension
.c- Size
- 15269 bytes
- Lines
- 566
- 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/clk.hlinux/interrupt.hlinux/clockchips.hlinux/clocksource.hlinux/of_address.hlinux/of_irq.hlinux/platform_device.hlinux/slab.hlinux/sched_clock.hlinux/module.hlinux/of_platform.h
Detected Declarations
struct ttc_timerstruct ttc_timer_clocksourcestruct ttc_timer_clockeventfunction ttc_set_intervalfunction ttc_clock_event_interruptfunction __ttc_clocksource_readfunction ttc_sched_clock_readfunction ttc_set_next_eventfunction ttc_shutdownfunction ttc_set_periodicfunction ttc_resumefunction ttc_rate_change_clocksource_cbfunction ttc_setup_clocksourcefunction ttc_rate_change_clockevent_cbfunction ttc_setup_clockeventfunction ttc_timer_probe
Annotated Snippet
struct ttc_timer {
void __iomem *base_addr;
unsigned long freq;
struct clk *clk;
struct notifier_block clk_rate_change_nb;
};
#define to_ttc_timer(x) \
container_of(x, struct ttc_timer, clk_rate_change_nb)
struct ttc_timer_clocksource {
u32 scale_clk_ctrl_reg_old;
u32 scale_clk_ctrl_reg_new;
struct ttc_timer ttc;
struct clocksource cs;
};
#define to_ttc_timer_clksrc(x) \
container_of(x, struct ttc_timer_clocksource, cs)
struct ttc_timer_clockevent {
struct ttc_timer ttc;
struct clock_event_device ce;
};
#define to_ttc_timer_clkevent(x) \
container_of(x, struct ttc_timer_clockevent, ce)
static void __iomem *ttc_sched_clock_val_reg;
/**
* ttc_set_interval - Set the timer interval value
*
* @timer: Pointer to the timer instance
* @cycles: Timer interval ticks
**/
static void ttc_set_interval(struct ttc_timer *timer,
unsigned long cycles)
{
u32 ctrl_reg;
/* Disable the counter, set the counter value and re-enable counter */
ctrl_reg = readl_relaxed(timer->base_addr + TTC_CNT_CNTRL_OFFSET);
ctrl_reg |= TTC_CNT_CNTRL_DISABLE_MASK;
writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET);
writel_relaxed(cycles, timer->base_addr + TTC_INTR_VAL_OFFSET);
/*
* Reset the counter (0x10) so that it starts from 0, one-shot
* mode makes this needed for timing to be right.
*/
ctrl_reg |= CNT_CNTRL_RESET;
ctrl_reg &= ~TTC_CNT_CNTRL_DISABLE_MASK;
writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET);
}
/**
* ttc_clock_event_interrupt - Clock event timer interrupt handler
*
* @irq: IRQ number of the Timer
* @dev_id: void pointer to the ttc_timer instance
*
* Returns: Always IRQ_HANDLED - success
**/
static irqreturn_t ttc_clock_event_interrupt(int irq, void *dev_id)
{
struct ttc_timer_clockevent *ttce = dev_id;
struct ttc_timer *timer = &ttce->ttc;
/* Acknowledge the interrupt and call event handler */
readl_relaxed(timer->base_addr + TTC_ISR_OFFSET);
ttce->ce.event_handler(&ttce->ce);
return IRQ_HANDLED;
}
/**
* __ttc_clocksource_read - Reads the timer counter register
* @cs: &clocksource to read from
*
* Returns: Current timer counter register value
**/
static u64 __ttc_clocksource_read(struct clocksource *cs)
{
struct ttc_timer *timer = &to_ttc_timer_clksrc(cs)->ttc;
return (u64)readl_relaxed(timer->base_addr +
TTC_COUNT_VAL_OFFSET);
Annotation
- Immediate include surface: `linux/clk.h`, `linux/interrupt.h`, `linux/clockchips.h`, `linux/clocksource.h`, `linux/of_address.h`, `linux/of_irq.h`, `linux/platform_device.h`, `linux/slab.h`.
- Detected declarations: `struct ttc_timer`, `struct ttc_timer_clocksource`, `struct ttc_timer_clockevent`, `function ttc_set_interval`, `function ttc_clock_event_interrupt`, `function __ttc_clocksource_read`, `function ttc_sched_clock_read`, `function ttc_set_next_event`, `function ttc_shutdown`, `function ttc_set_periodic`.
- 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.