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 Tue Feb 2 17:46:04 2010 for RTAI API by  doxygen 1.4.7