Re: [patch 2.6.25-rc2-git 2/2] atmel_tc clocksource/clockevent code

2008-02-26 Thread David Brownell
On Tuesday 26 February 2008, Haavard Skinnemoen wrote:
> > Another way to address that rm9200 issue would be to just rate
> > the TC clockevent source lower than the one based on the system
> > timer, so it's set up but never enabled ... and remember "t2_clk",
> > calling clk_enable() only when that clockevent device is active.
> > 
> > That would address one half of the suspend/resume equation too,
> > ensuring that clock is disabled during suspend...
> 
> Yes, we could probably do that. Which means we can just remove all the
> ifdeffery?

There'd still be the #ifdef for CONFIG_GENERIC_CLOCKEVENTS,
unless all the platforms get updated to support that.  Right
now it's a "patches available but not merged" situation.


> > The other half being:  how to clk_disable(t0_clk) during system
> > suspend?  (And t1_clk on some systems.)  There's currently no
> > clocksource.set_mode() call; evidently there's an assumption that
> > such counters cost no power, so they can always be left running.
> 
> Yes...that would be a clocksource core issue I guess. Better leave that
> for later...

My thoughts exactly.  ;)

Plus a bit of puzzlement why that didn't trigger at least a
warning during AT91 suspend testing.  There used to be warnings
there about clocks which were wrongly left enabled...

- Dave
--
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 2.6.25-rc2-git 2/2] atmel_tc clocksource/clockevent code

2008-02-26 Thread Haavard Skinnemoen
On Mon, 25 Feb 2008 09:51:16 -0800
David Brownell <[EMAIL PROTECTED]> wrote:

> > > > > +static cycle_t tc_get_cycles(void)
> > > > > +{
> > > > > + unsigned long   flags;
> > > > > + u32 lower, upper;
> > > > > +
> > > > > + raw_local_irq_save(flags);
> > > >
> > > > Why do you need to use the raw version?
> > > 
> > > This is part of the system timer code, and it should never be a
> > > preemption point.  Plus I didn't want to waste any instruction
> > > cycles in code that runs before e.g. the DBGU IRQ handler would
> > > get called... observably, such extra cycles *do* hurt.
> >
> > I don't understand what you mean by preemption point, but I guess the
> > non-raw version may consume some extra cycles when lockdep is enabled.
> 
> A preemption point is where CONFIG_PREEMPT kicks in task switching
> logic; lockdep is different.

I know, but I dont' see how local_irq_save/restore has anything to do
with it, raw or not. There would be absolutely no point checking for
preemption on local_irq_restore() since no one would have been able to
set the TIF_NEED_RESCHED flag while interrupts were disabled...

raw_local_irq_save/restore is only different from
local_irq_save/restore when lockdep is enabled. That's why I don't
understand why you're talking about preemption.

> > If we really expect using TC as a clocksource but not as a clockevent
> > is going to be a common usage, perhaps we should move the decision into
> > Kconfig?
> 
> Maybe, but I already spent lots more time on this than I wanted.  :(

I'm not asking you to do it. I'm asking if it would be a good thing to
do. I said that I can take these patches off your back if you want, but
I want to make sure I don't do anything with them that you disagree
with.

> Another way to address that rm9200 issue would be to just rate
> the TC clockevent source lower than the one based on the system
> timer, so it's set up but never enabled ... and remember "t2_clk",
> calling clk_enable() only when that clockevent device is active.
> 
> That would address one half of the suspend/resume equation too,
> ensuring that clock is disabled during suspend...

Yes, we could probably do that. Which means we can just remove all the
ifdeffery?

> The other half being:  how to clk_disable(t0_clk) during system
> suspend?  (And t1_clk on some systems.)  There's currently no
> clocksource.set_mode() call; evidently there's an assumption that
> such counters cost no power, so they can always be left running.

Yes...that would be a clocksource core issue I guess. Better leave that
for later...

> > > > I don't think it is safe to assume that one clock per channel always
> > > > means one irq per channel as well...
> > > 
> > > On current chips, that's how it works.
> >
> > Indeed. I just don't see any fundamental reason why it has to work that
> > way, which is why I don't think we should depend on it.
> 
> AT91 chips share identifiers between clocks and interrupts; that's
> fundamental, yes?
> 
> If some future chip works differently, that's a good time to change
> things.  Otherwise I see little point in caring about such issues.

Agreed.

Haavard
--
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 2.6.25-rc2-git 2/2] atmel_tc clocksource/clockevent code

2008-02-26 Thread Haavard Skinnemoen
On Mon, 25 Feb 2008 09:51:16 -0800
David Brownell [EMAIL PROTECTED] wrote:

 +static cycle_t tc_get_cycles(void)
 +{
 + unsigned long   flags;
 + u32 lower, upper;
 +
 + raw_local_irq_save(flags);
   
Why do you need to use the raw version?
   
   This is part of the system timer code, and it should never be a
   preemption point.  Plus I didn't want to waste any instruction
   cycles in code that runs before e.g. the DBGU IRQ handler would
   get called... observably, such extra cycles *do* hurt.
 
  I don't understand what you mean by preemption point, but I guess the
  non-raw version may consume some extra cycles when lockdep is enabled.
 
 A preemption point is where CONFIG_PREEMPT kicks in task switching
 logic; lockdep is different.

I know, but I dont' see how local_irq_save/restore has anything to do
with it, raw or not. There would be absolutely no point checking for
preemption on local_irq_restore() since no one would have been able to
set the TIF_NEED_RESCHED flag while interrupts were disabled...

raw_local_irq_save/restore is only different from
local_irq_save/restore when lockdep is enabled. That's why I don't
understand why you're talking about preemption.

  If we really expect using TC as a clocksource but not as a clockevent
  is going to be a common usage, perhaps we should move the decision into
  Kconfig?
 
 Maybe, but I already spent lots more time on this than I wanted.  :(

I'm not asking you to do it. I'm asking if it would be a good thing to
do. I said that I can take these patches off your back if you want, but
I want to make sure I don't do anything with them that you disagree
with.

 Another way to address that rm9200 issue would be to just rate
 the TC clockevent source lower than the one based on the system
 timer, so it's set up but never enabled ... and remember t2_clk,
 calling clk_enable() only when that clockevent device is active.
 
 That would address one half of the suspend/resume equation too,
 ensuring that clock is disabled during suspend...

Yes, we could probably do that. Which means we can just remove all the
ifdeffery?

 The other half being:  how to clk_disable(t0_clk) during system
 suspend?  (And t1_clk on some systems.)  There's currently no
 clocksource.set_mode() call; evidently there's an assumption that
 such counters cost no power, so they can always be left running.

Yes...that would be a clocksource core issue I guess. Better leave that
for later...

I don't think it is safe to assume that one clock per channel always
means one irq per channel as well...
   
   On current chips, that's how it works.
 
  Indeed. I just don't see any fundamental reason why it has to work that
  way, which is why I don't think we should depend on it.
 
 AT91 chips share identifiers between clocks and interrupts; that's
 fundamental, yes?
 
 If some future chip works differently, that's a good time to change
 things.  Otherwise I see little point in caring about such issues.

Agreed.

Haavard
--
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 2.6.25-rc2-git 2/2] atmel_tc clocksource/clockevent code

2008-02-26 Thread David Brownell
On Tuesday 26 February 2008, Haavard Skinnemoen wrote:
  Another way to address that rm9200 issue would be to just rate
  the TC clockevent source lower than the one based on the system
  timer, so it's set up but never enabled ... and remember t2_clk,
  calling clk_enable() only when that clockevent device is active.
  
  That would address one half of the suspend/resume equation too,
  ensuring that clock is disabled during suspend...
 
 Yes, we could probably do that. Which means we can just remove all the
 ifdeffery?

There'd still be the #ifdef for CONFIG_GENERIC_CLOCKEVENTS,
unless all the platforms get updated to support that.  Right
now it's a patches available but not merged situation.


  The other half being:  how to clk_disable(t0_clk) during system
  suspend?  (And t1_clk on some systems.)  There's currently no
  clocksource.set_mode() call; evidently there's an assumption that
  such counters cost no power, so they can always be left running.
 
 Yes...that would be a clocksource core issue I guess. Better leave that
 for later...

My thoughts exactly.  ;)

Plus a bit of puzzlement why that didn't trigger at least a
warning during AT91 suspend testing.  There used to be warnings
there about clocks which were wrongly left enabled...

- Dave
--
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 2.6.25-rc2-git 2/2] atmel_tc clocksource/clockevent code

