drivers/clocksource/arm_arch_timer.c
Source file repositories/reference/linux-study-clean/drivers/clocksource/arm_arch_timer.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/clocksource/arm_arch_timer.c- Extension
.c- Size
- 34870 bytes
- Lines
- 1288
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/init.hlinux/kernel.hlinux/device.hlinux/smp.hlinux/cpu.hlinux/cpu_pm.hlinux/clockchips.hlinux/clocksource.hlinux/clocksource_ids.hlinux/interrupt.hlinux/kstrtox.hlinux/of_irq.hlinux/of_address.hlinux/io.hlinux/slab.hlinux/sched/clock.hlinux/sched_clock.hlinux/acpi.hlinux/arm-smccc.hlinux/ptp_kvm.hasm/arch_timer.hasm/virt.hclocksource/arm_arch_timer.h
Detected Declarations
struct ate_acpi_oem_infofunction early_evtstrm_cfgfunction arch_counter_get_widthfunction raw_counter_get_cntpct_stablefunction arch_counter_get_cntpct_stablefunction arch_counter_get_cntpctfunction raw_counter_get_cntvct_stablefunction arch_counter_get_cntvct_stablefunction arch_counter_get_cntvctfunction arch_counter_readfunction arch_counter_read_ccfunction fsl_a008585_read_cntpct_el0function fsl_a008585_read_cntvct_el0function hisi_161010101_read_cntpct_el0function hisi_161010101_read_cntvct_el0function arm64_858921_read_cntpct_el0function arm64_858921_read_cntvct_el0function sun50i_a64_read_cntpct_el0function sun50i_a64_read_cntvct_el0function erratum_set_next_event_genericfunction erratum_set_next_event_virtfunction erratum_set_next_event_physfunction arch_timer_check_dt_erratumfunction arch_timer_check_local_cap_erratumfunction arch_timer_check_acpi_oem_erratumfunction arch_timer_iterate_erratafunction arch_timer_enable_workaroundfunction gamefunction arch_timer_check_ool_workaroundfunction arch_timer_this_cpu_has_cntvct_wafunction arch_timer_counter_has_wafunction timer_handlerfunction arch_timer_handler_virtfunction arch_timer_handler_physfunction arch_timer_shutdownfunction arch_timer_shutdown_virtfunction arch_timer_shutdown_physfunction set_next_eventfunction arch_timer_set_next_event_virtfunction arch_timer_set_next_event_physfunction __arch_timer_check_deltafunction __arch_timer_setupfunction arch_timer_evtstrm_enablefunction arch_timer_configure_evtstreamfunction arch_timer_evtstrm_starting_cpufunction arch_timer_evtstrm_dying_cpufunction arch_timer_evtstrm_registerfunction arch_counter_set_user_access
Annotated Snippet
core_initcall(arch_timer_evtstrm_register);
static void arch_counter_set_user_access(void)
{
u32 cntkctl = arch_timer_get_cntkctl();
/* Disable user access to the timers and both counters */
/* Also disable virtual event stream */
cntkctl &= ~(ARCH_TIMER_USR_PT_ACCESS_EN
| ARCH_TIMER_USR_VT_ACCESS_EN
| ARCH_TIMER_USR_VCT_ACCESS_EN
| ARCH_TIMER_VIRT_EVT_EN
| ARCH_TIMER_USR_PCT_ACCESS_EN);
/*
* Enable user access to the virtual counter if it doesn't
* need to be workaround. The vdso may have been already
* disabled though.
*/
if (arch_timer_this_cpu_has_cntvct_wa())
pr_info("CPU%d: Trapping CNTVCT access\n", smp_processor_id());
else
cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN;
arch_timer_set_cntkctl(cntkctl);
}
static bool arch_timer_has_nonsecure_ppi(void)
{
return (arch_timer_uses_ppi == ARCH_TIMER_PHYS_SECURE_PPI &&
arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]);
}
static u32 check_ppi_trigger(int irq)
{
u32 flags = irq_get_trigger_type(irq);
if (flags != IRQF_TRIGGER_HIGH && flags != IRQF_TRIGGER_LOW) {
pr_warn("WARNING: Invalid trigger for IRQ%d, assuming level low\n", irq);
pr_warn("WARNING: Please fix your firmware\n");
flags = IRQF_TRIGGER_LOW;
}
return flags;
}
static int arch_timer_starting_cpu(unsigned int cpu)
{
struct clock_event_device *clk = this_cpu_ptr(arch_timer_evt);
u32 flags;
__arch_timer_setup(clk);
flags = check_ppi_trigger(arch_timer_ppi[arch_timer_uses_ppi]);
enable_percpu_irq(arch_timer_ppi[arch_timer_uses_ppi], flags);
if (arch_timer_has_nonsecure_ppi()) {
flags = check_ppi_trigger(arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]);
enable_percpu_irq(arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI],
flags);
}
arch_counter_set_user_access();
return 0;
}
static int validate_timer_rate(void)
{
if (!arch_timer_rate)
return -EINVAL;
/* Arch timer frequency < 1MHz can cause trouble */
WARN_ON(arch_timer_rate < 1000000);
return 0;
}
/*
* For historical reasons, when probing with DT we use whichever (non-zero)
* rate was probed first, and don't verify that others match. If the first node
* probed has a clock-frequency property, this overrides the HW register.
*/
static void __init arch_timer_of_configure_rate(u32 rate, struct device_node *np)
{
/* Who has more than one independent system counter? */
if (arch_timer_rate)
return;
if (of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
Annotation
- Immediate include surface: `linux/init.h`, `linux/kernel.h`, `linux/device.h`, `linux/smp.h`, `linux/cpu.h`, `linux/cpu_pm.h`, `linux/clockchips.h`, `linux/clocksource.h`.
- Detected declarations: `struct ate_acpi_oem_info`, `function early_evtstrm_cfg`, `function arch_counter_get_width`, `function raw_counter_get_cntpct_stable`, `function arch_counter_get_cntpct_stable`, `function arch_counter_get_cntpct`, `function raw_counter_get_cntvct_stable`, `function arch_counter_get_cntvct_stable`, `function arch_counter_get_cntvct`, `function arch_counter_read`.
- Atlas domain: Driver Families / drivers/clocksource.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- 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.