drivers/clocksource/timer-ti-dm-systimer.c
Source file repositories/reference/linux-study-clean/drivers/clocksource/timer-ti-dm-systimer.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/clocksource/timer-ti-dm-systimer.c- Extension
.c- Size
- 22177 bytes
- Lines
- 853
- Domain
- Driver Families
- Bucket
- drivers/clocksource
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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/clocksource.hlinux/clockchips.hlinux/cpuhotplug.hlinux/interrupt.hlinux/io.hlinux/iopoll.hlinux/err.hlinux/of.hlinux/of_address.hlinux/of_irq.hlinux/sched_clock.hlinux/clk/clk-conf.hclocksource/timer-ti-dm.hdt-bindings/bus/ti-sysc.h
Detected Declarations
struct dmtimer_systimerstruct dmtimer_clockeventstruct dmtimer_clocksourcefunction dmtimer_systimer_revision1function dmtimer_systimer_enablefunction dmtimer_systimer_disablefunction dmtimer_systimer_type1_resetfunction dmtimer_systimer_type2_resetfunction dmtimer_systimer_resetfunction dmtimer_systimer_check_counter32kfunction dmtimer_is_preferredfunction dmtimer_systimer_assign_alwonfunction for_each_matching_nodefunction dmtimer_systimer_find_first_availablefunction for_each_matching_nodefunction dmtimer_systimer_select_bestfunction dmtimer_systimer_init_clockfunction dmtimer_systimer_setupfunction to_dmtimer_clockeventfunction dmtimer_clockevent_interruptfunction dmtimer_set_next_eventfunction dmtimer_clockevent_shutdownfunction dmtimer_set_periodicfunction omap_clockevent_idlefunction omap_clockevent_unidlefunction dmtimer_clkevt_init_commonfunction dmtimer_clockevent_initfunction dmtimer_percpu_timer_initfunction omap_dmtimer_starting_cpufunction dmtimer_percpu_timer_startupfunction dmtimer_percpu_quirk_initfunction to_dmtimer_clocksourcefunction dmtimer_clocksource_read_cyclesfunction dmtimer_read_sched_clockfunction dmtimer_clocksource_suspendfunction dmtimer_clocksource_resumefunction dmtimer_clocksource_initfunction dmtimer_systimer_initmodule init dmtimer_percpu_timer_startup
Annotated Snippet
subsys_initcall(dmtimer_percpu_timer_startup);
static int __init dmtimer_percpu_quirk_init(struct device_node *np, u32 pa)
{
struct device_node *arm_timer __free(device_node) =
of_find_compatible_node(NULL, NULL, "arm,armv7-timer");
if (of_device_is_available(arm_timer)) {
pr_warn_once("ARM architected timer wrap issue i940 detected\n");
return 0;
}
if (pa == 0x4882c000) /* dra7 dmtimer15 */
return dmtimer_percpu_timer_init(np, 0);
else if (pa == 0x4882e000) /* dra7 dmtimer16 */
return dmtimer_percpu_timer_init(np, 1);
return 0;
}
/* Clocksource */
static struct dmtimer_clocksource *
to_dmtimer_clocksource(struct clocksource *cs)
{
return container_of(cs, struct dmtimer_clocksource, dev);
}
static u64 dmtimer_clocksource_read_cycles(struct clocksource *cs)
{
struct dmtimer_clocksource *clksrc = to_dmtimer_clocksource(cs);
struct dmtimer_systimer *t = &clksrc->t;
return (u64)readl_relaxed(t->base + t->counter);
}
static void __iomem *dmtimer_sched_clock_counter;
static u64 notrace dmtimer_read_sched_clock(void)
{
return readl_relaxed(dmtimer_sched_clock_counter);
}
static void dmtimer_clocksource_suspend(struct clocksource *cs)
{
struct dmtimer_clocksource *clksrc = to_dmtimer_clocksource(cs);
struct dmtimer_systimer *t = &clksrc->t;
clksrc->loadval = readl_relaxed(t->base + t->counter);
dmtimer_systimer_disable(t);
clk_disable(t->fck);
}
static void dmtimer_clocksource_resume(struct clocksource *cs)
{
struct dmtimer_clocksource *clksrc = to_dmtimer_clocksource(cs);
struct dmtimer_systimer *t = &clksrc->t;
int error;
error = clk_enable(t->fck);
if (error)
pr_err("could not enable timer fck on resume: %i\n", error);
dmtimer_systimer_enable(t);
writel_relaxed(clksrc->loadval, t->base + t->counter);
writel_relaxed(OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR,
t->base + t->ctrl);
}
static int __init dmtimer_clocksource_init(struct device_node *np)
{
struct dmtimer_clocksource *clksrc;
struct dmtimer_systimer *t;
struct clocksource *dev;
int error;
clksrc = kzalloc_obj(*clksrc);
if (!clksrc)
return -ENOMEM;
dev = &clksrc->dev;
t = &clksrc->t;
error = dmtimer_systimer_setup(np, t);
if (error)
goto err_out_free;
dev->name = "dmtimer";
dev->rating = 300;
dev->read = dmtimer_clocksource_read_cycles;
dev->mask = CLOCKSOURCE_MASK(32);
Annotation
- Immediate include surface: `linux/clk.h`, `linux/clocksource.h`, `linux/clockchips.h`, `linux/cpuhotplug.h`, `linux/interrupt.h`, `linux/io.h`, `linux/iopoll.h`, `linux/err.h`.
- Detected declarations: `struct dmtimer_systimer`, `struct dmtimer_clockevent`, `struct dmtimer_clocksource`, `function dmtimer_systimer_revision1`, `function dmtimer_systimer_enable`, `function dmtimer_systimer_disable`, `function dmtimer_systimer_type1_reset`, `function dmtimer_systimer_type2_reset`, `function dmtimer_systimer_reset`, `function dmtimer_systimer_check_counter32k`.
- Atlas domain: Driver Families / drivers/clocksource.
- Implementation status: integration 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.