drivers/clocksource/timer-stm32.c

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

File Facts

System
Linux kernel
Corpus path
drivers/clocksource/timer-stm32.c
Extension
.c
Size
8594 bytes
Lines
336
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 stm32_timer_private {
	int bits;
};

/**
 * stm32_timer_of_bits_set - set accessor helper
 * @to: a timer_of structure pointer
 * @bits: the number of bits (16 or 32)
 *
 * Accessor helper to set the number of bits in the timer-of private
 * structure.
 *
 */
static void stm32_timer_of_bits_set(struct timer_of *to, int bits)
{
	struct stm32_timer_private *pd = to->private_data;

	pd->bits = bits;
}

/**
 * stm32_timer_of_bits_get - get accessor helper
 * @to: a timer_of structure pointer
 *
 * Accessor helper to get the number of bits in the timer-of private
 * structure.
 *
 * Returns: an integer corresponding to the number of bits.
 */
static int stm32_timer_of_bits_get(struct timer_of *to)
{
	struct stm32_timer_private *pd = to->private_data;

	return pd->bits;
}

static void __iomem *stm32_timer_cnt __read_mostly;

static u64 notrace stm32_read_sched_clock(void)
{
	return readl_relaxed(stm32_timer_cnt);
}

static struct delay_timer stm32_timer_delay;

static unsigned long stm32_read_delay(void)
{
	return readl_relaxed(stm32_timer_cnt);
}

static void stm32_clock_event_disable(struct timer_of *to)
{
	writel_relaxed(0, timer_of_base(to) + TIM_DIER);
}

/**
 * stm32_timer_start - Start the counter without event
 * @to: a timer_of structure pointer
 *
 * Start the timer in order to have the counter reset and start
 * incrementing but disable interrupt event when there is a counter
 * overflow. By default, the counter direction is used as upcounter.
 */
static void stm32_timer_start(struct timer_of *to)
{
	writel_relaxed(TIM_CR1_UDIS | TIM_CR1_CEN, timer_of_base(to) + TIM_CR1);
}

static int stm32_clock_event_shutdown(struct clock_event_device *clkevt)
{
	struct timer_of *to = to_timer_of(clkevt);

	stm32_clock_event_disable(to);

	return 0;
}

static int stm32_clock_event_set_next_event(unsigned long evt,
					    struct clock_event_device *clkevt)
{
	struct timer_of *to = to_timer_of(clkevt);
	unsigned long now, next;

	next = readl_relaxed(timer_of_base(to) + TIM_CNT) + evt;
	writel_relaxed(next, timer_of_base(to) + TIM_CCR1);
	now = readl_relaxed(timer_of_base(to) + TIM_CNT);

	if ((next - now) > evt)
		return -ETIME;

Annotation

Implementation Notes