drivers/clocksource/timer-owl.c

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

File Facts

System
Linux kernel
Corpus path
drivers/clocksource/timer-owl.c
Extension
.c
Size
4170 bytes
Lines
177
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-or-later
/*
 * Actions Semi Owl timer
 *
 * Copyright 2012 Actions Semi Inc.
 * Author: Actions Semi, Inc.
 *
 * Copyright (c) 2017 SUSE Linux GmbH
 * Author: Andreas Färber
 */

#include <linux/clk.h>
#include <linux/clockchips.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/irqreturn.h>
#include <linux/sched_clock.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>

#define OWL_Tx_CTL		0x0
#define OWL_Tx_CMP		0x4
#define OWL_Tx_VAL		0x8

#define OWL_Tx_CTL_PD		BIT(0)
#define OWL_Tx_CTL_INTEN	BIT(1)
#define OWL_Tx_CTL_EN		BIT(2)

static void __iomem *owl_timer_base;
static void __iomem *owl_clksrc_base;
static void __iomem *owl_clkevt_base;

static inline void owl_timer_reset(void __iomem *base)
{
	writel(0, base + OWL_Tx_CTL);
	writel(0, base + OWL_Tx_VAL);
	writel(0, base + OWL_Tx_CMP);
}

static inline void owl_timer_set_enabled(void __iomem *base, bool enabled)
{
	u32 ctl = readl(base + OWL_Tx_CTL);

	/* PD bit is cleared when set */
	ctl &= ~OWL_Tx_CTL_PD;

	if (enabled)
		ctl |= OWL_Tx_CTL_EN;
	else
		ctl &= ~OWL_Tx_CTL_EN;

	writel(ctl, base + OWL_Tx_CTL);
}

static u64 notrace owl_timer_sched_read(void)
{
	return (u64)readl(owl_clksrc_base + OWL_Tx_VAL);
}

static int owl_timer_set_state_shutdown(struct clock_event_device *evt)
{
	owl_timer_set_enabled(owl_clkevt_base, false);

	return 0;
}

static int owl_timer_set_state_oneshot(struct clock_event_device *evt)
{
	owl_timer_reset(owl_clkevt_base);

	return 0;
}

static int owl_timer_tick_resume(struct clock_event_device *evt)
{
	return 0;
}

static int owl_timer_set_next_event(unsigned long evt,
				    struct clock_event_device *ev)
{
	void __iomem *base = owl_clkevt_base;

	owl_timer_set_enabled(base, false);
	writel(OWL_Tx_CTL_INTEN, base + OWL_Tx_CTL);
	writel(0, base + OWL_Tx_VAL);
	writel(evt, base + OWL_Tx_CMP);
	owl_timer_set_enabled(base, true);

Annotation

Implementation Notes