static ssize_t kona_timer_module_cfg(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) { char name[255]; unsigned int rate; if (sscanf(buf, "%s %d", name, &rate) == 2) { pr_info("timer name:%s rate %d\n", name, rate); /* * Assuming that kona_timer_modules_init has happend already * This is safe because this function is called during * system timer init itself */ if (kona_timer_module_set_rate(name, rate) < 0) { pr_err("kona_timer_module_cfg: Unable to set rate\n"); return n; } pr_info("kona_timer_module_cfg: Configured the module with " "rate %d\n", rate); return n; } pr_info("\nusage: echo [timer_name(aon-timer/slave-timer)]" "[rate 32000 (32KHz), 1000000 (1MHz), 19500000 (19.5MHz)] > /sys/bcm/timer_module_cfg\n"); return -EINVAL; }
static void __init timers_init(struct gp_timer_setup *gpt_setup) { struct timer_ch_cfg evt_tm_cfg; if (kona_timer_modules_init() < 0) { pr_err ("timers_init: Unable to initialize kona timer modules \r\n"); return; } if (kona_timer_module_set_rate(gpt_setup->name, gpt_setup->rate) < 0) { pr_err("timers_init: Unable to set the clock rate to %d \r\n", gpt_setup->rate); return; } /* Initialize Event timer */ gpt_evt = kona_timer_request(gpt_setup->name, gpt_setup->ch_num); if (gpt_evt == NULL) { pr_err("timers_init: Unable to get GPT timer for event\r\n"); return; } pr_info("timers_init: === SYSTEM TIMER NAME: %s CHANNEL NUMBER %d \ RATE %d \r\n", gpt_setup->name, gpt_setup->ch_num, gpt_setup->rate); evt_tm_cfg.mode = MODE_ONESHOT; evt_tm_cfg.arg = &clockevent_gptimer; evt_tm_cfg.cb = gptimer_interrupt_cb; kona_timer_config(gpt_evt, &evt_tm_cfg); gptimer_set_next_event((CLOCK_TICK_RATE / HZ), NULL); /* * IMPORTANT * Note that we don't want to waste a channel for clock source. In Kona *timer module by default there is a counter that keeps counting *irrespective of the channels. So instead of implementing a periodic *timer using a channel (which in the HW is not peridoic) we can *simply read the counters of the timer that is used for event and *send it for source. The only catch is that this timer should not be *stopped by PM or any other sub-systems. */ gpt_src = gpt_evt; return; }