Re: [PATCH query] arm: i.MX/MX1 clock event source
On Wed, 2007-01-24 at 03:00 +0100, Pavel Pisa wrote: > stays NULL after clock event registration. Interrupts > runs, but my code doesnot call any function. The notification > chain and clock events list seems to be filled correctly. > I have added > > clockevent_imx.cpumask = cpumask_of_cpu(0); Correct. I probably should disable the check for UP. > to ensure that clock are not used for affinity > mask reasons. I have tried even exchange clock > event forcibly at the end of clockevent_imx initialization. > But it only resulted in asking timer to switch off > into unused mode. > > I have added next hack into IRQ > write_seqlock(_lock); > timer_tick(); > write_sequnlock(_lock); > which stays enabled until imx_set_mode() is called first time, > The system boots after this modification, but imx_set_mode() > is never called and there is no switch to high resolution mode. You should not set up the timer at all. The setup of the timer happens from the registration. We need to know, why the timer is not picked from the tick code in the first place and why set_mode() is not called. tglx - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH query] arm: i.MX/MX1 clock event source
On Wed, 2007-01-24 at 03:00 +0100, Pavel Pisa wrote: stays NULL after clock event registration. Interrupts runs, but my code doesnot call any function. The notification chain and clock events list seems to be filled correctly. I have added clockevent_imx.cpumask = cpumask_of_cpu(0); Correct. I probably should disable the check for UP. to ensure that clock are not used for affinity mask reasons. I have tried even exchange clock event forcibly at the end of clockevent_imx initialization. But it only resulted in asking timer to switch off into unused mode. I have added next hack into IRQ write_seqlock(xtime_lock); timer_tick(); write_sequnlock(xtime_lock); which stays enabled until imx_set_mode() is called first time, The system boots after this modification, but imx_set_mode() is never called and there is no switch to high resolution mode. You should not set up the timer at all. The setup of the timer happens from the registration. We need to know, why the timer is not picked from the tick code in the first place and why set_mode() is not called. tglx - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH query] arm: i.MX/MX1 clock event source
On Tuesday 23 January 2007 03:52, Pavel Pisa wrote: > > i've added your patch to -rt, but note that there's a new, slightly > > incompatible clockevents code in -rt now so you'll need to do some more > > (hopefully trivial) fixups for this to build and work. > > > > Ingo > > Hello Ingo, > > Unfortunately, even with these corrections boot stuck at > > Memory: 18972KB available (2488K code, 358K data, 92K init) > > I have not time now to start JTAG debugging session, so I look at that > tomorrow or on Friday. > > It seems, that the interrupts are not coming from device. > > Best wishes > > Pavel > Hello Ingo, I have found some time and tried to debugg problem with help of JTAG debugger. But I have found, that IRQs are processed right. The plain rc5 runs flawlessly. The rt8 doesnot start. The problem is, that handler stays NULL after clock event registration. Interrupts runs, but my code doesnot call any function. The notification chain and clock events list seems to be filled correctly. I have added clockevent_imx.cpumask = cpumask_of_cpu(0); to ensure that clock are not used for affinity mask reasons. I have tried even exchange clock event forcibly at the end of clockevent_imx initialization. But it only resulted in asking timer to switch off into unused mode. I have added next hack into IRQ write_seqlock(_lock); timer_tick(); write_sequnlock(_lock); which stays enabled until imx_set_mode() is called first time, The system boots after this modification, but imx_set_mode() is never called and there is no switch to high resolution mode. CONFIG_ARM=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y ??? CONFIG_TICK_ONESHOT=y ??? CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_PREEMPT_RT=y CONFIG_PREEMPT=y CONFIG_PREEMPT_SOFTIRQS=y CONFIG_PREEMPT_HARDIRQS=y CONFIG_PREEMPT_BKL=y Could I preset some handler directly during timer initialization? Can I declare somehow, that I want to use that clock event device as source of tick from beginning? Should I try to rebuild with CONFIG_NO_HZ=n? I would like to keep up with changes, because I have tested RTs for ARM already over more "stable" releases and over many rc-s. And high resolution timers support has worked well over for me last three months (up to 2.6.20-rc4). So I want to learn what is required to be compatible with latest code. Thanks for any hints to the problem Pavel - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH query] arm: i.MX/MX1 clock event source
On Tuesday 23 January 2007 03:52, Pavel Pisa wrote: i've added your patch to -rt, but note that there's a new, slightly incompatible clockevents code in -rt now so you'll need to do some more (hopefully trivial) fixups for this to build and work. Ingo Hello Ingo, Unfortunately, even with these corrections boot stuck at Memory: 18972KB available (2488K code, 358K data, 92K init) I have not time now to start JTAG debugging session, so I look at that tomorrow or on Friday. It seems, that the interrupts are not coming from device. Best wishes Pavel Hello Ingo, I have found some time and tried to debugg problem with help of JTAG debugger. But I have found, that IRQs are processed right. The plain rc5 runs flawlessly. The rt8 doesnot start. The problem is, that handler stays NULL after clock event registration. Interrupts runs, but my code doesnot call any function. The notification chain and clock events list seems to be filled correctly. I have added clockevent_imx.cpumask = cpumask_of_cpu(0); to ensure that clock are not used for affinity mask reasons. I have tried even exchange clock event forcibly at the end of clockevent_imx initialization. But it only resulted in asking timer to switch off into unused mode. I have added next hack into IRQ write_seqlock(xtime_lock); timer_tick(); write_sequnlock(xtime_lock); which stays enabled until imx_set_mode() is called first time, The system boots after this modification, but imx_set_mode() is never called and there is no switch to high resolution mode. CONFIG_ARM=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y ??? CONFIG_TICK_ONESHOT=y ??? CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_PREEMPT_RT=y CONFIG_PREEMPT=y CONFIG_PREEMPT_SOFTIRQS=y CONFIG_PREEMPT_HARDIRQS=y CONFIG_PREEMPT_BKL=y Could I preset some handler directly during timer initialization? Can I declare somehow, that I want to use that clock event device as source of tick from beginning? Should I try to rebuild with CONFIG_NO_HZ=n? I would like to keep up with changes, because I have tested RTs for ARM already over more stable releases and over many rc-s. And high resolution timers support has worked well over for me last three months (up to 2.6.20-rc4). So I want to learn what is required to be compatible with latest code. Thanks for any hints to the problem Pavel - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH query] arm: i.MX/MX1 clock event source
On Monday 22 January 2007 20:59, Ingo Molnar wrote: > * Pavel Pisa <[EMAIL PROTECTED]> wrote: > > Hello Thomas, Sascha and Ingo > > > > please can you find some time to review next patch > > arm: i.MX/MX1 clock event source > > which has been sent to you and to the ALKML at 2007-01-13. > > > > http://thread.gmane.org/gmane.linux.ports.arm.kernel/29510/focus=29533 > > > > There seems to be some problems, because this patch has not been > > accepted to patch-2.6.20-rc5-rt7.patch, but GENERIC_CLOCKEVENTS are > > set already for i.MX and this results in a problems to run RT kernel > > on this architecture. > > i've added your patch to -rt, but note that there's a new, slightly > incompatible clockevents code in -rt now so you'll need to do some more > (hopefully trivial) fixups for this to build and work. > > Ingo Hello Ingo, thanks for reply. I am attaching updated version of the patch at the end of e-mail. There is problem with missing include in tick-sched.c CC kernel/time/tick-sched.o /usr/src/linux-2.6.20-rc5/kernel/time/tick-sched.c: In function `tick_nohz_handler': /usr/src/linux-2.6.20-rc5/kernel/time/tick-sched.c:330: warning: implicit declaration of function `get_irq_regs' /usr/src/linux-2.6.20-rc5/kernel/time/tick-sched.c:330: warning: initialization makes pointer from integer without a cast /usr/src/linux-2.6.20-rc5/kernel/time/tick-sched.c: In function `tick_sched_timer': /usr/src/linux-2.6.20-rc5/kernel/time/tick-sched.c:425: warning: initialization makes pointer from integer without a cast LD kernel/time/built-in.o --- linux-2.6.20-rc5.orig/kernel/time/tick-sched.c +++ linux-2.6.20-rc5/kernel/time/tick-sched.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "tick-internal.h" And CC arch/arm/kernel/process.o /usr/src/linux-2.6.20-rc5/arch/arm/kernel/process.c: In function `cpu_idle': /usr/src/linux-2.6.20-rc5/arch/arm/kernel/process.c:157: warning: implicit declaration of function `hrtimer_stop_sched_tick' /usr/src/linux-2.6.20-rc5/arch/arm/kernel/process.c:161: warning: implicit declaration of function `hrtimer_restart_sched_tick' --- linux-2.6.20-rc5.orig/arch/arm/kernel/process.c +++ linux-2.6.20-rc5/arch/arm/kernel/process.c @@ -154,11 +154,11 @@ void cpu_idle(void) if (!idle) idle = default_idle; leds_event(led_idle_start); - hrtimer_stop_sched_tick(); + tick_nohz_stop_sched_tick(); while (!need_resched() && !need_resched_delayed()) idle(); leds_event(led_idle_end); - hrtimer_restart_sched_tick(); + tick_nohz_restart_sched_tick(); local_irq_disable(); __preempt_enable_no_resched(); __schedule(); Unfortunately, even with these corrections boot stuck at Memory: 18972KB available (2488K code, 358K data, 92K init) I have not time now to start JTAG debugging session, so I look at that tomorrow or on Friday. It seems, that the interrupts are not coming from device. Best wishes Pavel == Subject: arm: i.MX/MX1 clock event source Support clock event source based on i.MX general purpose timer in free running timer mode. Signed-off-by: Pavel Pisa <[EMAIL PROTECTED]> arch/arm/mach-imx/time.c | 112 --- 1 file changed, 107 insertions(+), 5 deletions(-) Index: linux-2.6.20-rc5/arch/arm/mach-imx/time.c === --- linux-2.6.20-rc5.orig/arch/arm/mach-imx/time.c +++ linux-2.6.20-rc5/arch/arm/mach-imx/time.c @@ -15,6 +15,9 @@ #include #include #include +#ifdef CONFIG_GENERIC_CLOCKEVENTS +#include +#endif #include #include @@ -25,6 +28,11 @@ /* Use timer 1 as system timer */ #define TIMER_BASE IMX_TIM1_BASE +#ifdef CONFIG_GENERIC_CLOCKEVENTS +static struct clock_event_device clockevent_imx; +static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_PERIODIC; +#endif + static unsigned long evt_diff; /* @@ -33,6 +41,7 @@ static unsigned long evt_diff; static irqreturn_t imx_timer_interrupt(int irq, void *dev_id) { + unsigned long tcmp; uint32_t tstat; /* clear the interrupt */ @@ -42,13 +51,20 @@ imx_timer_interrupt(int irq, void *dev_i if (tstat & TSTAT_COMP) { do { +#ifdef CONFIG_GENERIC_CLOCKEVENTS + if (clockevent_imx.event_handler) + clockevent_imx.event_handler(_imx); + if (likely(clockevent_mode != CLOCK_EVT_MODE_PERIODIC)) + break; +#else write_seqlock(_lock); timer_tick(); write_sequnlock(_lock); - IMX_TCMP(TIMER_BASE) += evt_diff; +#endif +
Re: [PATCH query] arm: i.MX/MX1 clock event source
* Pavel Pisa <[EMAIL PROTECTED]> wrote: > Hello Thomas, Sascha and Ingo > > please can you find some time to review next patch > arm: i.MX/MX1 clock event source > which has been sent to you and to the ALKML at 2007-01-13. > > http://thread.gmane.org/gmane.linux.ports.arm.kernel/29510/focus=29533 > > There seems to be some problems, because this patch has not been > accepted to patch-2.6.20-rc5-rt7.patch, but GENERIC_CLOCKEVENTS are > set already for i.MX and this results in a problems to run RT kernel > on this architecture. i've added your patch to -rt, but note that there's a new, slightly incompatible clockevents code in -rt now so you'll need to do some more (hopefully trivial) fixups for this to build and work. Ingo - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH query] arm: i.MX/MX1 clock event source
* Pavel Pisa [EMAIL PROTECTED] wrote: Hello Thomas, Sascha and Ingo please can you find some time to review next patch arm: i.MX/MX1 clock event source which has been sent to you and to the ALKML at 2007-01-13. http://thread.gmane.org/gmane.linux.ports.arm.kernel/29510/focus=29533 There seems to be some problems, because this patch has not been accepted to patch-2.6.20-rc5-rt7.patch, but GENERIC_CLOCKEVENTS are set already for i.MX and this results in a problems to run RT kernel on this architecture. i've added your patch to -rt, but note that there's a new, slightly incompatible clockevents code in -rt now so you'll need to do some more (hopefully trivial) fixups for this to build and work. Ingo - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH query] arm: i.MX/MX1 clock event source
On Monday 22 January 2007 20:59, Ingo Molnar wrote: * Pavel Pisa [EMAIL PROTECTED] wrote: Hello Thomas, Sascha and Ingo please can you find some time to review next patch arm: i.MX/MX1 clock event source which has been sent to you and to the ALKML at 2007-01-13. http://thread.gmane.org/gmane.linux.ports.arm.kernel/29510/focus=29533 There seems to be some problems, because this patch has not been accepted to patch-2.6.20-rc5-rt7.patch, but GENERIC_CLOCKEVENTS are set already for i.MX and this results in a problems to run RT kernel on this architecture. i've added your patch to -rt, but note that there's a new, slightly incompatible clockevents code in -rt now so you'll need to do some more (hopefully trivial) fixups for this to build and work. Ingo Hello Ingo, thanks for reply. I am attaching updated version of the patch at the end of e-mail. There is problem with missing include in tick-sched.c CC kernel/time/tick-sched.o /usr/src/linux-2.6.20-rc5/kernel/time/tick-sched.c: In function `tick_nohz_handler': /usr/src/linux-2.6.20-rc5/kernel/time/tick-sched.c:330: warning: implicit declaration of function `get_irq_regs' /usr/src/linux-2.6.20-rc5/kernel/time/tick-sched.c:330: warning: initialization makes pointer from integer without a cast /usr/src/linux-2.6.20-rc5/kernel/time/tick-sched.c: In function `tick_sched_timer': /usr/src/linux-2.6.20-rc5/kernel/time/tick-sched.c:425: warning: initialization makes pointer from integer without a cast LD kernel/time/built-in.o --- linux-2.6.20-rc5.orig/kernel/time/tick-sched.c +++ linux-2.6.20-rc5/kernel/time/tick-sched.c @@ -20,6 +20,7 @@ #include linux/profile.h #include linux/sched.h #include linux/tick.h +#include asm/irq_regs.h #include tick-internal.h And CC arch/arm/kernel/process.o /usr/src/linux-2.6.20-rc5/arch/arm/kernel/process.c: In function `cpu_idle': /usr/src/linux-2.6.20-rc5/arch/arm/kernel/process.c:157: warning: implicit declaration of function `hrtimer_stop_sched_tick' /usr/src/linux-2.6.20-rc5/arch/arm/kernel/process.c:161: warning: implicit declaration of function `hrtimer_restart_sched_tick' --- linux-2.6.20-rc5.orig/arch/arm/kernel/process.c +++ linux-2.6.20-rc5/arch/arm/kernel/process.c @@ -154,11 +154,11 @@ void cpu_idle(void) if (!idle) idle = default_idle; leds_event(led_idle_start); - hrtimer_stop_sched_tick(); + tick_nohz_stop_sched_tick(); while (!need_resched() !need_resched_delayed()) idle(); leds_event(led_idle_end); - hrtimer_restart_sched_tick(); + tick_nohz_restart_sched_tick(); local_irq_disable(); __preempt_enable_no_resched(); __schedule(); Unfortunately, even with these corrections boot stuck at Memory: 18972KB available (2488K code, 358K data, 92K init) I have not time now to start JTAG debugging session, so I look at that tomorrow or on Friday. It seems, that the interrupts are not coming from device. Best wishes Pavel == Subject: arm: i.MX/MX1 clock event source Support clock event source based on i.MX general purpose timer in free running timer mode. Signed-off-by: Pavel Pisa [EMAIL PROTECTED] arch/arm/mach-imx/time.c | 112 --- 1 file changed, 107 insertions(+), 5 deletions(-) Index: linux-2.6.20-rc5/arch/arm/mach-imx/time.c === --- linux-2.6.20-rc5.orig/arch/arm/mach-imx/time.c +++ linux-2.6.20-rc5/arch/arm/mach-imx/time.c @@ -15,6 +15,9 @@ #include linux/irq.h #include linux/time.h #include linux/clocksource.h +#ifdef CONFIG_GENERIC_CLOCKEVENTS +#include linux/clockchips.h +#endif #include asm/hardware.h #include asm/io.h @@ -25,6 +28,11 @@ /* Use timer 1 as system timer */ #define TIMER_BASE IMX_TIM1_BASE +#ifdef CONFIG_GENERIC_CLOCKEVENTS +static struct clock_event_device clockevent_imx; +static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_PERIODIC; +#endif + static unsigned long evt_diff; /* @@ -33,6 +41,7 @@ static unsigned long evt_diff; static irqreturn_t imx_timer_interrupt(int irq, void *dev_id) { + unsigned long tcmp; uint32_t tstat; /* clear the interrupt */ @@ -42,13 +51,20 @@ imx_timer_interrupt(int irq, void *dev_i if (tstat TSTAT_COMP) { do { +#ifdef CONFIG_GENERIC_CLOCKEVENTS + if (clockevent_imx.event_handler) + clockevent_imx.event_handler(clockevent_imx); + if (likely(clockevent_mode != CLOCK_EVT_MODE_PERIODIC)) + break; +#else write_seqlock(xtime_lock); timer_tick();
[PATCH query] arm: i.MX/MX1 clock event source
Hello Thomas, Sascha and Ingo please can you find some time to review next patch arm: i.MX/MX1 clock event source which has been sent to you and to the ALKML at 2007-01-13. http://thread.gmane.org/gmane.linux.ports.arm.kernel/29510/focus=29533 There seems to be some problems, because this patch has not been accepted to patch-2.6.20-rc5-rt7.patch, but GENERIC_CLOCKEVENTS are set already for i.MX and this results in a problems to run RT kernel on this architecture. config ARCH_IMX bool "IMX" + select GENERIC_TIME + select GENERIC_CLOCKEVENTS Thanks for review and your time Pavel - Subject: arm: i.MX/MX1 clock event source Support clock event source based on i.MX general purpose timer in free running timer mode. Signed-off-by: Pavel Pisa <[EMAIL PROTECTED]> arch/arm/mach-imx/time.c | 92 +++ 1 file changed, 92 insertions(+) Index: linux-2.6.20-rc4/arch/arm/mach-imx/time.c === --- linux-2.6.20-rc4.orig/arch/arm/mach-imx/time.c +++ linux-2.6.20-rc4/arch/arm/mach-imx/time.c @@ -15,6 +15,9 @@ #include #include #include +#ifdef CONFIG_GENERIC_CLOCKEVENTS +#include +#endif #include #include @@ -25,6 +28,11 @@ /* Use timer 1 as system timer */ #define TIMER_BASE IMX_TIM1_BASE +#ifdef CONFIG_GENERIC_CLOCKEVENTS +static struct clock_event_device clockevent_imx; +static enum clock_event_mode clockevent_mode = CLOCK_EVT_PERIODIC; +#endif + static unsigned long evt_diff; /* @@ -42,9 +50,16 @@ imx_timer_interrupt(int irq, void *dev_i if (tstat & TSTAT_COMP) { do { +#ifdef CONFIG_GENERIC_CLOCKEVENTS + if (clockevent_imx.event_handler) + clockevent_imx.event_handler(); + if (likely(clockevent_mode != CLOCK_EVT_PERIODIC)) + break; +#else write_seqlock(_lock); timer_tick(); write_sequnlock(_lock); +#endif IMX_TCMP(TIMER_BASE) += evt_diff; } while (unlikely((int32_t)(IMX_TCMP(TIMER_BASE) @@ -99,11 +114,88 @@ static int __init imx_clocksource_init(v return 0; } +#ifdef CONFIG_GENERIC_CLOCKEVENTS + +static void imx_set_next_event(unsigned long evt, + struct clock_event_device *unused) +{ + evt_diff = evt; + IMX_TCMP(TIMER_BASE) = IMX_TCN(TIMER_BASE) + evt; +} + +static void imx_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) +{ + unsigned long flags; + + /* +* The timer interrupt generation is disabled at least +* for enough time to call imx_set_next_event() +*/ + local_irq_save(flags); + /* Disable interrupt in GPT module */ + IMX_TCTL(TIMER_BASE) &= ~TCTL_IRQEN; + if ((mode != CLOCK_EVT_PERIODIC) || (mode != clockevent_mode)) { + /* Set event time into far-far future */ + IMX_TCMP(TIMER_BASE) = IMX_TCN(TIMER_BASE) - 3; + /* Clear pending interrupt */ + IMX_TSTAT(TIMER_BASE) &= ~TSTAT_COMP; + } + /* Remember timer mode */ + clockevent_mode = mode; + local_irq_restore(flags); + + switch (mode) { + case CLOCK_EVT_PERIODIC: + case CLOCK_EVT_ONESHOT: + /* +* Do not put overhead of interrupt enable/disable into +* imx_set_next_event(), the core has about 4 minutes +* to call imx_set_next_event() or shutdown clock after +* mode switching +*/ + local_irq_save(flags); + IMX_TCTL(TIMER_BASE) |= TCTL_IRQEN; + local_irq_restore(flags); + break; + case CLOCK_EVT_SHUTDOWN: + /* Left event sources disabled, no more interrupts appears */ + break; + } +} + +static struct clock_event_device clockevent_imx = { + .name = "imx_timer1", + .capabilities = CLOCK_CAP_NEXTEVT | CLOCK_CAP_TICK | + CLOCK_CAP_UPDATE | CLOCK_CAP_PROFILE, + .shift = 32, + .set_mode = imx_set_mode, + .set_next_event = imx_set_next_event, +}; + +static int __init imx_clockevent_init(void) +{ + clockevent_imx.mult = div_sc(imx_get_perclk1(), NSEC_PER_SEC, + clockevent_imx.shift); + clockevent_imx.max_delta_ns = + clockevent_delta2ns(0xfffe, _imx); + clockevent_imx.min_delta_ns = + clockevent_delta2ns(0xf, _imx); + register_local_clockevent(_imx); + + return 0; +} +#endif + + static void __init imx_timer_init(void) { imx_timer_hardware_init();
[PATCH query] arm: i.MX/MX1 clock event source
Hello Thomas, Sascha and Ingo please can you find some time to review next patch arm: i.MX/MX1 clock event source which has been sent to you and to the ALKML at 2007-01-13. http://thread.gmane.org/gmane.linux.ports.arm.kernel/29510/focus=29533 There seems to be some problems, because this patch has not been accepted to patch-2.6.20-rc5-rt7.patch, but GENERIC_CLOCKEVENTS are set already for i.MX and this results in a problems to run RT kernel on this architecture. config ARCH_IMX bool IMX + select GENERIC_TIME + select GENERIC_CLOCKEVENTS Thanks for review and your time Pavel - Subject: arm: i.MX/MX1 clock event source Support clock event source based on i.MX general purpose timer in free running timer mode. Signed-off-by: Pavel Pisa [EMAIL PROTECTED] arch/arm/mach-imx/time.c | 92 +++ 1 file changed, 92 insertions(+) Index: linux-2.6.20-rc4/arch/arm/mach-imx/time.c === --- linux-2.6.20-rc4.orig/arch/arm/mach-imx/time.c +++ linux-2.6.20-rc4/arch/arm/mach-imx/time.c @@ -15,6 +15,9 @@ #include linux/irq.h #include linux/time.h #include linux/clocksource.h +#ifdef CONFIG_GENERIC_CLOCKEVENTS +#include linux/clockchips.h +#endif #include asm/hardware.h #include asm/io.h @@ -25,6 +28,11 @@ /* Use timer 1 as system timer */ #define TIMER_BASE IMX_TIM1_BASE +#ifdef CONFIG_GENERIC_CLOCKEVENTS +static struct clock_event_device clockevent_imx; +static enum clock_event_mode clockevent_mode = CLOCK_EVT_PERIODIC; +#endif + static unsigned long evt_diff; /* @@ -42,9 +50,16 @@ imx_timer_interrupt(int irq, void *dev_i if (tstat TSTAT_COMP) { do { +#ifdef CONFIG_GENERIC_CLOCKEVENTS + if (clockevent_imx.event_handler) + clockevent_imx.event_handler(); + if (likely(clockevent_mode != CLOCK_EVT_PERIODIC)) + break; +#else write_seqlock(xtime_lock); timer_tick(); write_sequnlock(xtime_lock); +#endif IMX_TCMP(TIMER_BASE) += evt_diff; } while (unlikely((int32_t)(IMX_TCMP(TIMER_BASE) @@ -99,11 +114,88 @@ static int __init imx_clocksource_init(v return 0; } +#ifdef CONFIG_GENERIC_CLOCKEVENTS + +static void imx_set_next_event(unsigned long evt, + struct clock_event_device *unused) +{ + evt_diff = evt; + IMX_TCMP(TIMER_BASE) = IMX_TCN(TIMER_BASE) + evt; +} + +static void imx_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) +{ + unsigned long flags; + + /* +* The timer interrupt generation is disabled at least +* for enough time to call imx_set_next_event() +*/ + local_irq_save(flags); + /* Disable interrupt in GPT module */ + IMX_TCTL(TIMER_BASE) = ~TCTL_IRQEN; + if ((mode != CLOCK_EVT_PERIODIC) || (mode != clockevent_mode)) { + /* Set event time into far-far future */ + IMX_TCMP(TIMER_BASE) = IMX_TCN(TIMER_BASE) - 3; + /* Clear pending interrupt */ + IMX_TSTAT(TIMER_BASE) = ~TSTAT_COMP; + } + /* Remember timer mode */ + clockevent_mode = mode; + local_irq_restore(flags); + + switch (mode) { + case CLOCK_EVT_PERIODIC: + case CLOCK_EVT_ONESHOT: + /* +* Do not put overhead of interrupt enable/disable into +* imx_set_next_event(), the core has about 4 minutes +* to call imx_set_next_event() or shutdown clock after +* mode switching +*/ + local_irq_save(flags); + IMX_TCTL(TIMER_BASE) |= TCTL_IRQEN; + local_irq_restore(flags); + break; + case CLOCK_EVT_SHUTDOWN: + /* Left event sources disabled, no more interrupts appears */ + break; + } +} + +static struct clock_event_device clockevent_imx = { + .name = imx_timer1, + .capabilities = CLOCK_CAP_NEXTEVT | CLOCK_CAP_TICK | + CLOCK_CAP_UPDATE | CLOCK_CAP_PROFILE, + .shift = 32, + .set_mode = imx_set_mode, + .set_next_event = imx_set_next_event, +}; + +static int __init imx_clockevent_init(void) +{ + clockevent_imx.mult = div_sc(imx_get_perclk1(), NSEC_PER_SEC, + clockevent_imx.shift); + clockevent_imx.max_delta_ns = + clockevent_delta2ns(0xfffe, clockevent_imx); + clockevent_imx.min_delta_ns = + clockevent_delta2ns(0xf, clockevent_imx); + register_local_clockevent(clockevent_imx); + + return 0; +}