2008-02-25 Thread David Brownell
> > > > +static cycle_t tc_get_cycles(void)
> > > > +{
> > > > +   unsigned long   flags;
> > > > +   u32 lower, upper;
> > > > +
> > > > +   raw_local_irq_save(flags);
> > >
> > > Why do you need to use the raw version?
> > 
> > This is part of the system timer code, and it should never be a
> > preemption point.  Plus I didn't want to waste any instruction
> > cycles in code that runs before e.g. the DBGU IRQ handler would
> > get called... observably, such extra cycles *do* hurt.
>
> I don't understand what you mean by preemption point, but I guess the
> non-raw version may consume some extra cycles when lockdep is enabled.

A preemption point is where CONFIG_PREEMPT kicks in task switching
logic; lockdep is different.


> If we really expect using TC as a clocksource but not as a clockevent
> is going to be a common usage, perhaps we should move the decision into
> Kconfig?

Maybe, but I already spent lots more time on this than I wanted.  :(

Another way to address that rm9200 issue would be to just rate
the TC clockevent source lower than the one based on the system
timer, so it's set up but never enabled ... and remember "t2_clk",
calling clk_enable() only when that clockevent device is active.

That would address one half of the suspend/resume equation too,
ensuring that clock is disabled during suspend...

The other half being:  how to clk_disable(t0_clk) during system
suspend?  (And t1_clk on some systems.)  There's currently no
clocksource.set_mode() call; evidently there's an assumption that
such counters cost no power, so they can always be left running.


> > > I don't think it is safe to assume that one clock per channel always
> > > means one irq per channel as well...
> > 
> > On current chips, that's how it works.
>
> Indeed. I just don't see any fundamental reason why it has to work that
> way, which is why I don't think we should depend on it.

AT91 chips share identifiers between clocks and interrupts; that's
fundamental, yes?

If some future chip works differently, that's a good time to change
things.  Otherwise I see little point in caring about such issues.

- Dave

--
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 2.6.25-rc2-git 2/2] atmel_tc clocksource/clockevent code

2008-02-25 Thread Haavard Skinnemoen
On Sun, 24 Feb 2008 15:42:51 -0800
David Brownell <[EMAIL PROTECTED]> wrote:

> > On Fri, 22 Feb 2008 17:28:37 -0800
> > David Brownell <[EMAIL PROTECTED]> wrote:
> >
> > > +static cycle_t tc_get_cycles(void)
> > > +{
> > > + unsigned long   flags;
> > > + u32 lower, upper;
> > > +
> > > + raw_local_irq_save(flags);
> >
> > Why do you need to use the raw version?
> 
> This is part of the system timer code, and it should never be a
> preemption point.  Plus I didn't want to waste any instruction
> cycles in code that runs before e.g. the DBGU IRQ handler would
> get called... observably, such extra cycles *do* hurt.

I don't understand what you mean by preemption point, but I guess the
non-raw version may consume some extra cycles when lockdep is enabled.

> > > +#ifdef CONFIG_GENERIC_CLOCKEVENTS
> > > +#define USE_TC_CLKEVT
> > > +#endif
> > > +
> > > +#ifdef CONFIG_ARCH_AT91RM9200
> > > +/* The AT91rm9200 system timer is a oneshot-capable 32k timer that's
> > > + * always running ... configuring a TC channel to work the same way
> > > + * would just waste some power.
> > > + */
> > > +#undef USE_TC_CLKEVT
> > > +#endif
> > > +
> > > +#ifdef USE_TC_CLKEVT
> >
> > Can't you just use #ifndef CONFIG_ARCH_AT91RM9200 and avoid the whole
> > ifdef/define/undef dance above?
> 
> I can't know that some other platform won't have a better system
> timer solution, and didn't want to assume that only that single
> venerable chip had such a solution ... it's kind of puzzling to
> me (software guy) that none of the newest Atmel SOCs have better
> timer infrastructure than they do.  ;)

Heh.

If we really expect using TC as a clocksource but not as a clockevent
is going to be a common usage, perhaps we should move the decision into
Kconfig?

Besides, I don't really see the difference between having a big #ifdef
expression around the whole clockevent block and having a big #ifdef
expression around the definition of USE_TC_CLKEVT except that the
latter is more code...

> > > + case CLOCK_EVT_MODE_ONESHOT:
> > > + /* slow clock, count up to RC, then irq and stop */
> >
> > Hmm. Do you really want to stop it? Won't you get better accuracy if
> > you let it run and program the next event as (prev_event + delta)?
> 
> No, ONESHOT means "stop after the IRQ I asked for".  And when
> tc_next_event() is asked to trigger that IRQ, it's relative to
> the instant it's requested, not relative to the last one that
> was requested (which may not have triggered yet, or may have
> been quite some time ago).

Right. Sounds like it might introduce some inaccuracy, but I guess it's
the clocksource's job to keep track of the actual time at the time of
the event.

> > > +static struct irqaction tc_irqaction = {
> > > + .name   = "tc_clkevt",
> > > + .flags  = IRQF_TIMER | IRQF_DISABLED,
> > > + .handler= ch2_irq,
> > > +};
> >
> > I don't think you need to define this statically. You can call
> > request_irq() at arch_initcall() time.
> 
> That could be done, yes ... and using request_irq()/free_irq()
> would also let this be linked as a module, not just statically.
> 
> On the other hand, doing it this way doesn't hurt either does it?
> Unless a modular build is important.

No, it doesn't hurt. Maybe we should keep it static so that we have the
option of initializing it earlier if we need to.

> > I don't think it is safe to assume that one clock per channel always
> > means one irq per channel as well...
> 
> On current chips, that's how it works.

Indeed. I just don't see any fundamental reason why it has to work that
way, which is why I don't think we should depend on it.

> > What's wrong with
> >
> > irq = platform_get_irq(pdev, 2);
> > if (irq < 0)
> > irq = platform_get_irq(pdev, 0);
> 
> Nothing much, except that I took the more concise path.  Got patch?

Not until we reach a conclusion about the tclib core.

> > How about we make tcb_clksrc_init() global and call it from the
> > platform code with whatever TCB the platform thinks is appropriate?
> 
> That could work too, but if it goes that way then there's no
> point in changes to support a modular build (e.g. the irqaction
> thing you noted above).

True.

> > Perhaps remove the prompt from ATMEL_TCB_CLKSRC and have the platform
> > select it as well? I certainly want to force this stuff on on the
> > AP7000...otherwise we'll just get lots of complaints that the thing is
> > using 4x more power than it's supposed to...
> 
> Well, "force" seems the wrong approach to me.  That should be a
> board-specific choice.  The ap700x power budget may not be the
> most important system design consideration, so making such a
> decision at the platform ("ap700x") level seems wrong.
> 
> Suppose someone has to build an AVR32 based system that uses both
> TCB modules to hook up to external hardware, so that neither one
> is available for use as a "system timer"?

Good point. Let's keep it as it is and let the board "select" it

Re: [patch 2.6.25-rc2-git 2/2] atmel_tc clocksource/clockevent code

2008-02-25 Thread Haavard Skinnemoen
On Sun, 24 Feb 2008 15:42:51 -0800
David Brownell [EMAIL PROTECTED] wrote:

  On Fri, 22 Feb 2008 17:28:37 -0800
  David Brownell [EMAIL PROTECTED] wrote:
 
   +static cycle_t tc_get_cycles(void)
   +{
   + unsigned long   flags;
   + u32 lower, upper;
   +
   + raw_local_irq_save(flags);
 
  Why do you need to use the raw version?
 
 This is part of the system timer code, and it should never be a
 preemption point.  Plus I didn't want to waste any instruction
 cycles in code that runs before e.g. the DBGU IRQ handler would
 get called... observably, such extra cycles *do* hurt.

I don't understand what you mean by preemption point, but I guess the
non-raw version may consume some extra cycles when lockdep is enabled.

   +#ifdef CONFIG_GENERIC_CLOCKEVENTS
   +#define USE_TC_CLKEVT
   +#endif
   +
   +#ifdef CONFIG_ARCH_AT91RM9200
   +/* The AT91rm9200 system timer is a oneshot-capable 32k timer that's
   + * always running ... configuring a TC channel to work the same way
   + * would just waste some power.
   + */
   +#undef USE_TC_CLKEVT
   +#endif
   +
   +#ifdef USE_TC_CLKEVT
 
  Can't you just use #ifndef CONFIG_ARCH_AT91RM9200 and avoid the whole
  ifdef/define/undef dance above?
 
 I can't know that some other platform won't have a better system
 timer solution, and didn't want to assume that only that single
 venerable chip had such a solution ... it's kind of puzzling to
 me (software guy) that none of the newest Atmel SOCs have better
 timer infrastructure than they do.  ;)

Heh.

If we really expect using TC as a clocksource but not as a clockevent
is going to be a common usage, perhaps we should move the decision into
Kconfig?

Besides, I don't really see the difference between having a big #ifdef
expression around the whole clockevent block and having a big #ifdef
expression around the definition of USE_TC_CLKEVT except that the
latter is more code...

   + case CLOCK_EVT_MODE_ONESHOT:
   + /* slow clock, count up to RC, then irq and stop */
 
  Hmm. Do you really want to stop it? Won't you get better accuracy if
  you let it run and program the next event as (prev_event + delta)?
 
 No, ONESHOT means stop after the IRQ I asked for.  And when
 tc_next_event() is asked to trigger that IRQ, it's relative to
 the instant it's requested, not relative to the last one that
 was requested (which may not have triggered yet, or may have
 been quite some time ago).

Right. Sounds like it might introduce some inaccuracy, but I guess it's
the clocksource's job to keep track of the actual time at the time of
the event.

   +static struct irqaction tc_irqaction = {
   + .name   = tc_clkevt,
   + .flags  = IRQF_TIMER | IRQF_DISABLED,
   + .handler= ch2_irq,
   +};
 
  I don't think you need to define this statically. You can call
  request_irq() at arch_initcall() time.
 
 That could be done, yes ... and using request_irq()/free_irq()
 would also let this be linked as a module, not just statically.
 
 On the other hand, doing it this way doesn't hurt either does it?
 Unless a modular build is important.

No, it doesn't hurt. Maybe we should keep it static so that we have the
option of initializing it earlier if we need to.

  I don't think it is safe to assume that one clock per channel always
  means one irq per channel as well...
 
 On current chips, that's how it works.

Indeed. I just don't see any fundamental reason why it has to work that
way, which is why I don't think we should depend on it.

  What's wrong with
 
  irq = platform_get_irq(pdev, 2);
  if (irq  0)
  irq = platform_get_irq(pdev, 0);
 
 Nothing much, except that I took the more concise path.  Got patch?

Not until we reach a conclusion about the tclib core.

  How about we make tcb_clksrc_init() global and call it from the
  platform code with whatever TCB the platform thinks is appropriate?
 
 That could work too, but if it goes that way then there's no
 point in changes to support a modular build (e.g. the irqaction
 thing you noted above).

True.

  Perhaps remove the prompt from ATMEL_TCB_CLKSRC and have the platform
  select it as well? I certainly want to force this stuff on on the
  AP7000...otherwise we'll just get lots of complaints that the thing is
  using 4x more power than it's supposed to...
 
 Well, force seems the wrong approach to me.  That should be a
 board-specific choice.  The ap700x power budget may not be the
 most important system design consideration, so making such a
 decision at the platform (ap700x) level seems wrong.
 
 Suppose someone has to build an AVR32 based system that uses both
 TCB modules to hook up to external hardware, so that neither one
 is available for use as a system timer?

Good point. Let's keep it as it is and let the board select it
through its defconfig.

Haavard
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  

Re: [patch 2.6.25-rc2-git 2/2] atmel_tc clocksource/clockevent code

2008-02-25 Thread David Brownell
+static cycle_t tc_get_cycles(void)
+{
+   unsigned long   flags;
+   u32 lower, upper;
+
+   raw_local_irq_save(flags);
  
   Why do you need to use the raw version?
  
  This is part of the system timer code, and it should never be a
  preemption point.  Plus I didn't want to waste any instruction
  cycles in code that runs before e.g. the DBGU IRQ handler would
  get called... observably, such extra cycles *do* hurt.

 I don't understand what you mean by preemption point, but I guess the
 non-raw version may consume some extra cycles when lockdep is enabled.

A preemption point is where CONFIG_PREEMPT kicks in task switching
logic; lockdep is different.


 If we really expect using TC as a clocksource but not as a clockevent
 is going to be a common usage, perhaps we should move the decision into
 Kconfig?

Maybe, but I already spent lots more time on this than I wanted.  :(

Another way to address that rm9200 issue would be to just rate
the TC clockevent source lower than the one based on the system
timer, so it's set up but never enabled ... and remember t2_clk,
calling clk_enable() only when that clockevent device is active.

That would address one half of the suspend/resume equation too,
ensuring that clock is disabled during suspend...

The other half being:  how to clk_disable(t0_clk) during system
suspend?  (And t1_clk on some systems.)  There's currently no
clocksource.set_mode() call; evidently there's an assumption that
such counters cost no power, so they can always be left running.


   I don't think it is safe to assume that one clock per channel always
   means one irq per channel as well...
  
  On current chips, that's how it works.

 Indeed. I just don't see any fundamental reason why it has to work that
 way, which is why I don't think we should depend on it.

AT91 chips share identifiers between clocks and interrupts; that's
fundamental, yes?

If some future chip works differently, that's a good time to change
things.  Otherwise I see little point in caring about such issues.

- Dave

--
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 2.6.25-rc2-git 2/2] atmel_tc clocksource/clockevent code

2008-02-24 Thread David Brownell
> Again, sorry for the delay...it really sucks that I haven't been able
> to look at this stuff closely until now. Hopefully a late review is
> better than no review.

Yes.  The review I've gotten so far has been of the "it works for me,
thanks" variety.

(The only issue reported to me is that NO_HZ on AT91 seems to make the
DBGU lose characters sometimes ... that one-byte "fifo" makes trouble
whenever there's the slightest delay in IRQ handling, and NO_HZ can
easily add such delays as part of ensuring that "jiffies" is current
before invoking handlers.)


> On Fri, 22 Feb 2008 17:28:37 -0800
> David Brownell <[EMAIL PROTECTED]> wrote:
>
> > +static cycle_t tc_get_cycles(void)
> > +{
> > +   unsigned long   flags;
> > +   u32 lower, upper;
> > +
> > +   raw_local_irq_save(flags);
>
> Why do you need to use the raw version?

This is part of the system timer code, and it should never be a
preemption point.  Plus I didn't want to waste any instruction
cycles in code that runs before e.g. the DBGU IRQ handler would
get called... observably, such extra cycles *do* hurt.


> > +retry:
> > +   upper = __raw_readl(tcaddr + ATMEL_TC_REG(1, CV));
> > +   lower = __raw_readl(tcaddr + ATMEL_TC_REG(0, CV));
> > +   if (upper != __raw_readl(tcaddr + ATMEL_TC_REG(1, CV)))
> > +   goto retry;
>
> Did you just open-code a do/while loop using goto? ;-)

I take that back about late review being better than none.  ;)


> > +#ifdef CONFIG_GENERIC_CLOCKEVENTS
> > +#define USE_TC_CLKEVT
> > +#endif
> > +
> > +#ifdef CONFIG_ARCH_AT91RM9200
> > +/* The AT91rm9200 system timer is a oneshot-capable 32k timer that's
> > + * always running ... configuring a TC channel to work the same way
> > + * would just waste some power.
> > + */
> > +#undef USE_TC_CLKEVT
> > +#endif
> > +
> > +#ifdef USE_TC_CLKEVT
>
> Can't you just use #ifndef CONFIG_ARCH_AT91RM9200 and avoid the whole
> ifdef/define/undef dance above?

I can't know that some other platform won't have a better system
timer solution, and didn't want to assume that only that single
venerable chip had such a solution ... it's kind of puzzling to
me (software guy) that none of the newest Atmel SOCs have better
timer infrastructure than they do.  ;)


