drivers/clocksource/timer-davinci.c

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

File Facts

System
Linux kernel
Corpus path
drivers/clocksource/timer-davinci.c
Extension
.c
Size
10230 bytes
Lines
385
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 davinci_clockevent {
	struct clock_event_device dev;
	void __iomem *base;
	unsigned int cmp_off;
};

/*
 * This must be globally accessible by davinci_timer_read_sched_clock(), so
 * let's keep it here.
 */
static struct {
	struct clocksource dev;
	void __iomem *base;
	unsigned int tim_off;
} davinci_clocksource;

static struct davinci_clockevent *
to_davinci_clockevent(struct clock_event_device *clockevent)
{
	return container_of(clockevent, struct davinci_clockevent, dev);
}

static unsigned int
davinci_clockevent_read(struct davinci_clockevent *clockevent,
			unsigned int reg)
{
	return readl_relaxed(clockevent->base + reg);
}

static void davinci_clockevent_write(struct davinci_clockevent *clockevent,
				     unsigned int reg, unsigned int val)
{
	writel_relaxed(val, clockevent->base + reg);
}

static void davinci_tim12_shutdown(void __iomem *base)
{
	unsigned int tcr;

	tcr = DAVINCI_TIMER_ENAMODE_DISABLED <<
		DAVINCI_TIMER_ENAMODE_SHIFT_TIM12;
	/*
	 * This function is only ever called if we're using both timer
	 * halves. In this case TIM34 runs in periodic mode and we must
	 * not modify it.
	 */
	tcr |= DAVINCI_TIMER_ENAMODE_PERIODIC <<
		DAVINCI_TIMER_ENAMODE_SHIFT_TIM34;

	writel_relaxed(tcr, base + DAVINCI_TIMER_REG_TCR);
}

static void davinci_tim12_set_oneshot(void __iomem *base)
{
	unsigned int tcr;

	tcr = DAVINCI_TIMER_ENAMODE_ONESHOT <<
		DAVINCI_TIMER_ENAMODE_SHIFT_TIM12;
	/* Same as above. */
	tcr |= DAVINCI_TIMER_ENAMODE_PERIODIC <<
		DAVINCI_TIMER_ENAMODE_SHIFT_TIM34;

	writel_relaxed(tcr, base + DAVINCI_TIMER_REG_TCR);
}

static int davinci_clockevent_shutdown(struct clock_event_device *dev)
{
	struct davinci_clockevent *clockevent;

	clockevent = to_davinci_clockevent(dev);

	davinci_tim12_shutdown(clockevent->base);

	return 0;
}

static int davinci_clockevent_set_oneshot(struct clock_event_device *dev)
{
	struct davinci_clockevent *clockevent = to_davinci_clockevent(dev);

	davinci_clockevent_write(clockevent, DAVINCI_TIMER_REG_TIM12, 0x0);

	davinci_tim12_set_oneshot(clockevent->base);

	return 0;
}

static int
davinci_clockevent_set_next_event_std(unsigned long cycles,
				      struct clock_event_device *dev)

Annotation

Implementation Notes