예제 #1
0
파일: hal.c 프로젝트: mhaberler/xenomai-2.6
int rthal_timer_request(void (*handler)(void), int cpu)
{
	int ret;

#ifdef CONFIG_IPIPE_CORE
	ret = rthal_tickdev_request(handler, NULL, NULL, cpu, NULL);
	if (ret < 0)
		return ret;
#endif /* CONFIG_IPIPE_CORE */

	/*
	 * The rest of the initialization should only be performed
	 * once by a single CPU.
	 */
	if (cpu_timers_requested++ > 0)
		return 0;

	rthal_ktimer_saved_mode = KTIMER_MODE_PERIODIC;

#ifndef CONFIG_IPIPE_CORE
	ret = rthal_irq_request(RTHAL_TIMER_IRQ,
				(rthal_irq_handler_t) handler,
				NULL, NULL);
	if (ret)
		return ret;
#endif /* !CONFIG_IPIPE_CORE */

	rthal_timer_set_oneshot(1);

	return 1000000000UL / HZ;
}
예제 #2
0
void rthal_timer_release(int cpu)
{
	ipipe_release_tickdev(cpu);

	if (--cpu_timers_requested > 0)
		return;

#ifdef CONFIG_SMP
	rthal_irq_release(RTHAL_TIMER_IPI);
#endif /* CONFIG_SMP */
	rthal_irq_release(RTHAL_TIMER_IRQ);

	if (rthal_ktimer_saved_mode == KTIMER_MODE_PERIODIC)
		rthal_timer_set_periodic();
	else if (rthal_ktimer_saved_mode == KTIMER_MODE_ONESHOT)
		rthal_timer_set_oneshot(0);
}
예제 #3
0
int rthal_timer_request(void (*tick_handler)(void),
			void (*mode_emul)(enum clock_event_mode mode,
					  struct clock_event_device *cdev),
			int (*tick_emul)(unsigned long delay,
					 struct clock_event_device *cdev),
			int cpu)
{
	unsigned long dummy, *tmfreq = &dummy;
	int tickval, err, res;

	if (rthal_timerfreq_arg == 0)
		tmfreq = &rthal_tunables.timer_freq;

	res = ipipe_request_tickdev("decrementer", mode_emul, tick_emul, cpu,
				    tmfreq);
	switch (res) {
	case CLOCK_EVT_MODE_PERIODIC:
		/* oneshot tick emulation callback won't be used, ask
		 * the caller to start an internal timer for emulating
		 * a periodic tick. */
		tickval = 1000000000UL / HZ;
		break;

	case CLOCK_EVT_MODE_ONESHOT:
		/* oneshot tick emulation */
		tickval = 1;
		break;

	case CLOCK_EVT_MODE_UNUSED:
		/* we don't need to emulate the tick at all. */
		tickval = 0;
		break;

	case CLOCK_EVT_MODE_SHUTDOWN:
		return -ENODEV;

	default:
		return res;
	}
	rthal_ktimer_saved_mode = res;

	/*
	 * The rest of the initialization should only be performed
	 * once by a single CPU.
	 */
	if (cpu_timers_requested++ > 0)
		goto out;

	err = rthal_irq_request(RTHAL_TIMER_IRQ,
				(rthal_irq_handler_t) tick_handler,
				NULL, NULL);
	if (err)
		return err;

#ifdef CONFIG_SMP
	err = rthal_irq_request(RTHAL_TIMER_IPI,
				(rthal_irq_handler_t) tick_handler,
				NULL, NULL);
	if (err)
		return err;
#endif

	rthal_timer_set_oneshot(1);

out:
	return tickval;
}
예제 #4
0
int rthal_timer_request(
	void (*tick_handler)(void),
#ifdef CONFIG_GENERIC_CLOCKEVENTS
	void (*mode_emul)(enum clock_event_mode mode,
			  struct clock_event_device *cdev),
	int (*tick_emul)(unsigned long delay,
			 struct clock_event_device *cdev),
#endif
	int cpu)
{
	int tickval, err;

#ifdef CONFIG_GENERIC_CLOCKEVENTS
	unsigned long tmfreq;

#ifdef __IPIPE_FEATURE_REQUEST_TICKDEV
	int res = ipipe_request_tickdev("pit", mode_emul, tick_emul, cpu,
					&tmfreq);
#else
	int res = ipipe_request_tickdev("pit",
					(compat_emumode_t)mode_emul,
					(compat_emutick_t)tick_emul,
					cpu);
	tmfreq = RTHAL_COMPAT_TIMERFREQ;
#endif

	switch (res) {
	case CLOCK_EVT_MODE_PERIODIC:
		/* oneshot tick emulation callback won't be used, ask
		 * the caller to start an internal timer for emulating
		 * a periodic tick. */
		tickval = 1000000000UL / HZ;
		break;

	case CLOCK_EVT_MODE_ONESHOT:
		/* oneshot tick emulation */
		tickval = 1;
		break;

	case CLOCK_EVT_MODE_UNUSED:
		/* we don't need to emulate the tick at all. */
		tickval = 0;
		break;

	case CLOCK_EVT_MODE_SHUTDOWN:
		return -ENOSYS;

	default:
		return res;
	}
	rthal_ktimer_saved_mode = res;

	if (rthal_timerfreq_arg == 0)
		rthal_tunables.timer_freq = tmfreq;
#else /* !CONFIG_GENERIC_CLOCKEVENTS */
	/*
	 * Out caller has to to emulate the periodic host tick by its
	 * own means once we will have grabbed the PIT.
	 */
	tickval = 1000000000UL / HZ;
	rthal_ktimer_saved_mode = KTIMER_MODE_PERIODIC;

	if (rthal_timerfreq_arg == 0)
		rthal_tunables.timer_freq = CLOCK_TICK_RATE;
#endif /* !CONFIG_GENERIC_CLOCKEVENTS */

	/*
	 * No APIC means that we can't be running in SMP mode, so this
	 * routine will be called only once, for CPU #0.
	 */

	rthal_timer_set_oneshot();

	err = rthal_irq_request(RTHAL_TIMER_IRQ,
				(rthal_irq_handler_t)tick_handler, NULL, NULL);

	return err ?: tickval;
}