/** * 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. *
*/ staticvoid 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.
*/ staticint stm32_timer_of_bits_get(struct timer_of *to)
{ struct stm32_timer_private *pd = to->private_data;
/** * 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.
*/ staticvoid stm32_timer_start(struct timer_of *to)
{
writel_relaxed(TIM_CR1_UDIS | TIM_CR1_CEN, timer_of_base(to) + TIM_CR1);
}
if (clockevent_state_periodic(clkevt))
stm32_clock_event_set_periodic(clkevt); else
stm32_clock_event_shutdown(clkevt);
clkevt->event_handler(clkevt);
return IRQ_HANDLED;
}
/** * stm32_timer_set_width - Sort out the timer width (32/16) * @to: a pointer to a timer-of structure * * Write the 32-bit max value and read/return the result. If the timer * is 32 bits wide, the result will be UINT_MAX, otherwise it will * be truncated by the 16-bit register to USHRT_MAX. *
*/ staticvoid __init stm32_timer_set_width(struct timer_of *to)
{
u32 width;
/** * stm32_timer_set_prescaler - Compute and set the prescaler register * @to: a pointer to a timer-of structure * * Depending on the timer width, compute the prescaler to always * target a 10MHz timer rate for 16 bits. 32-bit timers are * considered precise and long enough to not use the prescaler.
*/ staticvoid __init stm32_timer_set_prescaler(struct timer_of *to)
{ int prescaler = 1;
if (stm32_timer_of_bits_get(to) != 32) {
prescaler = DIV_ROUND_CLOSEST(timer_of_rate(to),
TIM_PSC_CLKRATE); /* * The prescaler register is an u16, the variable * can't be greater than TIM_PSC_MAX, let's cap it in * this case.
*/
prescaler = prescaler < TIM_PSC_MAX ? prescaler : TIM_PSC_MAX;
}
/* Adjust rate and period given the prescaler value */
to->of_clk.rate = DIV_ROUND_CLOSEST(to->of_clk.rate, prescaler);
to->of_clk.period = DIV_ROUND_UP(to->of_clk.rate, HZ);
}
/* * This driver allows to register several timers and relies on * the generic time framework to select the right one. * However, nothing allows to do the same for the * sched_clock. We are not interested in a sched_clock for the * 16-bit timers but only for the 32-bit one, so if no 32-bit * timer is registered yet, we select this 32-bit timer as a * sched_clock.
*/ if (bits == 32 && !stm32_timer_cnt) {
/* * Start immediately the counter as we will be using * it right after.
*/
stm32_timer_start(to);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.