/* Setup watchdog timer. */ void emxx_wdt_setup(void) { unsigned int regval; unsigned int tm_delay; struct timer_reg_t *reg = tm_reg[TIMER_WDT].reg; tm_delay = TIMER_DELAY(TW_CLOCK_TICK_RATE) * 2; spin_lock(&wdt_spinlock); writel(readl(SMU_WDT_INT_RESET) | 0x01003003, SMU_WDT_INT_RESET); emxx_open_clockgate(EMXX_CLK_TIM_P); emxx_open_clockgate(tm_reg[TIMER_WDT].clkdev); emxx_unreset_device(tm_reg[TIMER_WDT].rstdev); /* stop timer for sure. */ reg->tm_op = TSTOP; /* set counter */ regval = get_tw_count_value(TIMER_WDT, tm_param[TIMER_WDT].usecs); udelay(tm_delay); reg->tm_set = regval; spin_unlock(&wdt_spinlock); }
/* * WatchDog Timer Function */ int emxx_wdt_set_timeout(unsigned int usecs) { int ret = 0, val_tm_op, regval; unsigned int tm_delay; struct timer_reg_t *reg = tm_reg[TIMER_WDT].reg; if ((usecs < TW_MIN_USECS) || (TW_MAX_USECS < usecs)) return -EINVAL; tm_delay = TIMER_DELAY(TW_CLOCK_TICK_RATE) * 2; spin_lock(&wdt_spinlock); /* get tm_op */ val_tm_op = reg->tm_op; /* timer stop */ reg->tm_op = TSTOP; /* set counter */ regval = get_tw_count_value(TIMER_WDT, usecs); udelay(tm_delay); reg->tm_set = regval; /* timer start (restore tm_op) */ reg->tm_op = val_tm_op; spin_unlock(&wdt_spinlock); return ret; }
int emxx_timer_stop(unsigned int timer) { int ret = 0; unsigned int tm_delay; unsigned long flags; struct timer_reg_t *reg; ret = check_validity_channel(timer); if (ret != 0) return ret; /* delay value set */ tm_delay = TIMER_DELAY(TIMER_CLOCK_TICK_RATE_PLL3); reg = tm_reg[TIMER_TG0 + timer].reg; spin_lock_irqsave(&timer_spinlock, flags); /* Timer stop */ reg->tm_op = TSTOP; udelay(tm_delay); emxx_close_clockgate(tm_reg[TIMER_TG0 + timer].clkdev); tg_tm_op[timer] = 0; spin_unlock_irqrestore(&timer_spinlock, flags); return 0; }
/* * take a local timer down */ void local_timer_stop(void) { struct timer_reg_t *reg = tm_reg[TIMER_SYSTEM2].reg; reg->tm_op = TSTOP; udelay(TIMER_DELAY(TIMER_CLOCK_TICK_RATE_PLL3)); emxx_close_clockgate(tm_reg[TIMER_SYSTEM2].clkdev); }
/* Stop watchdog timer counting. */ void emxx_wdt_disable(void) { unsigned int tm_delay = TIMER_DELAY(TW_CLOCK_TICK_RATE); struct timer_reg_t *reg = tm_reg[TIMER_WDT].reg; spin_lock(&wdt_spinlock); reg->tm_op = TSTOP; udelay(tm_delay); spin_unlock(&wdt_spinlock); }
/* Clear watchdog timer. */ void emxx_wdt_ping(void) { unsigned int tm_delay = TIMER_DELAY(TW_CLOCK_TICK_RATE); struct timer_reg_t *reg = tm_reg[TIMER_WDT].reg; spin_lock(&wdt_spinlock); reg->tm_clr = TCR_CLR; udelay(tm_delay); spin_unlock(&wdt_spinlock); }
static int protothread2(struct pt *pt) { /* A protothread function must begin with PT_BEGIN() which takes a pointer to a struct pt. */ PT_BEGIN(pt); /* We loop forever here. */ while(1) { PORTB |= _BV(PB2); TIMER_DELAY(pt, timer2, 60); PORTB &= ~_BV(PB2); TIMER_DELAY(pt, timer2, 60); /* And we loop. */ } /* All protothread functions must end with PT_END() which takes a pointer to a struct pt. */ PT_END(pt); }
int emxx_timer_set_period(unsigned int timer, unsigned int usecs) { int ret = 0, regval = 0; unsigned long flags; unsigned int tm_delay; struct timer_reg_t *reg; ret = check_validity_channel(timer); if (ret != 0) return ret; if ((usecs < TIMER_MIN_USECS) || (TIMER_MAX_USECS < usecs)) return -EINVAL; /* 4clk x2 wait value */ tm_delay = TIMER_DELAY(TIMER_CLOCK_TICK_RATE_PLL3) * 2; reg = tm_reg[TIMER_TG0 + timer].reg; spin_lock_irqsave(&timer_spinlock, flags); if (reg->tm_op & TSTART) { spin_unlock_irqrestore(&timer_spinlock, flags); return -EBUSY; } emxx_open_clockgate(tm_reg[TIMER_TG0 + timer].clkdev); udelay(tm_delay); tm_param[TIMER_TG0 + timer].usecs = usecs; /* set counter */ regval = get_count_value(timer, usecs); reg->tm_set = regval; emxx_close_clockgate(tm_reg[TIMER_TG0 + timer].clkdev); spin_unlock_irqrestore(&timer_spinlock, flags); return 0; }
void timer_set_clock(unsigned int mode) { int i; unsigned int count; unsigned int tm_delay; struct timer_reg_t *reg; static unsigned int timer_pmu_flag; /* delay value set */ tm_delay = TIMER_DELAY(TIMER_CLOCK_TICK_RATE_32K); switch (mode) { case TIMER_SUSPEND: /* close clockgate */ emxx_close_clockgate(tm_reg[TIMER_SYSTEM].clkdev); emxx_close_clockgate(tm_reg[TIMER_WDT].clkdev); emxx_close_clockgate(tm_reg[TIMER_DSP].clkdev); timer_pmu_flag = emxx_get_clockgate(tm_reg[TIMER_PMU].clkdev); if (timer_pmu_flag) emxx_close_clockgate(tm_reg[TIMER_PMU].clkdev); for (i = 0; i < TIMER_TG_MAX_NUM; i++) { if (tg_tm_op[i] == 1) emxx_close_clockgate( tm_reg[TIMER_TG0 + i].clkdev); } break; case TIMER_RESUME: emxx_open_clockgate(tm_reg[TIMER_SYSTEM].clkdev); emxx_open_clockgate(tm_reg[TIMER_WDT].clkdev); emxx_open_clockgate(tm_reg[TIMER_DSP].clkdev); if (timer_pmu_flag) emxx_open_clockgate(tm_reg[TIMER_PMU].clkdev); for (i = 0; i < TIMER_TG_MAX_NUM; i++) { if (tg_tm_op[i] == 1) emxx_open_clockgate( tm_reg[TIMER_TG0 + i].clkdev); } break; case TIMER_INIT: emxx_open_clockgate(EMXX_CLK_TIM_P); emxx_open_clockgate(tm_reg[TIMER_SYSTEM].clkdev); emxx_open_clockgate(tm_reg[TIMER_DSP].clkdev); emxx_open_clockgate(tm_reg[TIMER_PMU].clkdev); emxx_unreset_device(tm_reg[TIMER_SYSTEM].rstdev); emxx_unreset_device(tm_reg[TIMER_DSP].rstdev); emxx_unreset_device(tm_reg[TIMER_PMU].rstdev); for (i = 0; i < TIMER_TG_MAX_NUM; i++) emxx_unreset_device(tm_reg[TIMER_TG0 + i].rstdev); reg = tm_reg[TIMER_SYSTEM].reg; reg->tm_op = TSTOP; reg->tm_clr = TCR_CLR; reg = tm_reg[TIMER_WDT].reg; reg->tm_op = TSTOP; reg->tm_clr = TCR_CLR; reg = tm_reg[TIMER_DSP].reg; reg->tm_op = TSTOP; reg->tm_clr = TCR_CLR; reg->tm_set = TIMER_INTERVAL_DSP; reg = tm_reg[TIMER_PMU].reg; reg->tm_op = TSTOP; reg->tm_clr = TCR_CLR; emxx_close_clockgate(tm_reg[TIMER_PMU].clkdev); /* select TIN clock */ writel(TINTIN_SEL_PLL3 | TWNTIN_SEL_32K, SMU_TWI0TIN_SEL); writel(TINTIN_SEL_PLL3 | TWNTIN_SEL_PLL3, SMU_TWI1TIN_SEL); writel(TINTIN_SEL_32K | TWNTIN_SEL_PLL3, SMU_TWI2TIN_SEL); writel(TINTIN_SEL_32K | TWNTIN_SEL_PLL3, SMU_TWI3TIN_SEL); writel(TINTIN_SEL_32K, SMU_TW4TIN_SEL); writel(TGNTIN_SEL_PLL3, SMU_TGNTIN_SEL); /* DIVTIMTIN Register set */ writel(SMU_PLLSEL_PLL3 | SMU_DIV(40), SMU_TIMCLKDIV); for (i = 0; i < TIMER_TG_MAX_NUM; i++) { count = get_count_value(i, tm_param[TIMER_TG0 + i].usecs); reg = tm_reg[TIMER_TG0 + i].reg; reg->tm_set = count; } break; default: printk(KERN_INFO "%s(): set clock error mode = %d.\n", __func__, mode); break; } }