drivers/clocksource/timer-nxp-stm.c

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

File Facts

System
Linux kernel
Corpus path
drivers/clocksource/timer-nxp-stm.c
Extension
.c
Size
13450 bytes
Lines
497
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

struct stm_timer {
	void __iomem *base;
	unsigned long rate;
	unsigned long delta;
	unsigned long counter;
	struct clock_event_device ced;
	struct clocksource cs;
	atomic_t refcnt;
};

static DEFINE_PER_CPU(struct stm_timer *, stm_timers);

static struct stm_timer *stm_sched_clock;

/*
 * Global structure for multiple STMs initialization
 */
static int stm_instances;

/*
 * This global lock is used to prevent race conditions with the
 * stm_instances in case the driver is using the ASYNC option
 */
static DEFINE_MUTEX(stm_instances_lock);

DEFINE_GUARD(stm_instances, struct mutex *, mutex_lock(_T), mutex_unlock(_T))

static struct stm_timer *cs_to_stm(struct clocksource *cs)
{
	return container_of(cs, struct stm_timer, cs);
}

static struct stm_timer *ced_to_stm(struct clock_event_device *ced)
{
	return container_of(ced, struct stm_timer, ced);
}

static u64 notrace nxp_stm_read_sched_clock(void)
{
	return readl(STM_CNT(stm_sched_clock->base));
}

static u32 nxp_stm_clocksource_getcnt(struct stm_timer *stm_timer)
{
	return readl(STM_CNT(stm_timer->base));
}

static void nxp_stm_clocksource_setcnt(struct stm_timer *stm_timer, u32 cnt)
{
	writel(cnt, STM_CNT(stm_timer->base));
}

static u64 nxp_stm_clocksource_read(struct clocksource *cs)
{
	struct stm_timer *stm_timer = cs_to_stm(cs);

	return (u64)nxp_stm_clocksource_getcnt(stm_timer);
}

static void nxp_stm_module_enable(struct stm_timer *stm_timer)
{
	u32 reg;

	reg = readl(STM_CR(stm_timer->base));

	reg |= STM_ENABLE_MASK;

	writel(reg, STM_CR(stm_timer->base));
}

static void nxp_stm_module_disable(struct stm_timer *stm_timer)
{
	u32 reg;

	reg = readl(STM_CR(stm_timer->base));

	reg &= ~STM_ENABLE_MASK;

	writel(reg, STM_CR(stm_timer->base));
}

static void nxp_stm_module_put(struct stm_timer *stm_timer)
{
	if (atomic_dec_and_test(&stm_timer->refcnt))
		nxp_stm_module_disable(stm_timer);
}

static void nxp_stm_module_get(struct stm_timer *stm_timer)
{
	if (atomic_inc_return(&stm_timer->refcnt) == 1)

Annotation

Implementation Notes