base/arch/arm/hal/mach-pxa/pxa-timer.c

Go to the documentation of this file.
00001 /* rtai/arch/arm/mach-pxa/pxa-timer.c 00002 COPYRIGHT (C) 2002 Guennadi Liakhovetski, DSA GmbH (gl@dsa-ac.de) 00003 COPYRIGHT (C) 2002 Wolfgang Müller (wolfgang.mueller@dsa-ac.de) 00004 Copyright (c) 2001 Alex Züpke, SYSGO RTS GmbH (azu@sysgo.de) 00005 Copyright (c) 2005 Luca Pizzi, (lucapizzi@hotmail.com) 00006 Copyright (c) 2005 Stefano Gafforelli, (stefano.gafforelli@tiscali.it) 00007 00008 This program is free software; you can redistribute it and/or modify 00009 it under the terms of version 2 of the GNU General Public License as 00010 published by the Free Software Foundation. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program; if not, write to the Free Software 00019 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00020 */ 00021 /* 00022 -------------------------------------------------------------------------- 00023 Acknowledgements 00024 - Paolo Mantegazza (mantegazza@aero.polimi.it) 00025 creator of RTAI 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 /* No pending to linux! */ 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(); /* update tsc - make sure we don't miss a wrap */ 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 * sync w/jiffie, wait for a OS timer 0 match and clear the match bit 00090 */ 00091 rtai_tsc.tsc = 0; 00092 /* wait for a timer match 0 and clear the match bit */ 00093 00094 do { 00095 // t = rdtsc(); 00096 } while ( (signed long)(OSMR0 - OSCR) >= 0 ); 00097 OSSR = OSSR_M0; 00098 00099 /* set up rt_times structure */ 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 /* Trick the scheduler - set this our way. */ 00107 // tuned.setup_time_TIMER_CPUNIT = (int)(~(~0 >> 1)) + 1; /* smallest negative + 1 - for extra safety:-) */ 00108 00109 /* update Match-register */ 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 * pend linux timer irq to handle current jiffie 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 }

Generated on Thu Nov 20 11:49:47 2008 for RTAI API by doxygen 1.3.8