/* Called with ints off */ void __INLINE__ start_timer_trig(unsigned long delay_us) { reg_timer_rw_ack_intr ack_intr = { 0 }; reg_timer_rw_intr_mask intr_mask; reg_timer_rw_trig trig; reg_timer_rw_trig_cfg trig_cfg = { 0 }; reg_timer_r_time r_time; r_time = REG_RD(timer, regi_timer, r_time); D1(printk("start_timer_trig : %d us freq: %i div: %i\n", delay_us, freq_index, div)); /* Clear trig irq */ intr_mask = REG_RD(timer, regi_timer, rw_intr_mask); intr_mask.trig = 0; REG_WR(timer, regi_timer, rw_intr_mask, intr_mask); /* Set timer values */ /* r_time is 100MHz (10 ns resolution) */ trig = r_time + delay_us*(1000/10); timer_div_settings[fast_timers_started % NUM_TIMER_STATS] = trig; timer_delay_settings[fast_timers_started % NUM_TIMER_STATS] = delay_us; /* Ack interrupt */ ack_intr.trig = 1; REG_WR(timer, regi_timer, rw_ack_intr, ack_intr); /* Start timer */ REG_WR(timer, regi_timer, rw_trig, trig); trig_cfg.tmr = regk_timer_time; REG_WR(timer, regi_timer, rw_trig_cfg, trig_cfg); /* Check if we have already passed the trig time */ r_time = REG_RD(timer, regi_timer, r_time); if (r_time < trig) { /* No, Enable trig irq */ intr_mask = REG_RD(timer, regi_timer, rw_intr_mask); intr_mask.trig = 1; REG_WR(timer, regi_timer, rw_intr_mask, intr_mask); fast_timers_started++; fast_timer_running = 1; } else { /* We have passed the time, disable trig point, ack intr */ trig_cfg.tmr = regk_timer_off; REG_WR(timer, regi_timer, rw_trig_cfg, trig_cfg); REG_WR(timer, regi_timer, rw_ack_intr, ack_intr); /* call the int routine directly */ timer_trig_handler(); } }
static irqreturn_t timer_trig_interrupt(int irq, void *dev_id) { reg_timer_r_masked_intr masked_intr; /* Check if the timer interrupt is for us (a trig int) */ masked_intr = REG_RD(timer, regi_timer0, r_masked_intr); if (!masked_intr.trig) return IRQ_NONE; timer_trig_handler(NULL); return IRQ_HANDLED; }