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; }
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); }
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; }
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; }