> > +   case CLOCK_EVT_MODE_ONESHOT:
> > +   /* slow clock, count up to RC, then irq and stop */
>
> Hmm. Do you really want to stop it? Won't you get better accuracy if
> you let it run and program the next event as (prev_event + delta)?

No, ONESHOT means "stop after the IRQ I asked for".  And when
tc_next_event() is asked to trigger that IRQ, it's relative to
the instant it's requested, not relative to the last one that
was requested (which may not have triggered yet, or may have
been quite some time ago).


> > +static struct irqaction tc_irqaction = {
> > +   .name   = "tc_clkevt",
> > +   .flags  = IRQF_TIMER | IRQF_DISABLED,
> > +   .handler= ch2_irq,
> > +};
>
> I don't think you need to define this statically. You can call
> request_irq() at arch_initcall() time.

That could be done, yes ... and using request_irq()/free_irq()
would also let this be linked as a module, not just statically.

On the other hand, doing it this way doesn't hurt either does it?
Unless a modular build is important.


> > +static void __init setup_clkevents(struct platform_device *pdev,
> > +   struct clk *t0_clk, int clk32k_divisor_idx)
> > +{
> > +   struct clk  *t2_clk = clk_get(>dev, "t2_clk");
> > +   int irq;
> > +
> > +   /* SOCs have either one IRQ and one clock for the whole
> > +* TC block; or one each per channel.  We use channel 2.
> > +*/
> > +   if (IS_ERR(t2_clk)) {
> > +   t2_clk = t0_clk;
> > +   irq = platform_get_irq(pdev, 0);
> > +   } else {
> > +   irq = platform_get_irq(pdev, 2);
> > +   clk_enable(t2_clk);
> > +   }
>
> I don't think it is safe to assume that one clock per channel always
> means one irq per channel as well...

On current chips, that's how it works.


> What's wrong with
>
>   irq = platform_get_irq(pdev, 2);
>   if (irq < 0)
>   irq = platform_get_irq(pdev, 0);

Nothing much, except that I took the more concise path.  Got patch?


> > +config ATMEL_TCB_CLKSRC
> > +   bool "TC Block Clocksource"
> > +   depends on ATMEL_TCLIB && GENERIC_TIME
> > +   default y
> > +   help
> > + Select this to get a high precision clocksource based on a
> > + TC block with a 5+ MHz base clock rate.  Two timer channels
> > + are combined to make a single 32-bit timer.
> > +
> > + When GENERIC_CLOCKEVENTS is defined, the third timer channel
> > + may be used as a clock event device supporting oneshot mode
> > + (delays of up to two seconds) based on the 32 KiHz clock.
> > +
> > +config ATMEL_TCB_CLKSRC_BLOCK
> > +   int
> > +   depends on ATMEL_TCB_CLKSRC
> > +   prompt "TC Block" if ARCH_AT91RM9200 || ARCH_AT91SAM9260 || 
> > CPU_AT32AP700X
> > +   default 0
> > +   range 0 

Re: [patch 2.6.25-rc2-git 2/2] atmel_tc clocksource/clockevent code

2008-02-24 Thread Haavard Skinnemoen
Again, sorry for the delay...it really sucks that I haven't been able
to look at this stuff closely until now. Hopefully a late review is
better than no review.

On Fri, 22 Feb 2008 17:28:37 -0800
David Brownell <[EMAIL PROTECTED]> wrote:

> +static cycle_t tc_get_cycles(void)
> +{
> + unsigned long   flags;
> + u32 lower, upper;
> +
> + raw_local_irq_save(flags);

Why do you need to use the raw version?

> +retry:
> + upper = __raw_readl(tcaddr + ATMEL_TC_REG(1, CV));
> + lower = __raw_readl(tcaddr + ATMEL_TC_REG(0, CV));
> + if (upper != __raw_readl(tcaddr + ATMEL_TC_REG(1, CV)))
> + goto retry;

Did you just open-code a do/while loop using goto? ;-)

> +#ifdef CONFIG_GENERIC_CLOCKEVENTS
> +#define USE_TC_CLKEVT
> +#endif
> +
> +#ifdef CONFIG_ARCH_AT91RM9200
> +/* The AT91rm9200 system timer is a oneshot-capable 32k timer that's
> + * always running ... configuring a TC channel to work the same way
> + * would just waste some power.
> + */
> +#undef USE_TC_CLKEVT
> +#endif
> +
> +#ifdef USE_TC_CLKEVT

Can't you just use #ifndef CONFIG_ARCH_AT91RM9200 and avoid the whole
ifdef/define/undef dance above?

> + case CLOCK_EVT_MODE_ONESHOT:
> + /* slow clock, count up to RC, then irq and stop */

Hmm. Do you really want to stop it? Won't you get better accuracy if
you let it run and program the next event as (prev_event + delta)?

> +static struct irqaction tc_irqaction = {
> + .name   = "tc_clkevt",
> + .flags  = IRQF_TIMER | IRQF_DISABLED,
> + .handler= ch2_irq,
> +};

I don't think you need to define this statically. You can call
request_irq() at arch_initcall() time.

> +static void __init setup_clkevents(struct platform_device *pdev,
> + struct clk *t0_clk, int clk32k_divisor_idx)
> +{
> + struct clk  *t2_clk = clk_get(>dev, "t2_clk");
> + int irq;
> +
> + /* SOCs have either one IRQ and one clock for the whole
> +  * TC block; or one each per channel.  We use channel 2.
> +  */
> + if (IS_ERR(t2_clk)) {
> + t2_clk = t0_clk;
> + irq = platform_get_irq(pdev, 0);
> + } else {
> + irq = platform_get_irq(pdev, 2);
> + clk_enable(t2_clk);
> + }

I don't think it is safe to assume that one clock per channel always
means one irq per channel as well...

What's wrong with

irq = platform_get_irq(pdev, 2);
if (irq < 0)
irq = platform_get_irq(pdev, 0);

?

> +config ATMEL_TCB_CLKSRC
> + bool "TC Block Clocksource"
> + depends on ATMEL_TCLIB && GENERIC_TIME
> + default y
> + help
> +   Select this to get a high precision clocksource based on a
> +   TC block with a 5+ MHz base clock rate.  Two timer channels
> +   are combined to make a single 32-bit timer.
> +
> +   When GENERIC_CLOCKEVENTS is defined, the third timer channel
> +   may be used as a clock event device supporting oneshot mode
> +   (delays of up to two seconds) based on the 32 KiHz clock.
> +
> +config ATMEL_TCB_CLKSRC_BLOCK
> + int
> + depends on ATMEL_TCB_CLKSRC
> + prompt "TC Block" if ARCH_AT91RM9200 || ARCH_AT91SAM9260 || 
> CPU_AT32AP700X
> + default 0
> + range 0 1

Hmm...I don't like the direction this is going...

How about we make tcb_clksrc_init() global and call it from the
platform code with whatever TCB the platform thinks is appropriate?

Perhaps remove the prompt from ATMEL_TCB_CLKSRC and have the platform
select it as well? I certainly want to force this stuff on on the
AP7000...otherwise we'll just get lots of complaints that the thing is
using 4x more power than it's supposed to...

Haavard
--
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 2.6.25-rc2-git 2/2] atmel_tc clocksource/clockevent code

2008-02-24 Thread Haavard Skinnemoen
Again, sorry for the delay...it really sucks that I haven't been able
to look at this stuff closely until now. Hopefully a late review is
better than no review.

On Fri, 22 Feb 2008 17:28:37 -0800
David Brownell [EMAIL PROTECTED] wrote:

 +static cycle_t tc_get_cycles(void)
 +{
 + unsigned long   flags;
 + u32 lower, upper;
 +
 + raw_local_irq_save(flags);

Why do you need to use the raw version?

 +retry:
 + upper = __raw_readl(tcaddr + ATMEL_TC_REG(1, CV));
 + lower = __raw_readl(tcaddr + ATMEL_TC_REG(0, CV));
 + if (upper != __raw_readl(tcaddr + ATMEL_TC_REG(1, CV)))
 + goto retry;

Did you just open-code a do/while loop using goto? ;-)

 +#ifdef CONFIG_GENERIC_CLOCKEVENTS
 +#define USE_TC_CLKEVT
 +#endif
 +
 +#ifdef CONFIG_ARCH_AT91RM9200
 +/* The AT91rm9200 system timer is a oneshot-capable 32k timer that's
 + * always running ... configuring a TC channel to work the same way
 + * would just waste some power.
 + */
 +#undef USE_TC_CLKEVT
 +#endif
 +
 +#ifdef USE_TC_CLKEVT

Can't you just use #ifndef CONFIG_ARCH_AT91RM9200 and avoid the whole
ifdef/define/undef dance above?

 + case CLOCK_EVT_MODE_ONESHOT:
 + /* slow clock, count up to RC, then irq and stop */

Hmm. Do you really want to stop it? Won't you get better accuracy if
you let it run and program the next event as (prev_event + delta)?

 +static struct irqaction tc_irqaction = {
 + .name   = tc_clkevt,
 + .flags  = IRQF_TIMER | IRQF_DISABLED,
 + .handler= ch2_irq,
 +};

I don't think you need to define this statically. You can call
request_irq() at arch_initcall() time.

 +static void __init setup_clkevents(struct platform_device *pdev,
 + struct clk *t0_clk, int clk32k_divisor_idx)
 +{
 + struct clk  *t2_clk = clk_get(pdev-dev, t2_clk);
 + int irq;
 +
 + /* SOCs have either one IRQ and one clock for the whole
 +  * TC block; or one each per channel.  We use channel 2.
 +  */
 + if (IS_ERR(t2_clk)) {
 + t2_clk = t0_clk;
 + irq = platform_get_irq(pdev, 0);
 + } else {
 + irq = platform_get_irq(pdev, 2);
 + clk_enable(t2_clk);
 + }

I don't think it is safe to assume that one clock per channel always
means one irq per channel as well...

What's wrong with

irq = platform_get_irq(pdev, 2);
if (irq  0)
irq = platform_get_irq(pdev, 0);

?

 +config ATMEL_TCB_CLKSRC
 + bool TC Block Clocksource
 + depends on ATMEL_TCLIB  GENERIC_TIME
 + default y
 + help
 +   Select this to get a high precision clocksource based on a
 +   TC block with a 5+ MHz base clock rate.  Two timer channels
 +   are combined to make a single 32-bit timer.
 +
 +   When GENERIC_CLOCKEVENTS is defined, the third timer channel
 +   may be used as a clock event device supporting oneshot mode
 +   (delays of up to two seconds) based on the 32 KiHz clock.
 +
 +config ATMEL_TCB_CLKSRC_BLOCK
 + int
 + depends on ATMEL_TCB_CLKSRC
 + prompt TC Block if ARCH_AT91RM9200 || ARCH_AT91SAM9260 || 
 CPU_AT32AP700X
 + default 0
 + range 0 1

Hmm...I don't like the direction this is going...

How about we make tcb_clksrc_init() global and call it from the
platform code with whatever TCB the platform thinks is appropriate?

Perhaps remove the prompt from ATMEL_TCB_CLKSRC and have the platform
select it as well? I certainly want to force this stuff on on the
AP7000...otherwise we'll just get lots of complaints that the thing is
using 4x more power than it's supposed to...

Haavard
--
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 2.6.25-rc2-git 2/2] atmel_tc clocksource/clockevent code

2008-02-24 Thread David Brownell
 Again, sorry for the delay...it really sucks that I haven't been able
 to look at this stuff closely until now. Hopefully a late review is
 better than no review.

Yes.  The review I've gotten so far has been of the it works for me,
thanks variety.

(The only issue reported to me is that NO_HZ on AT91 seems to make the
DBGU lose characters sometimes ... that one-byte fifo makes trouble
whenever there's the slightest delay in IRQ handling, and NO_HZ can
easily add such delays as part of ensuring that jiffies is current
before invoking handlers.)


 On Fri, 22 Feb 2008 17:28:37 -0800
 David Brownell [EMAIL PROTECTED] wrote:

  +static cycle_t tc_get_cycles(void)
  +{
  +   unsigned long   flags;
  +   u32 lower, upper;
  +
  +   raw_local_irq_save(flags);

 Why do you need to use the raw version?

This is part of the system timer code, and it should never be a
preemption point.  Plus I didn't want to waste any instruction
cycles in code that runs before e.g. the DBGU IRQ handler would
get called... observably, such extra cycles *do* hurt.


  +retry:
  +   upper = __raw_readl(tcaddr + ATMEL_TC_REG(1, CV));
  +   lower = __raw_readl(tcaddr + ATMEL_TC_REG(0, CV));
  +   if (upper != __raw_readl(tcaddr + ATMEL_TC_REG(1, CV)))
  +   goto retry;

 Did you just open-code a do/while loop using goto? ;-)

I take that back about late review being better than none.  ;)


  +#ifdef CONFIG_GENERIC_CLOCKEVENTS
  +#define USE_TC_CLKEVT
  +#endif
  +
  +#ifdef CONFIG_ARCH_AT91RM9200
  +/* The AT91rm9200 system timer is a oneshot-capable 32k timer that's
  + * always running ... configuring a TC channel to work the same way
  + * would just waste some power.
  + */
  +#undef USE_TC_CLKEVT
  +#endif
  +
  +#ifdef USE_TC_CLKEVT

 Can't you just use #ifndef CONFIG_ARCH_AT91RM9200 and avoid the whole
 ifdef/define/undef dance above?

