00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
#include <rtai.h>
00024
#include <rtai_trace.h>
00025
#include <asm/arch/ep93xx_tsc.h>
00026
00027
00028
00029
00030
00031
00032
00033
int
00034 rt_request_timer(rt_timer_irq_handler_t handler,
unsigned int tick,
int i386_legacy_dummy)
00035 {
00036
unsigned long flags;
00037
int is_oneshot = (tick == 0);
00038
00039
TRACE_RTAI_TIMER(TRACE_RTAI_EV_TIMER_REQUEST,
handler, tick);
00040
00041
00042
if (is_oneshot)
00043 tick = LATCH;
00044
00045
flags =
rtai_critical_enter(NULL);
00046
00047
00048 outl(0, TIMER1CONTROL);
00049 outl(tick - 1, TIMER1LOAD);
00050
00051
00052
rt_times.tick_time = ({
00053 ep93xx_tsc_t t0;
00054
unsigned long target_offset;
00055
unsigned long t;
00056
00057
00058
do {
00059 t0.ll = ep93xx_rdtsc();
00060
unsigned long long const realtime_jiffies = (
long long)(t0.ll * HZ) / (
long)
RTAI_TSC_FREQ;
00061
unsigned long const current_offset = t0.ll - (realtime_jiffies *
RTAI_TSC_FREQ) / HZ;
00062 target_offset = ((
RTAI_TSC_FREQ + HZ/2) / HZ) - current_offset;
00063 }
while (target_offset < 10);
00064
00065
00066
do {
00067 t = inl(TIMER4VALUELOW);
00068 }
while ((t - t0.u.low) < target_offset);
00069
00070
00071 outl((is_oneshot) ? 0x88 : 0xc8, TIMER1CONTROL);
00072
00073
00074
if (t < t0.u.low)
00075 ++t0.u.high;
00076 t0.u.low = t;
00077
00078 t0.ll;
00079 });
00080
00081
00082 outl(1, TIMER1CLEAR);
00083
00084
00085
if (is_oneshot) {
00086
00087
rt_times.linux_time =
rtai_llimd(ep93xx_jiffies_done * LATCH,
RTAI_TSC_FREQ,
RTAI_TIMER_FREQ);
00088
rt_times.linux_tick =
rtai_imuldiv(LATCH,
RTAI_TSC_FREQ,
RTAI_TIMER_FREQ);
00089
rt_times.periodic_tick =
rt_times.linux_tick;
00090 }
else {
00091
00092
rt_times.tick_time =
rtai_llimd(
rt_times.tick_time,
RTAI_TIMER_FREQ,
RTAI_TSC_FREQ);
00093
rt_times.linux_time = ep93xx_jiffies_done * LATCH;
00094
rt_times.linux_tick = LATCH;
00095
rt_times.periodic_tick = tick;
00096 }
00097
rt_times.intr_time =
rt_times.tick_time +
rt_times.periodic_tick;
00098
00099
rt_release_irq(
RTAI_TIMER_IRQ);
00100
if (
rt_request_irq(
RTAI_TIMER_IRQ, (rt_irq_handler_t)
handler, NULL, 0) < 0) {
00101
rtai_critical_exit(
flags);
00102
return -EINVAL;
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112
rtai_critical_exit(
flags);
00113
return 0;
00114 }
00115
00116
00117
00118
00119
00120
void
00121 rt_free_timer(
void)
00122 {
00123
unsigned long flags;
00124
00125
TRACE_RTAI_TIMER(TRACE_RTAI_EV_TIMER_FREE, 0, 0);
00126
00127
flags =
rtai_critical_enter(NULL);
00128
00129
00130
00131
00132
00133 outl(0, TIMER1CONTROL);
00134
00135 outl(LATCH - 1, TIMER1LOAD);
00136
00137 outl(0xc8, TIMER1CONTROL);
00138
00139 outl(1, TIMER1CLEAR);
00140
00141
rt_release_irq(
RTAI_TIMER_IRQ);
00142
00143
rtai_critical_exit(
flags);
00144 }