diff mbox

dw_apb_timer_of.c: remove parts that were picoxcell-specific

Message ID 20130507201126.GA8169@amd.pavel.ucw.cz (mailing list archive)
State New, archived
Headers show

Commit Message

Pavel Machek May 7, 2013, 8:11 p.m. UTC
Hi!

> >>>So I guess it should go through the timekeeping tree...?
> >>I would prefer that, but we can also take it through arm-soc, it doesn't
> >>really matter.
> >I see no response from timekeeping people... so if you could take it,
> >that would be great.
> 
> I don't think the original patch ever made it to my inbox.

For some reason, I cced johnstul@us.ibm.com. (I guess
get_maintainer.pl? But it seems to behave now.) Anyway, patch is
below...

It would be great if you could apply it... Thanks,
							Pavel

----

It seems we made a mistake when creating dw_apb_timer_of.c:
picoxcell sched_clock had parts that were not related to
dw_apb_timer, yet we moved them to dw_apb_timer_of, and tried to
use them on socfpga.

This results in system where user/system time is not measured
properly, as demonstrated by
    
    time dd if=/dev/urandom of=/dev/zero bs=100000 count=100
    
So this patch switches sched_clock to hardware that exists on both
platforms, and adds missing of_node_put() in dw_apb_timer_init().
    
Signed-off-by: Pavel Machek <pavel@denx.de>
Acked-by: Jamie Iles <jamie@jamieiles.com>

Comments

John Stultz May 8, 2013, 12:30 a.m. UTC | #1
On 05/07/2013 01:11 PM, Pavel Machek wrote:
> It seems we made a mistake when creating dw_apb_timer_of.c:
> picoxcell sched_clock had parts that were not related to
> dw_apb_timer, yet we moved them to dw_apb_timer_of, and tried to
> use them on socfpga.
>
> This results in system where user/system time is not measured
> properly, as demonstrated by
>      
>      time dd if=/dev/urandom of=/dev/zero bs=100000 count=100
>      
> So this patch switches sched_clock to hardware that exists on both
> platforms, and adds missing of_node_put() in dw_apb_timer_init().
>      
> Signed-off-by: Pavel Machek <pavel@denx.de>
> Acked-by: Jamie Iles <jamie@jamieiles.com>

Ok. I'm still not a happy about the general issue of 
sched_clock/clockevent code being in drivers/clocksources (I know, 
everyone is sick of my griping about it :), so reviewing this sucks, but 
at least this patch technically isn't making that issue worse.

Additionally, this is an *ugly* driver in my opinion. Its split between 
arch specific logic in arch/x86/kernel/apb_timer.c, 
arch/arm/mach-picoxcell/common.c, and arch/arm/mach-socfpga/socfpga.c, 
and then arch independent logic in drivers/clocksource/dw_apb_timer.c 
and drivers/clocksource/dw_apb_timer_of.c, but then it seems like much 
of drivers/clocksource/dw_apb_timer_of.c is actually ARM specific.

Are there any plans to clean this up in the future?

Also, next time please run checkpatch.pl to catch trivial issues like 
trailing whitespace. :P

But I've gone ahead and queued this for 3.11.

thanks
-john
Pavel Machek May 10, 2013, 12:38 p.m. UTC | #2
On Tue 2013-05-07 17:30:52, John Stultz wrote:
> On 05/07/2013 01:11 PM, Pavel Machek wrote:
> >It seems we made a mistake when creating dw_apb_timer_of.c:
> >picoxcell sched_clock had parts that were not related to
> >dw_apb_timer, yet we moved them to dw_apb_timer_of, and tried to
> >use them on socfpga.
> >
> >This results in system where user/system time is not measured
> >properly, as demonstrated by
> >     time dd if=/dev/urandom of=/dev/zero bs=100000 count=100
> >So this patch switches sched_clock to hardware that exists on both
> >platforms, and adds missing of_node_put() in dw_apb_timer_init().
> >Signed-off-by: Pavel Machek <pavel@denx.de>
> >Acked-by: Jamie Iles <jamie@jamieiles.com>
> 
> Ok. I'm still not a happy about the general issue of
> sched_clock/clockevent code being in drivers/clocksources (I know,
> everyone is sick of my griping about it :), so reviewing this sucks,
> but at least this patch technically isn't making that issue worse.

Is there anything concrete you'd like to improve?

Yes, clocksource/clockevent split is confusing, doubly so because it
is same hardware driving both. Would it make sense to create "use this
clocksource for sched_clock()" helper?

> Additionally, this is an *ugly* driver in my opinion. Its split
> between arch specific logic in arch/x86/kernel/apb_timer.c,
> arch/arm/mach-picoxcell/common.c, and
> arch/arm/mach-socfpga/socfpga.c, and 

Can you elaborate? There's very little logic in socfpga.c, just single
line

        .timer          = &dw_apb_timer,

> then arch independent logic in
> drivers/clocksource/dw_apb_timer.c and
> drivers/clocksource/dw_apb_timer_of.c, but then it seems like much
> of drivers/clocksource/dw_apb_timer_of.c is actually ARM specific.

dw_apb_timer_of.c ... it should not be arm specific. Yes, it was
originally separated from picoxcell code, and so far only picoxcell &
socfpga use it, but it should work on other architectures, too..

> Are there any plans to clean this up in the future?

