Exemplo n.º 1
0
static int omap_32k_timer_set_next_event(unsigned long delta,
					 struct clock_event_device *dev)
{
	omap_32k_timer_start(delta);

	return 0;
}
Exemplo n.º 2
0
static __init void omap_init_32k_timer(void)
{

#ifdef CONFIG_NO_IDLE_HZ
	omap_timer.dyn_tick = &omap_dyn_tick_timer;
#endif

	setup_irq(INT_OS_TIMER, &omap_32k_timer_irq);
	omap_timer.offset  = omap_32k_timer_gettimeoffset;
	omap_32k_last_tick = omap_32k_sync_timer_read();
	omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
}
Exemplo n.º 3
0
static void omap_32k_timer_set_mode(enum clock_event_mode mode,
				    struct clock_event_device *evt)
{
	omap_32k_timer_stop();

	switch (mode) {
	case CLOCK_EVT_MODE_PERIODIC:
		omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
		break;
	case CLOCK_EVT_MODE_ONESHOT:
	case CLOCK_EVT_MODE_UNUSED:
	case CLOCK_EVT_MODE_SHUTDOWN:
		break;
	case CLOCK_EVT_MODE_RESUME:
		break;
	}
}
Exemplo n.º 4
0
/*
 * Timer interrupt for 32KHz timer. When dynamic tick is enabled, this
 * function is also called from other interrupts to remove latency
 * issues with dynamic tick. In the dynamic tick case, we need to lock
 * with irqsave.
 */
static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
					    struct pt_regs *regs)
{
	unsigned long flags;
	unsigned long now;

	write_seqlock_irqsave(&xtime_lock, flags);
	now = omap_32k_sync_timer_read();

	while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) {
#ifdef OMAP_32K_TICK_MODULO
		/* Modulo addition may put omap_32k_last_tick ahead of now
		 * and cause unwanted repetition of the while loop.
		 */
		if (unlikely(now - omap_32k_last_tick == ~0))
			break;

		modulo_count += OMAP_32K_TICK_MODULO;
		if (modulo_count > HZ) {
			++omap_32k_last_tick;
			modulo_count -= HZ;
		}
#endif
		omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ;
		timer_tick(regs);
	}

	/* Restart timer so we don't drift off due to modulo or dynamic tick.
	 * By default we program the next timer to be continuous to avoid
	 * latencies during high system load. During dynamic tick operation the
	 * continuous timer can be overridden from pm_idle to be longer.
	 */
	omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now);
	write_sequnlock_irqrestore(&xtime_lock, flags);

	return IRQ_HANDLED;
}
Exemplo n.º 5
0
static int omap_32k_timer_disable_dyn_tick(void)
{
	omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
	return 0;
}
Exemplo n.º 6
0
/*
 * Programs the next timer interrupt needed. Called when dynamic tick is
 * enabled, and to reprogram the ticks to skip from pm_idle. Note that
 * we can keep the timer continuous, and don't need to set it to run in
 * one-shot mode. This is because the timer will get reprogrammed again
 * after next interrupt.
 */
void omap_32k_timer_reprogram(unsigned long next_tick)
{
	omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1);
}