drivers/clocksource/bcm_kona_timer.c
Source file repositories/reference/linux-study-clean/drivers/clocksource/bcm_kona_timer.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/clocksource/bcm_kona_timer.c- Extension
.c- Size
- 4887 bytes
- Lines
- 193
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/init.hlinux/irq.hlinux/interrupt.hlinux/jiffies.hlinux/clockchips.hlinux/types.hlinux/clk.hlinux/io.hlinux/of.hlinux/of_address.hlinux/of_irq.h
Detected Declarations
struct kona_bcm_timersfunction kona_timer_disable_and_clearfunction kona_timer_get_counterfunction kona_timer_set_next_eventfunction kona_timer_shutdownfunction kona_timer_clockevents_initfunction kona_timer_interruptfunction kona_timer_init
Annotated Snippet
struct kona_bcm_timers {
int tmr_irq;
void __iomem *tmr_regs;
};
static struct kona_bcm_timers timers;
static u32 arch_timer_rate;
/*
* We use the peripheral timers for system tick, the cpu global timer for
* profile tick
*/
static void kona_timer_disable_and_clear(void __iomem *base)
{
uint32_t reg;
/*
* clear and disable interrupts
* We are using compare/match register 0 for our system interrupts
*/
reg = readl(base + KONA_GPTIMER_STCS_OFFSET);
/* Clear compare (0) interrupt */
reg |= 1 << KONA_GPTIMER_STCS_TIMER_MATCH_SHIFT;
/* disable compare */
reg &= ~(1 << KONA_GPTIMER_STCS_COMPARE_ENABLE_SHIFT);
writel(reg, base + KONA_GPTIMER_STCS_OFFSET);
}
static int
kona_timer_get_counter(void __iomem *timer_base, uint32_t *msw, uint32_t *lsw)
{
int loop_limit = 3;
/*
* Read 64-bit free running counter
* 1. Read hi-word
* 2. Read low-word
* 3. Read hi-word again
* 4.1
* if new hi-word is not equal to previously read hi-word, then
* start from #1
* 4.2
* if new hi-word is equal to previously read hi-word then stop.
*/
do {
*msw = readl(timer_base + KONA_GPTIMER_STCHI_OFFSET);
*lsw = readl(timer_base + KONA_GPTIMER_STCLO_OFFSET);
if (*msw == readl(timer_base + KONA_GPTIMER_STCHI_OFFSET))
break;
} while (--loop_limit);
if (!loop_limit) {
pr_err("bcm_kona_timer: getting counter failed.\n");
pr_err(" Timer will be impacted\n");
return -ETIMEDOUT;
}
return 0;
}
static int kona_timer_set_next_event(unsigned long clc,
struct clock_event_device *unused)
{
/*
* timer (0) is disabled by the timer interrupt already
* so, here we reload the next event value and re-enable
* the timer.
*
* This way, we are potentially losing the time between
* timer-interrupt->set_next_event. CPU local timers, when
* they come in should get rid of skew.
*/
uint32_t lsw, msw;
uint32_t reg;
int ret;
ret = kona_timer_get_counter(timers.tmr_regs, &msw, &lsw);
if (ret)
return ret;
/* Load the "next" event tick value */
writel(lsw + clc, timers.tmr_regs + KONA_GPTIMER_STCM0_OFFSET);
/* Enable compare */
reg = readl(timers.tmr_regs + KONA_GPTIMER_STCS_OFFSET);
Annotation
- Immediate include surface: `linux/init.h`, `linux/irq.h`, `linux/interrupt.h`, `linux/jiffies.h`, `linux/clockchips.h`, `linux/types.h`, `linux/clk.h`, `linux/io.h`.
- Detected declarations: `struct kona_bcm_timers`, `function kona_timer_disable_and_clear`, `function kona_timer_get_counter`, `function kona_timer_set_next_event`, `function kona_timer_shutdown`, `function kona_timer_clockevents_init`, `function kona_timer_interrupt`, `function kona_timer_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.