drivers/clocksource/timer-rda.c

Source file repositories/reference/linux-study-clean/drivers/clocksource/timer-rda.c

File Facts

System
Linux kernel
Corpus path
drivers/clocksource/timer-rda.c
Extension
.c
Size
4934 bytes
Lines
203
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.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0+
/*
 * RDA8810PL SoC timer driver
 *
 * Copyright RDA Microelectronics Company Limited
 * Copyright (c) 2017 Andreas Färber
 * Copyright (c) 2018 Manivannan Sadhasivam
 *
 * RDA8810PL has two independent timers: OSTIMER (56 bit) and HWTIMER (64 bit).
 * Each timer provides optional interrupt support. In this driver, OSTIMER is
 * used for clockevents and HWTIMER is used for clocksource.
 */

#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/sched_clock.h>

#include "timer-of.h"

#define RDA_OSTIMER_LOADVAL_L	0x000
#define RDA_OSTIMER_CTRL	0x004
#define RDA_HWTIMER_LOCKVAL_L	0x024
#define RDA_HWTIMER_LOCKVAL_H	0x028
#define RDA_TIMER_IRQ_MASK_SET	0x02c
#define RDA_TIMER_IRQ_MASK_CLR	0x030
#define RDA_TIMER_IRQ_CLR	0x034

#define RDA_OSTIMER_CTRL_ENABLE		BIT(24)
#define RDA_OSTIMER_CTRL_REPEAT		BIT(28)
#define RDA_OSTIMER_CTRL_LOAD		BIT(30)

#define RDA_TIMER_IRQ_MASK_OSTIMER	BIT(0)

#define RDA_TIMER_IRQ_CLR_OSTIMER	BIT(0)

static int rda_ostimer_start(void __iomem *base, bool periodic, u64 cycles)
{
	u32 ctrl, load_l;

	load_l = (u32)cycles;
	ctrl = ((cycles >> 32) & 0xffffff);
	ctrl |= RDA_OSTIMER_CTRL_LOAD | RDA_OSTIMER_CTRL_ENABLE;
	if (periodic)
		ctrl |= RDA_OSTIMER_CTRL_REPEAT;

	/* Enable ostimer interrupt first */
	writel_relaxed(RDA_TIMER_IRQ_MASK_OSTIMER,
		       base + RDA_TIMER_IRQ_MASK_SET);

	/* Write low 32 bits first, high 24 bits are with ctrl */
	writel_relaxed(load_l, base + RDA_OSTIMER_LOADVAL_L);
	writel_relaxed(ctrl, base + RDA_OSTIMER_CTRL);

	return 0;
}

static int rda_ostimer_stop(void __iomem *base)
{
	/* Disable ostimer interrupt first */
	writel_relaxed(RDA_TIMER_IRQ_MASK_OSTIMER,
		       base + RDA_TIMER_IRQ_MASK_CLR);

	writel_relaxed(0, base + RDA_OSTIMER_CTRL);

	return 0;
}

static int rda_ostimer_set_state_shutdown(struct clock_event_device *evt)
{
	struct timer_of *to = to_timer_of(evt);

	rda_ostimer_stop(timer_of_base(to));

	return 0;
}

static int rda_ostimer_set_state_oneshot(struct clock_event_device *evt)
{
	struct timer_of *to = to_timer_of(evt);

	rda_ostimer_stop(timer_of_base(to));

	return 0;
}

static int rda_ostimer_set_state_periodic(struct clock_event_device *evt)
{
	struct timer_of *to = to_timer_of(evt);
	unsigned long cycles_per_jiffy;

Annotation

Implementation Notes