drivers/clocksource/timer-msc313e.c

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

File Facts

System
Linux kernel
Corpus path
drivers/clocksource/timer-msc313e.c
Extension
.c
Size
6110 bytes
Lines
254
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 msc313e_delay {
	void __iomem *base;
	struct delay_timer delay;
};
static struct msc313e_delay msc313e_delay;
#endif

static void __iomem *msc313e_clksrc;

static void msc313e_timer_stop(void __iomem *base)
{
	writew(0, base + MSC313E_REG_CTRL);
}

static void msc313e_timer_start(void __iomem *base, bool periodic)
{
	u16 reg;

	reg = readw(base + MSC313E_REG_CTRL);
	if (periodic)
		reg |= MSC313E_REG_CTRL_TIMER_EN;
	else
		reg |= MSC313E_REG_CTRL_TIMER_TRIG;
	writew(reg | MSC313E_REG_CTRL_TIMER_INT_EN, base + MSC313E_REG_CTRL);
}

static void msc313e_timer_setup(void __iomem *base, unsigned long delay)
{
	unsigned long flags;

	local_irq_save(flags);
	writew(delay >> 16, base + MSC313E_REG_TIMER_MAX_HIGH);
	writew(delay & 0xffff, base + MSC313E_REG_TIMER_MAX_LOW);
	local_irq_restore(flags);
}

static unsigned long msc313e_timer_current_value(void __iomem *base)
{
	unsigned long flags;
	u16 l, h;

	local_irq_save(flags);
	l = readw(base + MSC313E_REG_COUNTER_LOW);
	h = readw(base + MSC313E_REG_COUNTER_HIGH);
	local_irq_restore(flags);

	return (((u32)h) << 16 | l);
}

static int msc313e_timer_clkevt_shutdown(struct clock_event_device *evt)
{
	struct timer_of *timer = to_timer_of(evt);

	msc313e_timer_stop(timer_of_base(timer));

	return 0;
}

static int msc313e_timer_clkevt_set_oneshot(struct clock_event_device *evt)
{
	struct timer_of *timer = to_timer_of(evt);

	msc313e_timer_stop(timer_of_base(timer));
	msc313e_timer_start(timer_of_base(timer), false);

	return 0;
}

static int msc313e_timer_clkevt_set_periodic(struct clock_event_device *evt)
{
	struct timer_of *timer = to_timer_of(evt);

	msc313e_timer_stop(timer_of_base(timer));
	msc313e_timer_setup(timer_of_base(timer), timer_of_period(timer));
	msc313e_timer_start(timer_of_base(timer), true);

	return 0;
}

static int msc313e_timer_clkevt_next_event(unsigned long evt, struct clock_event_device *clkevt)
{
	struct timer_of *timer = to_timer_of(clkevt);

	msc313e_timer_stop(timer_of_base(timer));
	msc313e_timer_setup(timer_of_base(timer), evt);
	msc313e_timer_start(timer_of_base(timer), false);

	return 0;
}

Annotation

Implementation Notes