Re: [PATCH query] arm: i.MX/MX1 clock event source

2007-01-24 Thread Thomas Gleixner
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

2007-01-24 Thread Thomas Gleixner
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

2007-01-23 Thread Pavel Pisa
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

2007-01-23 Thread Pavel Pisa
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

2007-01-22 Thread Pavel Pisa
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

2007-01-22 Thread Ingo Molnar

* 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

2007-01-22 Thread Ingo Molnar

* 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

2007-01-22 Thread Pavel Pisa
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

2007-01-20 Thread Pavel Pisa
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

2007-01-20 Thread Pavel Pisa
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;
+}