On Mon, 22 Oct 2007 19:43:15 +0900, Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
wrote:
> +static int gt641xx_timer0_set_next_event(unsigned long delta,
> + struct clock_event_device *evt)
> +{
> + unsigned long flags;
> + u32 ctrl;
> +
> + spin_lock_irqsave(>641xx_timer_lock, flags);
> +
> + ctrl = GT_READ(GT_TC_CONTROL_OFS);
> + ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK);
> + ctrl |= GT_TC_CONTROL_ENTC0_MSK;
> +
> + GT_WRITE(GT_TC0_OFS, delta);
> + GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
> +
> + spin_unlock_irqrestore(>641xx_timer_lock, flags);
> +
> + return 0;
> +}
> +
> +static void gt641xx_timer0_set_mode(enum clock_event_mode mode,
> + struct clock_event_device *evt)
> +{
> + unsigned long flags;
> + u32 ctrl;
> +
> + spin_lock_irqsave(>641xx_timer_lock, flags);
> +
> + ctrl = GT_READ(GT_TC_CONTROL_OFS);
> + ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK);
> +
> + switch (mode) {
> + case CLOCK_EVT_MODE_PERIODIC:
> + ctrl |= GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK;
> + break;
> + case CLOCK_EVT_MODE_ONESHOT:
> + ctrl |= GT_TC_CONTROL_ENTC0_MSK;
> + break;
> + default:
> + break;
> + }
> +
> + GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
> +
> + spin_unlock_irqrestore(>641xx_timer_lock, flags);
> +}
These clockevent routines are always called with interrupt disabled,
so I suppose those spin_lock_irqsave/spin_unlock_irqrestore pairs can
be omitted. (or this timer can be used on SMP?)
> + cd = >641xx_timer0_clockevent;
> + cd->rating = 200 + gt641xx_base_clock / 10000000;
> + cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
> + cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
> + clockevent_set_clock(cd, gt641xx_base_clock);
clockevent_delta2ns() use shift and mult value. So you should call
clockevent_set_clock() first.
---
Atsushi Nemoto
|