From: Thomas Gleixner <tglx@linutronix.de>
To: liqin.chen@sunplusct.com
Cc: linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org,
Arnd Bergmann <arnd@arndb.de>,
Andrew Morton <akpm@linux-foundation.org>,
torvalds@linux-foundation.org
Subject: Re: [PATCH 22/27] score: create kernel files signal.c sys_score.c time.c
Date: Tue, 9 Jun 2009 10:51:13 +0200 (CEST) [thread overview]
Message-ID: <alpine.LFD.2.00.0906091028020.3351@localhost.localdomain> (raw)
In-Reply-To: <OF32AB4A20.4574C065-ON482575D0.00243CB1-482575D0.0024AD26@sunplusct.com>
Chen,
On Tue, 9 Jun 2009, liqin.chen@sunplusct.com wrote:
> +static struct irqaction timer_irq = {
> + .handler = timer_interrupt,
> + .flags = IRQF_DISABLED | IRQF_TIMER,
> + .mask = CPU_MASK_NONE,
> + .name = "timer",
> +};
> +
> +static int comparator_next_event(unsigned long delta,
> + struct clock_event_device *evdev)
> +{
> + unsigned long flags;
> +
> + raw_local_irq_save(flags);
This function is always called with interrupts disabled.
> + __raw_writel((TMR_M_PERIODIC | TMR_IE_ENABLE), (void *)P_TIMER0_CTRL);
Can you please move the type cast to the define or better have a:
static const __iomem void *timer_ctrl = .....;
somehwere at the top of the file/
> + __raw_writel(delta, (void *)P_TIMER0_PRELOAD);
> + __raw_writel(__raw_readl((void *)P_TIMER0_CTRL) | TMR_ENABLE,
> + (void *)P_TIMER0_CTRL);
> +
> + raw_local_irq_restore(flags);
> +
> + return 0;
> +}
> +
> +static void comparator_mode(enum clock_event_mode mode,
> + struct clock_event_device *evdev)
> +{
> + unsigned long flags;
> +
> + switch (mode) {
> + case CLOCK_EVT_MODE_PERIODIC:
> + raw_local_irq_save(flags);
This function is also called with interrupts disabled.
> + __raw_writel((TMR_M_PERIODIC | TMR_IE_ENABLE),
> + (void *)P_TIMER0_CTRL);
> + __raw_writel(SYSTEM_CLOCK/100, (void *)P_TIMER0_PRELOAD);
shouldn't 100 be replaced by HZ ?
> + __raw_writel(__raw_readl((void *)P_TIMER0_CTRL) |
> TMR_ENABLE,
> + (void *)P_TIMER0_CTRL);
> + raw_local_irq_restore(flags);
> + break;
> + case CLOCK_EVT_MODE_ONESHOT:
> + case CLOCK_EVT_MODE_RESUME:
> + case CLOCK_EVT_MODE_UNUSED:
> + case CLOCK_EVT_MODE_SHUTDOWN:
> + break;
> + default:
> + BUG();
> + }
> +}
> +
> +static struct clock_event_device comparator = {
> + .name = "avr32_comparator",
> + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
> + .shift = 16,
> + .set_next_event = comparator_next_event,
> + .set_mode = comparator_mode,
> +};
> +
> +static u32 score_tick_cnt;
> +
> +static cycle_t score_read_clk(struct clocksource *cs)
> +{
> + unsigned long flags;
> +
> + local_irq_save(flags);
> + score_tick_cnt += SYSTEM_CLOCK/100;
> + local_irq_restore(flags);
How is that supposed to work ? read_clk() is called from various
places in the kernel and you seem to add some constant value to it
on every call. That can not work at all. You need a counter which
is incrementing at a constant rate and can be read out.
If you do not have a continous counter then you should not provide a
clock source. The generic code will then provide the jiffies clock
source. In that case you need to disable the oneshot mode of your
clock event device as well.
> +
> + return score_tick_cnt;
> +}
> +
> +static struct clocksource score_clk = {
> + .name = "timer",
> + .rating = 250,
> + .read = score_read_clk,
> + .shift = 20,
> + .mask = CLOCKSOURCE_MASK(32),
> + .flags = CLOCK_SOURCE_IS_CONTINUOUS,
yeah, continuously wrong :)
> +};
> +
> +void __init time_init(void)
> +{
> + xtime.tv_sec = mktime(2009, 1, 1, 0, 0, 0);
> + xtime.tv_nsec = 0;
> +
> + set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec,
> + -xtime.tv_nsec);
xtime setup is done in the generic time keeping code already. Please
remove.
> + /* disable timer, timer interrupt enable */
> + __raw_writel((TMR_M_PERIODIC | TMR_IE_ENABLE), (void
> *)P_TIMER0_CTRL);
> + __raw_writel(SYSTEM_CLOCK/100, (void *)P_TIMER0_PRELOAD); /* 10ms
> */
> +
> + /* start timer */
> + __raw_writel(__raw_readl((void *)P_TIMER0_CTRL) | TMR_ENABLE,
> + (void *)P_TIMER0_CTRL);
No need to start the timer here. When you register your clock event
device the set_mode function is called and the timer is started.
Your implementation is not going to work at all.
A clock event device is a device which delivers either periodic or
one shot interrupts. It is registered with the generic clockevents
layer which takes care of setting up the device via the set_mode
call back.
The clock source device is a device which provides a monotonic
increasing counter which can wrap around at some point. The wrap
around point has to be power of 2 and is defined via the .mask
member of the clock source device structure. The generic time
keeping code takes care of the conversion to nsec based time and
handles NTP and other adjustments.
So in practice you need either two hardware devices (counter and
interrupt generator) or a device which has a monotonic increasing
counter and a match register which generates an interrupt when the
counter value and the match register are the same.
Thanks,
tglx
next prev parent reply other threads:[~2009-06-09 8:52 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-06-09 6:36 [PATCH 22/27] score: create kernel files signal.c sys_score.c time.c liqin.chen
2009-06-09 8:51 ` Thomas Gleixner [this message]
2009-06-13 6:26 ` liqin.chen
2009-06-13 6:26 ` liqin.chen
2009-06-09 17:52 ` Arnd Bergmann
2009-06-09 17:52 ` Arnd Bergmann
2009-06-13 6:43 ` liqin.chen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=alpine.LFD.2.00.0906091028020.3351@localhost.localdomain \
--to=tglx@linutronix.de \
--cc=akpm@linux-foundation.org \
--cc=arnd@arndb.de \
--cc=linux-arch@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=liqin.chen@sunplusct.com \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox