static void s5p_sched_timer_start(unsigned long load_val, int autoreset) { unsigned long tcon; unsigned long tcnt; unsigned long tcfg; tcnt = TICK_MAX; /* default value for tcnt */ /* initialize system timer clock */ tcfg = s5p_systimer_read(S5P_SYSTIMER_TCFG); tcfg &= ~S5P_SYSTIMER_TCLK_MASK; tcfg |= S5P_SYSTIMER_TCLK_USB; s5p_systimer_write(S5P_SYSTIMER_TCFG, tcfg); /* TCFG must not be changed at run-time. * If you want to change TCFG, stop timer(TCON[0] = 0) */ s5p_systimer_write(S5P_SYSTIMER_TCON, 0); /* read the current timer configuration bits */ tcon = s5p_systimer_read(S5P_SYSTIMER_TCON); tcfg = s5p_systimer_read(S5P_SYSTIMER_TCFG); tcfg &= ~S5P_SYSTIMER_TCLK_MASK; tcfg |= S5P_SYSTIMER_TCLK_USB; tcfg &= ~S5P_SYSTIMER_PRESCALER_MASK; /* check to see if timer is within 16bit range... */ if (tcnt > TICK_MAX) { panic("setup_timer: cannot configure timer!"); return; } s5p_systimer_write(S5P_SYSTIMER_TCFG, tcfg); s5p_systimer_write(S5P_SYSTIMER_TICNTB, tcnt); #if !defined(USE_SYSTIMER_IRQ) /* set timer con */ tcon = (S5P_SYSTIMER_START | S5P_SYSTIMER_AUTO_RELOAD); s5p_systimer_write(S5P_SYSTIMER_TCON, tcon); #else /* set timer con */ tcon = S5P_SYSTIMER_INT_AUTO | S5P_SYSTIMER_START | S5P_SYSTIMER_AUTO_RELOAD; s5p_systimer_write(S5P_SYSTIMER_TCON, tcon); tcon |= S5P_SYSTIMER_INT_START; s5p_systimer_write(S5P_SYSTIMER_TCON, tcon); /* Interrupt Start and Enable */ s5p_systimer_write(S5P_SYSTIMER_INT_CSTAT, (S5P_SYSTIMER_INT_ICNTEIE | S5P_SYSTIMER_INT_INTENABLE)); #endif sched_timer_running = 1; }
/* * --------------------------------------------------------------------------- * SYSTEM TIMER ... free running 32-bit clock source and scheduler clock * --------------------------------------------------------------------------- */ irqreturn_t s5p_sched_timer_interrupt(int irq, void *dev_id) { volatile unsigned int temp_cstat; temp_cstat = s5p_systimer_read(S5P_SYSTIMER_INT_CSTAT); temp_cstat |= S5P_SYSTIMER_INT_INTCNT; s5p_systimer_write(S5P_SYSTIMER_INT_CSTAT, temp_cstat); if (unlikely(pending_irq)) pending_irq = 0; else s5p_sched_timer_overflows++; return IRQ_HANDLED; }