I can't know that some other platform won't have a better system
timer solution, and didn't want to assume that only that single
venerable chip had such a solution ... it's kind of puzzling to
me (software guy) that none of the newest Atmel SOCs have better
timer infrastructure than they do.  ;)


  +   case CLOCK_EVT_MODE_ONESHOT:
  +   /* slow clock, count up to RC, then irq and stop */

 Hmm. Do you really want to stop it? Won't you get better accuracy if
 you let it run and program the next event as (prev_event + delta)?

No, ONESHOT means stop after the IRQ I asked for.  And when
tc_next_event() is asked to trigger that IRQ, it's relative to
the instant it's requested, not relative to the last one that
was requested (which may not have triggered yet, or may have
been quite some time ago).


  +static struct irqaction tc_irqaction = {
  +   .name   = tc_clkevt,
  +   .flags  = IRQF_TIMER | IRQF_DISABLED,
  +   .handler= ch2_irq,
  +};

 I don't think you need to define this statically. You can call
 request_irq() at arch_initcall() time.

That could be done, yes ... and using request_irq()/free_irq()
would also let this be linked as a module, not just statically.

On the other hand, doing it this way doesn't hurt either does it?
Unless a modular build is important.


  +static void __init setup_clkevents(struct platform_device *pdev,
  +   struct clk *t0_clk, int clk32k_divisor_idx)
  +{
  +   struct clk  *t2_clk = clk_get(pdev-dev, t2_clk);
  +   int irq;
  +
  +   /* SOCs have either one IRQ and one clock for the whole
  +* TC block; or one each per channel.  We use channel 2.
  +*/
  +   if (IS_ERR(t2_clk)) {
  +   t2_clk = t0_clk;
  +   irq = platform_get_irq(pdev, 0);
  +   } else {
  +   irq = platform_get_irq(pdev, 2);
  +   clk_enable(t2_clk);
  +   }

 I don't think it is safe to assume that one clock per channel always
 means one irq per channel as well...

On current chips, that's how it works.


 What's wrong with

   irq = platform_get_irq(pdev, 2);
   if (irq  0)
   irq = platform_get_irq(pdev, 0);

Nothing much, except that I took the more concise path.  Got patch?


  +config ATMEL_TCB_CLKSRC
  +   bool TC Block Clocksource
  +   depends on ATMEL_TCLIB  GENERIC_TIME
  +   default y
  +   help
  + Select this to get a high precision clocksource based on a
  + TC block with a 5+ MHz base clock rate.  Two timer channels
  + are combined to make a single 32-bit timer.
  +
  + When GENERIC_CLOCKEVENTS is defined, the third timer channel
  + may be used as a clock event device supporting oneshot mode
  + (delays of up to two seconds) based on the 32 KiHz clock.
  +
  +config ATMEL_TCB_CLKSRC_BLOCK
  +   int
  +   depends on ATMEL_TCB_CLKSRC
  +   prompt TC Block if ARCH_AT91RM9200 || ARCH_AT91SAM9260 || 
  CPU_AT32AP700X
  +   default 0
  +   range 0 1

 Hmm...I don't like the direction this is going...

 How about we make tcb_clksrc_init() global and call it from the
 platform code with whatever TCB the platform thinks is 

[patch 2.6.25-rc2-git 2/2] atmel_tc clocksource/clockevent code

2008-02-22 Thread David Brownell
Clocksource and clockevent device based on the Atmel TC blocks.

The clockevent device handles both periodic and oneshot modes, so this
enables NO_HZ and high res timers on some platforms that previously
couldn't use those mechanisms.

This works on both AVR32 and AT91 chips, given relevant patches for
tclib support (always) and clockevents (or else this will only look
like a higher precision clocksource).  It's an updated and modularized
version of an AT91-only patch that has circulated for some time now.

Signed-off-by: David Brownell <[EMAIL PROTECTED]>
---
As with the preceding patch, this depends on platform updates that
won't merge before 2.6.26 ... in this case, updates to switch over
to clocksources (at91sam9 chips, but not at91rm9200) and clockevents
(avr32 and at91sam9), on top of platform_device setup.

 drivers/clocksource/Makefile |1 
 drivers/clocksource/tcb_clksrc.c |  303 +++
 drivers/misc/Kconfig |   25 +++
 3 files changed, 329 insertions(+)

--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_clksrc.o
 obj-$(CONFIG_X86_CYCLONE_TIMER)+= cyclone.o
 obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o
 obj-$(CONFIG_SCx200HR_TIMER)   += scx200_hrt.o
--- /dev/null
+++ b/drivers/clocksource/tcb_clksrc.c
@@ -0,0 +1,303 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+
+/*
+ * We're configured to use a specific TC block, one that's not hooked
+ * up to external hardware, to provide a time solution:
+ *
+ *   - Two channels combine to create a free-running 32 bit counter
+ * with a base rate of 5+ MHz, packaged as a clocksource (with
+ * resolution better than 200 nsec).
+ *
+ *   - The third channel may be used to provide a 16-bit clockevent
+ * source, used in either periodic or oneshot mode.  This runs
+ * at 32 KiHZ, and can handle delays of up to two seconds.
+ *
+ * A boot clocksource and clockevent source are also currently needed,
+ * unless the relevant platforms (ARM/AT91, AVR32/AT32) are changed so
+ * this code can be used when init_timers() is called, well before most
+ * devices are set up.  (Some low end AT91 parts, which can run uClinux,
+ * have only the timers in one TC block... they currently don't support
+ * the tclib code, because of that initialization issue.)
+ *
+ * REVISIT behavior during system suspend states... we should disable
+ * all clocks and save the power.  Easily done for clockevent devices,
+ * but clocksources won't necessarily get the needed notifications.
+ * For deeper system sleep states, this will be mandatory...
+ */
+
+static void __iomem *tcaddr;
+
+static cycle_t tc_get_cycles(void)
+{
+   unsigned long   flags;
+   u32 lower, upper;
+
+   raw_local_irq_save(flags);
+retry:
+   upper = __raw_readl(tcaddr + ATMEL_TC_REG(1, CV));
+   lower = __raw_readl(tcaddr + ATMEL_TC_REG(0, CV));
+   if (upper != __raw_readl(tcaddr + ATMEL_TC_REG(1, CV)))
+   goto retry;
+
+   raw_local_irq_restore(flags);
+   return (upper << 16) | lower;
+}
+
+static struct clocksource clksrc = {
+   .name   = "tcb_clksrc",
+   .rating = 200,
+   .read   = tc_get_cycles,
+   .mask   = CLOCKSOURCE_MASK(32),
+   .shift  = 18,
+   .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+#ifdef CONFIG_GENERIC_CLOCKEVENTS
+#define USE_TC_CLKEVT
+#endif
+
+#ifdef CONFIG_ARCH_AT91RM9200
+/* The AT91rm9200 system timer is a oneshot-capable 32k timer that's
+ * always running ... configuring a TC channel to work the same way
+ * would just waste some power.
+ */
+#undef USE_TC_CLKEVT
+#endif
+
+#ifdef USE_TC_CLKEVT
+
+/* For now, we always use the 32K clock ... this optimizes for NO_HZ,
+ * because using one of the divided clocks would usually mean the
+ * tick rate can never be less than several dozen Hz (vs 0.5 Hz).
+ *
+ * A divided clock could be good for high resolution timers, since
+ * 30.5 usec resolution can seem "low".
+ */
+static u32 timer_clock;
+
+static void tc_mode(enum clock_event_mode m, struct clock_event_device *d)
+{
+   __raw_writel(0xff, tcaddr + ATMEL_TC_REG(2, IDR));
+   __raw_writel(ATMEL_TC_CLKDIS, tcaddr + ATMEL_TC_REG(2, CCR));
+
+   switch (m) {
+
+   /* By not making the gentime core emulate periodic mode on top
+* of oneshot, we get lower overhead and improved accuracy.
+*/
+   case CLOCK_EVT_MODE_PERIODIC:
+   /* slow clock, count up to RC, then irq and restart */
+   __raw_writel(timer_clock
+   | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO,
+   tcaddr + ATMEL_TC_REG(2, CMR));
+   __raw_writel((32768 + HZ/2) / HZ, tcaddr + ATMEL_TC_REG(2, RC));
+
+   /* Enable clock and interrupts on RC 

[patch 2.6.25-rc2-git 2/2] atmel_tc clocksource/clockevent code

2008-02-22 Thread David Brownell
Clocksource and clockevent device based on the Atmel TC blocks.

The clockevent device handles both periodic and oneshot modes, so this
enables NO_HZ and high res timers on some platforms that previously
couldn't use those mechanisms.

This works on both AVR32 and AT91 chips, given relevant patches for
tclib support (always) and clockevents (or else this will only look
like a higher precision clocksource).  It's an updated and modularized
version of an AT91-only patch that has circulated for some time now.

Signed-off-by: David Brownell [EMAIL PROTECTED]
---
As with the preceding patch, this depends on platform updates that
won't merge before 2.6.26 ... in this case, updates to switch over
to clocksources (at91sam9 chips, but not at91rm9200) and clockevents
(avr32 and at91sam9), on top of platform_device setup.

 drivers/clocksource/Makefile |1 
 drivers/clocksource/tcb_clksrc.c |  303 +++
 drivers/misc/Kconfig |   25 +++
 3 files changed, 329 insertions(+)

--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_clksrc.o
 obj-$(CONFIG_X86_CYCLONE_TIMER)+= cyclone.o
 obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o
 obj-$(CONFIG_SCx200HR_TIMER)   += scx200_hrt.o
--- /dev/null
+++ b/drivers/clocksource/tcb_clksrc.c
@@ -0,0 +1,303 @@
+#include linux/init.h
+#include linux/clocksource.h
+#include linux/clockchips.h
+#include linux/interrupt.h
+#include linux/irq.h
+
+#include linux/clk.h
+#include linux/err.h
+#include linux/ioport.h
+#include linux/io.h
+#include linux/platform_device.h
+#include linux/atmel_tc.h
+
+
+/*
+ * We're configured to use a specific TC block, one that's not hooked
+ * up to external hardware, to provide a time solution:
+ *
+ *   - Two channels combine to create a free-running 32 bit counter
+ * with a base rate of 5+ MHz, packaged as a clocksource (with
+ * resolution better than 200 nsec).
+ *
+ *   - The third channel may be used to provide a 16-bit clockevent
+ * source, used in either periodic or oneshot mode.  This runs
+ * at 32 KiHZ, and can handle delays of up to two seconds.
+ *
+ * A boot clocksource and clockevent source are also currently needed,
+ * unless the relevant platforms (ARM/AT91, AVR32/AT32) are changed so
+ * this code can be used when init_timers() is called, well before most
+ * devices are set up.  (Some low end AT91 parts, which can run uClinux,
+ * have only the timers in one TC block... they currently don't support
+ * the tclib code, because of that initialization issue.)
+ *
+ * REVISIT behavior during system suspend states... we should disable
+ * all clocks and save the power.  Easily done for clockevent devices,
+ * but clocksources won't necessarily get the needed notifications.
+ * For deeper system sleep states, this will be mandatory...
+ */
+
+static void __iomem *tcaddr;
+
+static cycle_t tc_get_cycles(void)
+{
+   unsigned long   flags;
+   u32 lower, upper;
+
+   raw_local_irq_save(flags);
+retry:
+   upper = __raw_readl(tcaddr + ATMEL_TC_REG(1, CV));
+   lower = __raw_readl(tcaddr + ATMEL_TC_REG(0, CV));
+   if (upper != __raw_readl(tcaddr + ATMEL_TC_REG(1, CV)))
+   goto retry;
+
+   raw_local_irq_restore(flags);
+   return (upper  16) | lower;
+}
+
+static struct clocksource clksrc = {
+   .name   = tcb_clksrc,
+   .rating = 200,
+   .read   = tc_get_cycles,
+   .mask   = CLOCKSOURCE_MASK(32),
+   .shift  = 18,
+   .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+#ifdef CONFIG_GENERIC_CLOCKEVENTS
+#define USE_TC_CLKEVT
+#endif
+
+#ifdef CONFIG_ARCH_AT91RM9200
+/* The AT91rm9200 system timer is a oneshot-capable 32k timer that's
+ * always running ... configuring a TC channel to work the same way
+ * would just waste some power.
+ */
+#undef USE_TC_CLKEVT
+#endif
+
+#ifdef USE_TC_CLKEVT
+
+/* For now, we always use the 32K clock ... this optimizes for NO_HZ,
+ * because using one of the divided clocks would usually mean the
+ * tick rate can never be less than several dozen Hz (vs 0.5 Hz).
+ *
+ * A divided clock could be good for high resolution timers, since
+ * 30.5 usec resolution can seem low.
+ */
+static u32 timer_clock;
+
+static void tc_mode(enum clock_event_mode m, struct clock_event_device *d)
+{
+   __raw_writel(0xff, tcaddr + ATMEL_TC_REG(2, IDR));
+   __raw_writel(ATMEL_TC_CLKDIS, tcaddr + ATMEL_TC_REG(2, CCR));
+
+   switch (m) {
+
+   /* By not making the gentime core emulate periodic mode on top
+* of oneshot, we get lower overhead and improved accuracy.
+*/
+   case CLOCK_EVT_MODE_PERIODIC:
+   /* slow clock, count up to RC, then irq and restart */
+   __raw_writel(timer_clock
+   | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO,
+   tcaddr +