Esempio n. 1
0
int __init init_module(void)
{
	init_timer(&timer);
	timer.function = timer_fun;
	mod_timer(&timer, jiffies + ECHO_PERIOD*HZ);
	xnintr_init(&intr, 0, isr, NULL, 0);
	xnintr_attach(&intr, &intr);
	return 0;
}
Esempio n. 2
0
int rt_intr_create(RT_INTR *intr,
		   const char *name,
		   unsigned irq, rt_isr_t isr, rt_iack_t iack, int mode)
{
	int err;
	spl_t s;

	if (xnpod_asynch_p())
		return -EPERM;

	if (name)
		xnobject_copy_name(intr->name, name);
	else
		/* Kernel-side "anonymous" objects (name == NULL) get unique names.
		 * Nevertheless, they will not be exported via the registry. */
		xnobject_create_name(intr->name, sizeof(intr->name), isr);

	xnintr_init(&intr->intr_base, intr->name, irq, isr, iack, mode);
#ifdef CONFIG_XENO_OPT_PERVASIVE
	xnsynch_init(&intr->synch_base, XNSYNCH_PRIO, NULL);
	intr->pending = 0;
	intr->cpid = 0;
	intr->mode = 0;
#endif /* CONFIG_XENO_OPT_PERVASIVE */
	intr->magic = XENO_INTR_MAGIC;
	intr->handle = 0;	/* i.e. (still) unregistered interrupt. */
	inith(&intr->rlink);
	intr->rqueue = &xeno_get_rholder()->intrq;
	xnlock_get_irqsave(&nklock, s);
	appendq(intr->rqueue, &intr->rlink);
	xnlock_put_irqrestore(&nklock, s);

	err = xnintr_attach(&intr->intr_base, intr);

	/*
	 * <!> Since xnregister_enter() may reschedule, only register
	 * complete objects, so that the registry cannot return
	 * handles to half-baked objects...
	 */
	if (!err && name)
		err = xnregistry_enter(intr->name, intr, &intr->handle,
				       &__intr_pnode);
	if (err)
		rt_intr_delete(intr);

	return err;
}
Esempio n. 3
0
int xntimer_grab_hardware(void)
{
	struct xnsched *sched;
	int ret, cpu, _cpu;
	spl_t s;

#ifdef CONFIG_XENO_OPT_STATS
	/*
	 * Only for statistical purpose, the timer interrupt is
	 * attached by xntimer_grab_hardware().
	 */
	xnintr_init(&nktimer, "[timer]",
		    per_cpu(ipipe_percpu.hrtimer_irq, 0), NULL, NULL, 0);
#endif /* CONFIG_XENO_OPT_STATS */

	nkclock.wallclock_offset =
		xnclock_get_host_time() - xnclock_read_monotonic(&nkclock);

	ret = xntimer_setup_ipi();
	if (ret)
		return ret;

	for_each_realtime_cpu(cpu) {
		ret = grab_hardware_timer(cpu);
		if (ret < 0)
			goto fail;

		xnlock_get_irqsave(&nklock, s);

		/*
		 * If the current tick device for the target CPU is
		 * periodic, we won't be called back for host tick
		 * emulation. Therefore, we need to start a periodic
		 * nucleus timer which will emulate the ticking for
		 * that CPU, since we are going to hijack the hw clock
		 * chip for managing our own system timer.
		 *
		 * CAUTION:
		 *
		 * - nucleus timers may be started only _after_ the hw
		 * timer has been set up for the target CPU through a
		 * call to xntimer_grab_hardware().
		 *
		 * - we don't compensate for the elapsed portion of
		 * the current host tick, since we cannot get this
		 * information easily for all CPUs except the current
		 * one, and also because of the declining relevance of
		 * the jiffies clocksource anyway.
		 *
		 * - we must not hold the nklock across calls to
		 * xntimer_grab_hardware().
		 */

		sched = xnsched_struct(cpu);
		/* Set up timer with host tick period if valid. */
		if (ret > 1)
			xntimer_start(&sched->htimer, ret, ret, XN_RELATIVE);
		else if (ret == 1)
			xntimer_start(&sched->htimer, 0, 0, XN_RELATIVE);

#ifdef CONFIG_XENO_OPT_WATCHDOG
		xntimer_start(&sched->wdtimer, 1000000000UL, 1000000000UL, XN_RELATIVE);
		xnsched_reset_watchdog(sched);
#endif
		xnlock_put_irqrestore(&nklock, s);
	}

	return 0;
fail:
	for_each_realtime_cpu(_cpu) {
		if (_cpu == cpu)
			break;
		xnlock_get_irqsave(&nklock, s);
		sched = xnsched_struct(cpu);
		xntimer_stop(&sched->htimer);
#ifdef CONFIG_XENO_OPT_WATCHDOG
		xntimer_stop(&sched->wdtimer);
#endif
		xnlock_put_irqrestore(&nklock, s);
		ipipe_timer_stop(_cpu);
	}

	xntimer_release_ipi();

	return ret;
}