Exemplo n.º 1
0
/*
 * Setup the local clock events for a CPU.
 */
int __cpuinit local_timer_setup(struct clock_event_device *evt)
{
	unsigned int cpu = smp_processor_id();
	struct kona_td kona_td;
	struct timer_ch_cfg config;

	/* allocate an AON timer channel as local tick timer
	 */
	kona_td = (struct kona_td)__get_cpu_var(percpu_kona_td);

	if (!kona_td.allocated) {
		kona_td.kona_timer =
		    kona_timer_request(TICK_TIMER_NAME,
				       TICK_TIMER_OFFSET + cpu);
		if (kona_td.kona_timer) {
			kona_td.allocated = true;
		} else {
			pr_err("%s: Failed to allocate %s channel %d as"
			       "CPU %d local tick device\n", __func__,
			       TICK_TIMER_NAME,
			       TICK_TIMER_OFFSET + cpu, cpu);
			return -ENXIO;
		}
	}

	/*
	 * In the future: The following codes should be one time configuration
	 */
	config.mode = MODE_ONESHOT;
	config.arg = evt;
	config.cb = kona_tick_interrupt_cb;
	kona_timer_config(kona_td.kona_timer, &config);

	irq_set_affinity(kona_td.kona_timer->irq, cpumask_of(cpu));

	evt->name = "local_timer";
	evt->cpumask = cpumask_of(cpu);
	evt->irq = kona_td.kona_timer->irq;
	evt->set_next_event = kona_tick_set_next_event;
	evt->set_mode = kona_tick_set_mode;
	evt->features = CLOCK_EVT_FEAT_ONESHOT;
	evt->rating = 250;
	evt->shift = 32;
	evt->mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, evt->shift);
	evt->max_delta_ns = clockevent_delta2ns(MAX_KONA_COUNT_CLOCK, evt);
	/* There is MIN_KONA_DELTA_CLOCK clock cycles delay in HUB Timer by
	 * ASIC limitation. When min_delta_ns set N, real requested load value
	 * in hrtimer becomes N - 1. So add 1 to be MIN_DELTA_CLOCK
	 */
	evt->min_delta_ns = clockevent_delta2ns(MIN_KONA_DELTA_CLOCK + 1, evt);

	per_cpu(percpu_kona_td, cpu) = kona_td;

	clockevents_register_device(evt);

	return 0;
}
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;
}
Exemplo n.º 3
0
static ssize_t
kona_timer_start_test(struct device *dev, struct device_attribute *attr,
	  const char *buf, size_t n)
{
	unsigned int ch_num, mode, count;
	char name[255];

	if (sscanf(buf, "%s %d %d %d", name, &ch_num, &mode, &count) == 4) {
		pr_info("channel_num:%d mode(0-periodic 1-oneshot):%d "
			"count:%d\n", ch_num, mode, count);

		if (kt == NULL)
			kt = kona_timer_request(name, ch_num);

		if (kt == NULL) {
			pr_err("kona_timer_request returned error\n");
			goto out;
		}

		cfg.mode = mode;
		cfg.arg  = kt;
		cfg.cb	 = timer_callback;
		cfg.reload = count;

		if (kona_timer_config(kt, &cfg) < 0) {
			pr_err("kona_timer_config returned error\n");
			goto out;
		}

		if (kona_timer_set_match_start(kt, count) < 0) {
			pr_err("kona_timer_set_match_start returned error\n");
			goto out;
		}
		pr_info("Timer test started\n");
out:
		return n;
	}

	pr_info("\nusage: echo [name (aon-timer/slave-timer)] "
		"[channel num (0-3)] [mode(0-periodic"
		"1-oneshot)] [count value] > /sys/bcm/timer_start_test\n");
	return -EINVAL;
}
Exemplo n.º 4
0
static int kona_timer_unit_test_program(struct kona_timer *lkt,
					 enum timer_mode mode,
					 unsigned long count)
{
	struct timer_ch_cfg lcfg;

	lcfg.mode = mode;
	lcfg.arg  = lkt;
	lcfg.cb = timer_callback;

	if (kona_timer_config(lkt, &lcfg) < 0) {
		pr_err("kona_timer_config returned error.\n");
		goto error;
	}

	if (kona_timer_set_match_start(lkt, count) < 0) {
		pr_err("kona_timer_set_match_start returned error.\n");
		goto error;
	}

	return 0;
error:
	return -1;
}