00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <linux/sched.h>
00029 #include <linux/interrupt.h>
00030 #include <linux/init.h>
00031 #include <asm/mach/irq.h>
00032 #include <asm/system.h>
00033 #include <rtai.h>
00034 #define do_leds()
00035 #define do_set_rtc()
00036 #define do_profile(x)
00037 extern struct irqaction timer_irq;
00038 extern unsigned long (*gettimeoffset)(void);
00039 extern int (*set_rtc)(void);
00040 #include <asm-arm/arch-pxa/timex.h>
00041 #include <asm-arm/arch-pxa/rtai_timer.h>
00042 #include <rtai_trace.h>
00043
00044 volatile union rtai_tsc rtai_tsc;
00045 EXPORT_SYMBOL(rtai_tsc);
00046 extern volatile u32 soft_timer_match;
00047 extern void timer_tick(struct pt_regs *);
00048 static int (*saved_adeos_timer_handler)(int irq, void *dev_id, struct pt_regs *regs);
00049
00050
00051 void rtai_pxa_GPIO_2_80_demux( int irq, void *dev_id, struct pt_regs *regs )
00052 {
00053
00054 }
00055
00056
00057 volatile union rtai_tsc lx_timer;
00058
00059 unsigned long split_timer (void) {
00060 lx_timer.tsc = rt_times.linux_time;
00061 return lx_timer.hltsc[0];
00062 }
00063
00064 int soft_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
00065 {
00066 long flags;
00067
00068 rdtsc();
00069
00070 local_irq_save(flags);
00071
00072 timer_tick(regs);
00073 soft_timer_match = split_timer();
00074
00075 local_irq_restore(flags);
00076
00077 return IRQ_HANDLED;
00078 }
00079
00080 int rt_request_timer(rt_timer_irq_handler_t handler, unsigned tick, int use_apic)
00081 {
00082 RTIME t;
00083 unsigned long flags;
00084
00085 TRACE_RTAI_TIMER(TRACE_RTAI_EV_TIMER_REQUEST, handler, tick);
00086 flags = rtai_critical_enter(NULL);
00087
00088
00089
00090
00091 rtai_tsc.tsc = 0;
00092
00093
00094 do {
00095
00096 } while ( (signed long)(OSMR0 - OSCR) >= 0 );
00097 OSSR = OSSR_M0;
00098
00099
00100 rt_times.linux_tick = LATCH;
00101 rt_times.periodic_tick = tick > 0 && tick < (RTIME)rt_times.linux_tick ? tick : rt_times.linux_tick;
00102 rt_times.tick_time = t = rdtsc();
00103 rt_times.intr_time = t + (RTIME)rt_times.periodic_tick;
00104 rt_times.linux_time = t + (RTIME)rt_times.linux_tick;
00105
00106
00107
00108
00109
00110 rt_set_timer_match_reg(rt_times.periodic_tick);
00111
00112 saved_adeos_timer_handler = xchg(&irq_desc[TIMER_8254_IRQ].action->handler,(void *)soft_timer_interrupt);
00113
00114 rt_free_global_irq(TIMER_8254_IRQ);
00115
00116 rt_request_global_irq(TIMER_8254_IRQ, handler);
00117
00118
00119
00120
00121 rt_pend_linux_irq(TIMER_8254_IRQ);
00122 rtai_critical_exit(flags);
00123
00124 return 0;
00125 }
00126
00127 void rt_free_timer(void)
00128 {
00129 unsigned long flags;
00130
00131 TRACE_RTAI_TIMER(TRACE_RTAI_EV_TIMER_FREE, 0, 0);
00132
00133 flags = rtai_critical_enter(NULL);
00134
00135 rt_free_global_irq(TIMER_8254_IRQ);
00136 irq_desc[TIMER_8254_IRQ].action->handler =(void*)saved_adeos_timer_handler ;
00137
00138 rtai_critical_exit(flags);
00139 }