I can try, but I'd need a bit better idea what needs to be done. Would
"use this clocksource for sched_clock()" helper be acceptable?

> But I've gone ahead and queued this for 3.11.

Thanks!
								Pavel
diff mbox

Patch

diff --git a/arch/arm/mach-picoxcell/common.h b/arch/arm/mach-picoxcell/common.h
index 481b42a..237fb3b 100644
--- a/arch/arm/mach-picoxcell/common.h
+++ b/arch/arm/mach-picoxcell/common.h
@@ -12,6 +12,4 @@ 
 
 #include <asm/mach/time.h>
 
-extern void dw_apb_timer_init(void);
-
 #endif /* __PICOXCELL_COMMON_H__ */
diff --git a/drivers/clocksource/dw_apb_timer.c b/drivers/clocksource/dw_apb_timer.c
index 8c2a35f..460ac99 100644
--- a/drivers/clocksource/dw_apb_timer.c
+++ b/drivers/clocksource/dw_apb_timer.c
@@ -21,12 +21,6 @@ 
 #define APBT_MIN_PERIOD			4
 #define APBT_MIN_DELTA_USEC		200
 
-#define APBTMR_N_LOAD_COUNT		0x00
-#define APBTMR_N_CURRENT_VALUE		0x04
-#define APBTMR_N_CONTROL		0x08
-#define APBTMR_N_EOI			0x0c
-#define APBTMR_N_INT_STATUS		0x10
-
 #define APBTMRS_INT_STATUS		0xa0
 #define APBTMRS_EOI			0xa4
 #define APBTMRS_RAW_INT_STATUS		0xa8
diff --git a/drivers/clocksource/dw_apb_timer_of.c b/drivers/clocksource/dw_apb_timer_of.c
index ab09ed3..0fa3104 100644
--- a/drivers/clocksource/dw_apb_timer_of.c
+++ b/drivers/clocksource/dw_apb_timer_of.c
@@ -57,6 +57,15 @@  static void add_clockevent(struct device_node *event_timer)
 	dw_apb_clockevent_register(ced);
 }
 
+static void __iomem *sched_io_base;
+
+/* This is actually same as __apbt_read_clocksource(), but with
+   different interface */
+static u32 read_sched_clock_sptimer(void)
+{
+	return ~__raw_readl(sched_io_base + APBTMR_N_CURRENT_VALUE);
+}
+
 static void add_clocksource(struct device_node *source_timer)
 {
 	void __iomem *iobase;
@@ -71,41 +80,27 @@  static void add_clocksource(struct device_node *source_timer)
 
 	dw_apb_clocksource_start(cs);
 	dw_apb_clocksource_register(cs);
-}
 
-static void __iomem *sched_io_base;
-
-static u32 read_sched_clock(void)
-{
-	return __raw_readl(sched_io_base);
+	sched_io_base = iobase;
+	setup_sched_clock(read_sched_clock_sptimer, 32, rate);
 }
 
-static const struct of_device_id sptimer_ids[] __initconst = {
-	{ .compatible = "picochip,pc3x2-rtc" },
+static const struct of_device_id osctimer_ids[] __initconst = {
+	{ .compatible = "picochip,pc3x2-timer" },
+	{ .compatible = "snps,dw-apb-timer-osc" },
 	{ .compatible = "snps,dw-apb-timer-sp" },
-	{ /* Sentinel */ },
+	{  /* Sentinel */ },
 };
 
-static void init_sched_clock(void)
-{
-	struct device_node *sched_timer;
-	u32 rate;
-
-	sched_timer = of_find_matching_node(NULL, sptimer_ids);
-	if (!sched_timer)
-		panic("No RTC for sched clock to use");
+/*
+   You don't have to use dw_apb_timer for scheduler clock,
+   this should also work fine on arm:
 
-	timer_get_base_and_rate(sched_timer, &sched_io_base, &rate);
-	of_node_put(sched_timer);
+  twd_local_timer_of_register();
+  arch_timer_of_register();                 
+  arch_timer_sched_clock_init();
+*/
 
-	setup_sched_clock(read_sched_clock, 32, rate);
-}
-
-static const struct of_device_id osctimer_ids[] __initconst = {
-	{ .compatible = "picochip,pc3x2-timer" },
-	{ .compatible = "snps,dw-apb-timer-osc" },
-	{},
-};
 
 void __init dw_apb_timer_init(void)
 {
@@ -121,7 +116,6 @@  void __init dw_apb_timer_init(void)
 		panic("No timer for clocksource");
 	add_clocksource(source_timer);
 
+	of_node_put(event_timer);
 	of_node_put(source_timer);
-
-	init_sched_clock();
 }
diff --git a/include/linux/dw_apb_timer.h b/include/linux/dw_apb_timer.h
index dd755ce..a64c987 100644
--- a/include/linux/dw_apb_timer.h
+++ b/include/linux/dw_apb_timer.h
@@ -17,6 +17,12 @@ 
 #include <linux/clocksource.h>
 #include <linux/interrupt.h>
 
+#define APBTMR_N_LOAD_COUNT		0x00
+#define APBTMR_N_CURRENT_VALUE		0x04
+#define APBTMR_N_CONTROL		0x08
+#define APBTMR_N_EOI			0x0c
+#define APBTMR_N_INT_STATUS		0x10
+
 #define APBTMRS_REG_SIZE       0x14
 
 struct dw_apb_timer {