2009-04-15 01:32:57

by john stultz

[permalink] [raw]
Subject: [RESEND][PATCH 0/2] Convert acked !GENERIC_TIME architectures to use the generic timekeeping core.

Andrew, All,

Its been two and a half years since the GENERIC_TIME infrastructure
landed. It allowed architectures that have free running counters to only
have to provide a clocksource driver and leave the rest of the
timekeeping management to generic code.

So far out of the 23 architectures we've fully converted 15 of them over
to GENERIC_TIME. The remaining 8 (alpha, arm, blackfin, cris, m32r,
m68k, sh, sparc) have in some cases been able to convert, but not fully.
The issue that keeps most architectures from converting is that they do
not have free running counters. They instead use the counter on their
tick timer to determine their inter-tick time. This counter usually
wraps every interrupt, so its not really efficient to use as a
clocksource.

This has created some difficulty as the generic timekeeping core has had
to deal with both GENERIC_TIME arches as well as !GENERIC_TIME arches,
and since it didn't manage 100% of the calculation in the !GENERIC_TIME
case, we've been limited in some of the changes we could make.

So since these last remaining architectures are unlikely to be able to
fully convert to GENERIC_TIME as it stands, the generic core should try
to adopt to their needs so we can bring them into the fold and reduce
code duplication.

The solution is to provide a arch callout from the generic timekeeping
core: arch_gettimeoffset(). On architectures that do not provide a
clocksource, the jiffies clocksource is used, and arch_gettimeoffset is
added in to create finer grained inter-tick time.


The patchset I'm submitting for -mm does the following:
1) Introduces the arch_gettimeoffset infrastructure to the timekeeping
core.
2) Converts Acked arch (sh) to use the arch_gettimeoffset()hook.

The sparc arch was earlier acked, but I found some complications when
cross-compile testing it, so I'll be reworking it and requesting a new
ack later.

I still have patches for the 6 other arches that need to be converted,
but have not received acks for them yet. Instead of stalling the
patchset for all of those arches, I'm submitting these, so overloaded
arch maintainers can convert their arches or take my patches on their
schedule without blocking arches that are ready to go.

Once all 8 arches are converted, I'll send a final cleanup patch that
removes all conditionals and references to GENERIC_TIME.

I'll be sending the unacked patches I'm not submitting to -mm shortly.

Credits to Roman for initially suggesting the idea quite awhile back.

thanks
-john


2009-04-15 01:34:25

by john stultz

[permalink] [raw]
Subject: [RESEND][PATCH 1/2] Create arch_gettimeoffset infrastructure for use in the generic timekeeping core.

Andrew, all,

Some arches don't supply their own clocksource. This is mainly the case
in architectures that get their inter-tick times by reading the counter
on their interval timer. Since these timers wrap every tick, they're not
really useful as clocksources. Wrapping them to act like one is possible
but not very efficient. So we provide a callout these arches can
implement for use with the jiffies clocksource to provide finer then
tick granular time.

Please consider for inclusion into -mm in preparation for 2.6.31.

Signed-off-by: John Stultz <[email protected]>

diff --git a/include/linux/time.h b/include/linux/time.h
index 242f624..01145d5 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -113,6 +113,21 @@ struct timespec current_kernel_time(void);
#define CURRENT_TIME (current_kernel_time())
#define CURRENT_TIME_SEC ((struct timespec) { get_seconds(), 0 })

+/* Some architectures do not supply their own clocksource.
+ * This is mainly the case in architectures that get their
+ * inter-tick times by reading the counter on their interval
+ * timer. Since these timers wrap every tick, they're not really
+ * useful as clocksources. Wrapping them to act like one is possible
+ * but not very efficient. So we provide a callout these arches
+ * can implement for use with the jiffies clocksource to provide
+ * finer then tick granular time.
+ */
+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
+extern u32 arch_gettimeoffset(void);
+#else
+#define arch_gettimeoffset() (0)
+#endif
+
extern void do_gettimeofday(struct timeval *tv);
extern int do_settimeofday(struct timespec *tv);
extern int do_sys_settimeofday(struct timespec *tv, struct timezone *tz);
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 900f1b6..45d777f 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -77,6 +77,10 @@ static void clocksource_forward_now(void)
clock->cycle_last = cycle_now;

nsec = cyc2ns(clock, cycle_delta);
+
+ /* If arch requires, add in gettimeoffset() */
+ nsec += arch_gettimeoffset();
+
timespec_add_ns(&xtime, nsec);

nsec = ((s64)cycle_delta * clock->mult_orig) >> clock->shift;
@@ -111,6 +115,9 @@ void getnstimeofday(struct timespec *ts)
/* convert to nanoseconds: */
nsecs = cyc2ns(clock, cycle_delta);

+ /* If arch requires, add in gettimeoffset() */
+ nsecs += arch_gettimeoffset();
+
} while (read_seqretry(&xtime_lock, seq));

timespec_add_ns(ts, nsecs);

2009-04-15 01:36:50

by john stultz

[permalink] [raw]
Subject: [RESEND][PATCH 2/2] Convert sh to use arch_getoffset() infrastructure.

This patch converts sh to use GENERIC_TIME via the arch_getoffset()
infrastructure

I have tried cross-compiling this for sh3 and sh4. Also little has
changed since my last submission where it was acked. So I've taken my
best swing at converting this, but I'm not 100% confident I got it
right. Any assistance from arch maintainers or testers would be great.

Signed-off-by: John Stultz <[email protected]>
Acked-by: Paul Mundt <[email protected]>

diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index e7390dd..6ee1240 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -74,7 +74,7 @@ config GENERIC_IOMAP
bool

config GENERIC_TIME
- def_bool n
+ def_bool y

config GENERIC_CLOCKEVENTS
def_bool n
@@ -451,6 +451,10 @@ config SH_TMU
help
This enables the use of the TMU as the system timer.

+config ARCH_USES_GETTIMEOFFSET
+ def_bool y
+ depends on !SH_TMU
+
config SH_CMT
bool "CMT timer support"
depends on SYS_SUPPORTS_CMT && CPU_SH2
diff --git a/arch/sh/include/asm/timer.h b/arch/sh/include/asm/timer.h
index 4c3b66e..f688df2 100644
--- a/arch/sh/include/asm/timer.h
+++ b/arch/sh/include/asm/timer.h
@@ -9,7 +9,7 @@ struct sys_timer_ops {
int (*init)(void);
int (*start)(void);
int (*stop)(void);
-#ifndef CONFIG_GENERIC_TIME
+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
unsigned long (*get_offset)(void);
#endif
};
@@ -26,7 +26,7 @@ struct sys_timer {
extern struct sys_timer tmu_timer, cmt_timer, mtu2_timer;
extern struct sys_timer *sys_timer;

-#ifndef CONFIG_GENERIC_TIME
+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
static inline unsigned long get_timer_offset(void)
{
return sys_timer->ops->get_offset();
diff --git a/arch/sh/kernel/time_32.c b/arch/sh/kernel/time_32.c
index c34e1e0..b824291 100644
--- a/arch/sh/kernel/time_32.c
+++ b/arch/sh/kernel/time_32.c
@@ -44,65 +44,12 @@ static int null_rtc_set_time(const time_t secs)
void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time;
int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time;

-#ifndef CONFIG_GENERIC_TIME
-void do_gettimeofday(struct timeval *tv)
+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
+u32 arch_gettimeoffset(void)
{
- unsigned long flags;
- unsigned long seq;
- unsigned long usec, sec;
-
- do {
- /*
- * Turn off IRQs when grabbing xtime_lock, so that
- * the sys_timer get_offset code doesn't have to handle it.
- */
- seq = read_seqbegin_irqsave(&xtime_lock, flags);
- usec = get_timer_offset();
- sec = xtime.tv_sec;
- usec += xtime.tv_nsec / NSEC_PER_USEC;
- } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
- while (usec >= 1000000) {
- usec -= 1000000;
- sec++;
- }
-
- tv->tv_sec = sec;
- tv->tv_usec = usec;
-}
-EXPORT_SYMBOL(do_gettimeofday);
-
-int do_settimeofday(struct timespec *tv)
-{
- time_t wtm_sec, sec = tv->tv_sec;
- long wtm_nsec, nsec = tv->tv_nsec;
-
- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
- return -EINVAL;
-
- write_seqlock_irq(&xtime_lock);
- /*
- * This is revolting. We need to set "xtime" correctly. However, the
- * value in this location is the value at the most recent update of
- * wall time. Discover what correction gettimeofday() would have
- * made, and then undo it!
- */
- nsec -= get_timer_offset() * NSEC_PER_USEC;
-
- wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
- wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
- set_normalized_timespec(&xtime, sec, nsec);
- set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
- ntp_clear();
- write_sequnlock_irq(&xtime_lock);
- clock_was_set();
-
- return 0;
+ return get_timer_offset() * 1000;
}
-EXPORT_SYMBOL(do_settimeofday);
-#endif /* !CONFIG_GENERIC_TIME */
+#endif /* CONFIG_ARCH_USES_GETTIMEOFFSET */

/* last time the RTC clock got updated */
static long last_rtc_update;
@@ -199,7 +146,7 @@ struct clocksource clocksource_sh = {
.name = "SuperH",
};

-#ifdef CONFIG_GENERIC_TIME
+#ifndef CONFIG_ARCH_USES_GETTIMEOFFSET
unsigned long long sched_clock(void)
{
unsigned long long cycles;
diff --git a/arch/sh/kernel/time_64.c b/arch/sh/kernel/time_64.c
index 988c77c..f4f5e8a 100644
--- a/arch/sh/kernel/time_64.c
+++ b/arch/sh/kernel/time_64.c
@@ -144,59 +144,10 @@ static unsigned long usecs_since_tick(void)
return result;
}

-void do_gettimeofday(struct timeval *tv)
+u32 arch_gettimeoffset(void)
{
- unsigned long flags;
- unsigned long seq;
- unsigned long usec, sec;
-
- do {
- seq = read_seqbegin_irqsave(&xtime_lock, flags);
- usec = usecs_since_tick();
- sec = xtime.tv_sec;
- usec += xtime.tv_nsec / 1000;
- } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
- while (usec >= 1000000) {
- usec -= 1000000;
- sec++;
- }
-
- tv->tv_sec = sec;
- tv->tv_usec = usec;
-}
-EXPORT_SYMBOL(do_gettimeofday);
-
-int do_settimeofday(struct timespec *tv)
-{
- time_t wtm_sec, sec = tv->tv_sec;
- long wtm_nsec, nsec = tv->tv_nsec;
-
- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
- return -EINVAL;
-
- write_seqlock_irq(&xtime_lock);
- /*
- * This is revolting. We need to set "xtime" correctly. However, the
- * value in this location is the value at the most recent update of
- * wall time. Discover what correction gettimeofday() would have
- * made, and then undo it!
- */
- nsec -= 1000 * usecs_since_tick();
-
- wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
- wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
- set_normalized_timespec(&xtime, sec, nsec);
- set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
- ntp_clear();
- write_sequnlock_irq(&xtime_lock);
- clock_was_set();
-
- return 0;
+ return usecs_since_tick() * 1000;
}
-EXPORT_SYMBOL(do_settimeofday);

/* Dummy RTC ops */
static void null_rtc_get_time(struct timespec *tv)
diff --git a/arch/sh/kernel/timers/timer-cmt.c b/arch/sh/kernel/timers/timer-cmt.c
index 9aa3486..c5e5ad7 100644
--- a/arch/sh/kernel/timers/timer-cmt.c
+++ b/arch/sh/kernel/timers/timer-cmt.c
@@ -177,7 +177,7 @@ static struct sys_timer_ops cmt_timer_ops = {
.init = cmt_timer_init,
.start = cmt_timer_start,
.stop = cmt_timer_stop,
-#ifndef CONFIG_GENERIC_TIME
+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
.get_offset = cmt_timer_get_offset,
#endif
};
diff --git a/arch/sh/kernel/timers/timer-mtu2.c b/arch/sh/kernel/timers/timer-mtu2.c
index 9b0ef01..8a1dcc2 100644
--- a/arch/sh/kernel/timers/timer-mtu2.c
+++ b/arch/sh/kernel/timers/timer-mtu2.c
@@ -191,7 +191,7 @@ struct sys_timer_ops mtu2_timer_ops = {
.init = mtu2_timer_init,
.start = mtu2_timer_start,
.stop = mtu2_timer_stop,
-#ifndef CONFIG_GENERIC_TIME
+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
.get_offset = mtu2_timer_get_offset,
#endif
};

2009-04-15 01:39:25

by john stultz

[permalink] [raw]
Subject: [RFC][PATCH 1/8] Convert alpha to use arch_getoffset() infrastructure.

This patch converts alpha to use GENERIC_TIME via the arch_getoffset()
infrastructure

I do not have cross compilers for these architectures, and in some cases
the architectures can be compiles both with and without clocksources. So
I've taken my best swing at converting this, but I'm not confident I got
it right. Any assistance from arch maintainers or testers would be
great.

NOT FOR INCLUSION
Signed-off-by: John Stultz <[email protected]>

diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 9fb8aae..4434481 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -45,6 +45,14 @@ config GENERIC_CALIBRATE_DELAY
bool
default y

+config GENERIC_TIME
+ bool
+ default y
+
+config ARCH_USES_GETTIMEOFFSET
+ bool
+ default y
+
config ZONE_DMA
bool
default y
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
index b04e2cb..8f7eb6d 100644
--- a/arch/alpha/kernel/time.c
+++ b/arch/alpha/kernel/time.c
@@ -408,28 +408,17 @@ time_init(void)
* part. So we can't do the "find absolute time in terms of cycles" thing
* that the other ports do.
*/
-void
-do_gettimeofday(struct timeval *tv)
+u32 arch_gettimeoffset(void)
{
- unsigned long flags;
- unsigned long sec, usec, seq;
unsigned long delta_cycles, delta_usec, partial_tick;

- do {
- seq = read_seqbegin_irqsave(&xtime_lock, flags);
-
- delta_cycles = rpcc() - state.last_time;
- sec = xtime.tv_sec;
- usec = (xtime.tv_nsec / 1000);
- partial_tick = state.partial_tick;
-
- } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
#ifdef CONFIG_SMP
/* Until and unless we figure out how to get cpu cycle counters
in sync and keep them there, we can't use the rpcc tricks. */
delta_usec = 0;
#else
+ delta_cycles = rpcc() - state.last_time;
+ partial_tick = state.partial_tick;
/*
* usec = cycles * ticks_per_cycle * 2**48 * 1e6 / (2**48 * ticks)
* = cycles * (s_t_p_c) * 1e6 / (2**48 * ticks)
@@ -448,62 +437,9 @@ do_gettimeofday(struct timeval *tv)
delta_usec = ((delta_usec / ((1UL << (FIX_SHIFT-6-1)) * HZ)) + 1) / 2;
#endif

- usec += delta_usec;
- if (usec >= 1000000) {
- sec += 1;
- usec -= 1000000;
- }
-
- tv->tv_sec = sec;
- tv->tv_usec = usec;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-
-int
-do_settimeofday(struct timespec *tv)
-{
- time_t wtm_sec, sec = tv->tv_sec;
- long wtm_nsec, nsec = tv->tv_nsec;
- unsigned long delta_nsec;
-
- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
- return -EINVAL;
-
- write_seqlock_irq(&xtime_lock);
-
- /* The offset that is added into time in do_gettimeofday above
- must be subtracted out here to keep a coherent view of the
- time. Without this, a full-tick error is possible. */
-
-#ifdef CONFIG_SMP
- delta_nsec = 0;
-#else
- delta_nsec = rpcc() - state.last_time;
- delta_nsec = (delta_nsec * state.scaled_ticks_per_cycle
- + state.partial_tick) * 15625;
- delta_nsec = ((delta_nsec / ((1UL << (FIX_SHIFT-6-1)) * HZ)) + 1) / 2;
- delta_nsec *= 1000;
-#endif
-
- nsec -= delta_nsec;
-
- wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
- wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
- set_normalized_timespec(&xtime, sec, nsec);
- set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
- ntp_clear();
-
- write_sequnlock_irq(&xtime_lock);
- clock_was_set();
- return 0;
+ return delta_usec * 1000;
}

-EXPORT_SYMBOL(do_settimeofday);
-
-
/*
* In order to set the CMOS clock precisely, set_rtc_mmss has to be
* called 500 ms after the second nowtime has started, because when

2009-04-15 01:41:23

by john stultz

[permalink] [raw]
Subject: [RFC][PATCH 2/8] Convert arm to use arch_getoffset() infrastructure.

This patch converts arm to use GENERIC_TIME via the arch_getoffset()
infrastructure

I do not have cross compilers for these architectures, and in some cases
the architectures can be compiles both with and without clocksources. So
I've taken my best swing at converting this, but I'm not confident I got
it right. Any assistance from arch maintainers or testers would be
great.

NOT FOR INCLUSION
Signed-off-by: John Stultz <[email protected]>

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index e02b893..61c88e1 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -38,7 +38,7 @@ config GENERIC_GPIO

config GENERIC_TIME
bool
- default n
+ default y

config GENERIC_CLOCKEVENTS
bool
@@ -203,6 +203,7 @@ config ARCH_AAEC2000
select CPU_ARM920T
select ARM_AMBA
select HAVE_CLK
+ select ARCH_USES_GETTIMEOFFSET
help
This enables support for systems based on the Agilent AAEC-2000

@@ -212,6 +213,7 @@ config ARCH_INTEGRATOR
select HAVE_CLK
select COMMON_CLKDEV
select ICST525
+ select ARCH_USES_GETTIMEOFFSET
help
Support for ARM's Integrator platform.

@@ -221,7 +223,6 @@ config ARCH_REALVIEW
select HAVE_CLK
select COMMON_CLKDEV
select ICST307
- select GENERIC_TIME
select GENERIC_CLOCKEVENTS
help
This enables support for ARM Ltd RealView boards.
@@ -233,7 +234,6 @@ config ARCH_VERSATILE
select HAVE_CLK
select COMMON_CLKDEV
select ICST307
- select GENERIC_TIME
select GENERIC_CLOCKEVENTS
help
This enables support for ARM Ltd Versatile board.
@@ -243,6 +243,7 @@ config ARCH_AT91
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
select HAVE_CLK
+ select ARCH_USES_GETTIMEOFFSET
help
This enables support for systems based on the Atmel AT91RM9200,
AT91SAM9 and AT91CAP9 processors.
@@ -258,6 +259,7 @@ config ARCH_EBSA110
select CPU_SA110
select ISA
select NO_IOPORT
+ select ARCH_USES_GETTIMEOFFSET
help
This is an evaluation board for the StrongARM processor available
from Digital. It has limited hardware on-board, including an
@@ -273,6 +275,7 @@ config ARCH_EP93XX
select HAVE_CLK
select COMMON_CLKDEV
select ARCH_REQUIRE_GPIOLIB
+ select ARCH_USES_GETTIMEOFFSET
help
This enables support for the Cirrus EP93xx series of CPUs.

@@ -288,6 +291,7 @@ config ARCH_FOOTBRIDGE
bool "FootBridge"
select CPU_SA110
select FOOTBRIDGE
+ select ARCH_USES_GETTIMEOFFSET
help
Support for systems based on the DC21285 companion chip
("FootBridge"), such as the Simtec CATS and the Rebel NetWinder.
@@ -297,7 +301,6 @@ config ARCH_NETX
select CPU_ARM926T
select ARM_VIC
select GENERIC_CLOCKEVENTS
- select GENERIC_TIME
help
This enables support for systems based on the Hilscher NetX Soc

@@ -305,6 +308,7 @@ config ARCH_H720X
bool "Hynix HMS720x-based"
select CPU_ARM720T
select ISA_DMA_API
+ select ARCH_USES_GETTIMEOFFSET
help
This enables support for systems based on the Hynix HMS720x

@@ -312,7 +316,6 @@ config ARCH_IMX
bool "IMX"
select CPU_ARM920T
select GENERIC_GPIO
- select GENERIC_TIME
select GENERIC_CLOCKEVENTS
help
Support for Motorola's i.MX family of processors (MX1, MXL).
@@ -325,6 +328,7 @@ config ARCH_IOP13XX
select PCI
select ARCH_SUPPORTS_MSI
select VMSPLIT_1G
+ select ARCH_USES_GETTIMEOFFSET
help
Support for Intel's IOP13XX (XScale) family of processors.

@@ -336,6 +340,7 @@ config ARCH_IOP32X
select PCI
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
+ select ARCH_USES_GETTIMEOFFSET
help
Support for Intel's 80219 and IOP32X (XScale) family of
processors.
@@ -348,6 +353,7 @@ config ARCH_IOP33X
select PCI
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
+ select ARCH_USES_GETTIMEOFFSET
help
Support for Intel's IOP33X (XScale) family of processors.

@@ -356,6 +362,7 @@ config ARCH_IXP23XX
depends on MMU
select CPU_XSC3
select PCI
+ select ARCH_USES_GETTIMEOFFSET
help
Support for Intel's IXP23xx (XScale) family of processors.

@@ -364,6 +371,7 @@ config ARCH_IXP2000
depends on MMU
select CPU_XSCALE
select PCI
+ select ARCH_USES_GETTIMEOFFSET
help
Support for Intel's IXP2400/2800 (XScale) family of processors.

@@ -372,7 +380,6 @@ config ARCH_IXP4XX
depends on MMU
select CPU_XSCALE
select GENERIC_GPIO
- select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select DMABOUNCE if PCI
help
@@ -382,6 +389,7 @@ config ARCH_L7200
bool "LinkUp-L7200"
select CPU_ARM720T
select FIQ
+ select ARCH_USES_GETTIMEOFFSET
help
Say Y here if you intend to run this kernel on a LinkUp Systems
L7200 Software Development Board which uses an ARM720T processor.
@@ -397,7 +405,6 @@ config ARCH_KIRKWOOD
select CPU_FEROCEON
select PCI
select GENERIC_GPIO
- select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select PLAT_ORION
help
@@ -409,6 +416,7 @@ config ARCH_KS8695
select CPU_ARM922T
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
+ select ARCH_USES_GETTIMEOFFSET
help
Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based
System-on-Chip devices.
@@ -417,7 +425,6 @@ config ARCH_NS9XXX
bool "NetSilicon NS9xxx"
select CPU_ARM926T
select GENERIC_GPIO
- select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select HAVE_CLK
help
@@ -429,7 +436,6 @@ config ARCH_NS9XXX
config ARCH_LOKI
bool "Marvell Loki (88RC8480)"
select CPU_FEROCEON
- select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select PLAT_ORION
help
@@ -440,7 +446,6 @@ config ARCH_MV78XX0
select CPU_FEROCEON
select PCI
select GENERIC_GPIO
- select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select PLAT_ORION
help
@@ -449,7 +454,6 @@ config ARCH_MV78XX0

config ARCH_MXC
bool "Freescale MXC/iMX-based"
- select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select ARCH_MTD_XIP
select GENERIC_GPIO
@@ -463,7 +467,6 @@ config ARCH_ORION5X
select CPU_FEROCEON
select PCI
select GENERIC_GPIO
- select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select PLAT_ORION
help
@@ -475,6 +478,7 @@ config ARCH_PNX4008
bool "Philips Nexperia PNX4008 Mobile"
select CPU_ARM926T
select HAVE_CLK
+ select ARCH_USES_GETTIMEOFFSET
help
This enables support for Philips PNX4008 mobile platform.

@@ -488,7 +492,6 @@ config ARCH_PXA
select ARCH_REQUIRE_GPIOLIB
select HAVE_CLK
select COMMON_CLKDEV
- select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select TICK_ONESHOT
select PLAT_PXA
@@ -502,7 +505,6 @@ config ARCH_MMP
select ARCH_REQUIRE_GPIOLIB
select HAVE_CLK
select COMMON_CLKDEV
- select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select TICK_ONESHOT
select PLAT_PXA
@@ -519,6 +521,7 @@ config ARCH_RPC
select ISA_DMA_API
select NO_IOPORT
select ARCH_SPARSEMEM_ENABLE
+ select ARCH_USES_GETTIMEOFFSET
help
On the Acorn Risc-PC, Linux can support the internal IDE disk and
CD-ROM interface, serial and parallel port, and the floppy drive.
@@ -530,7 +533,6 @@ config ARCH_SA1100
select ARCH_SPARSEMEM_ENABLE
select ARCH_MTD_XIP
select GENERIC_GPIO
- select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select HAVE_CLK
select TICK_ONESHOT
@@ -542,6 +544,7 @@ config ARCH_S3C2410
bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443"
select GENERIC_GPIO
select HAVE_CLK
+ select ARCH_USES_GETTIMEOFFSET
help
Samsung S3C2410X CPU based systems, such as the Simtec Electronics
BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or
@@ -551,6 +554,7 @@ config ARCH_S3C64XX
bool "Samsung S3C64XX"
select GENERIC_GPIO
select HAVE_CLK
+ select ARCH_USES_GETTIMEOFFSET
help
Samsung S3C64XX series based systems

@@ -561,6 +565,7 @@ config ARCH_SHARK
select ISA_DMA
select ZONE_DMA
select PCI
+ select ARCH_USES_GETTIMEOFFSET
help
Support for the StrongARM based Digital DNARD machine, also known
as "Shark" (<http://www.shark-linux.de/shark.html>).
@@ -570,6 +575,7 @@ config ARCH_LH7A40X
select CPU_ARM922T
select ARCH_DISCONTIGMEM_ENABLE if !LH7A40X_CONTIGMEM
select ARCH_SPARSEMEM_ENABLE if !LH7A40X_CONTIGMEM
+ select ARCH_USES_GETTIMEOFFSET
help
Say Y here for systems based on one of the Sharp LH7A40X
System on a Chip processors. These CPUs include an ARM922T
@@ -579,7 +585,6 @@ config ARCH_LH7A40X
config ARCH_DAVINCI
bool "TI DaVinci"
select CPU_ARM926T
- select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
@@ -593,7 +598,6 @@ config ARCH_OMAP
select GENERIC_GPIO
select HAVE_CLK
select ARCH_REQUIRE_GPIOLIB
- select GENERIC_TIME
select GENERIC_CLOCKEVENTS
help
Support for TI's OMAP platform (OMAP1 and OMAP2).
@@ -601,7 +605,6 @@ config ARCH_OMAP
config ARCH_MSM
bool "Qualcomm MSM"
select CPU_V6
- select GENERIC_TIME
select GENERIC_CLOCKEVENTS
help
Support for Qualcomm MSM7K based systems. This runs on the ARM11
@@ -612,6 +615,7 @@ config ARCH_MSM
config ARCH_W90X900
bool "Nuvoton W90X900 CPU"
select CPU_ARM926T
+ select ARCH_USES_GETTIMEOFFSET
help
Support for Nuvoton (Winbond logic dept.) ARM9 processor,You
can login http://www.mcuos.com or http://www.nuvoton.com to know more.
diff --git a/arch/arm/include/asm/mach/time.h b/arch/arm/include/asm/mach/time.h
index b2cc1fc..20c1d84 100644
--- a/arch/arm/include/asm/mach/time.h
+++ b/arch/arm/include/asm/mach/time.h
@@ -38,7 +38,7 @@ struct sys_timer {
void (*init)(void);
void (*suspend)(void);
void (*resume)(void);
-#ifndef CONFIG_GENERIC_TIME
+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
unsigned long (*offset)(void);
#endif
};
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index 4cdc4a0..d9d8d6d 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -81,7 +81,7 @@ EXPORT_SYMBOL(profile_pc);
*/
int (*set_rtc)(void);

-#ifndef CONFIG_GENERIC_TIME
+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
static unsigned long dummy_gettimeoffset(void)
{
return 0;
@@ -236,63 +236,12 @@ static inline void do_leds(void)
#define do_leds()
#endif

-#ifndef CONFIG_GENERIC_TIME
-void do_gettimeofday(struct timeval *tv)
+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
+u32 arch_gettimeoffset(void)
{
- unsigned long flags;
- unsigned long seq;
- unsigned long usec, sec;
-
- do {
- seq = read_seqbegin_irqsave(&xtime_lock, flags);
- usec = system_timer->offset();
- sec = xtime.tv_sec;
- usec += xtime.tv_nsec / 1000;
- } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
- /* usec may have gone up a lot: be safe */
- while (usec >= 1000000) {
- usec -= 1000000;
- sec++;
- }
-
- tv->tv_sec = sec;
- tv->tv_usec = usec;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-
-int do_settimeofday(struct timespec *tv)
-{
- time_t wtm_sec, sec = tv->tv_sec;
- long wtm_nsec, nsec = tv->tv_nsec;
-
- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
- return -EINVAL;
-
- write_seqlock_irq(&xtime_lock);
- /*
- * This is revolting. We need to set "xtime" correctly. However, the
- * value in this location is the value at the most recent update of
- * wall time. Discover what correction gettimeofday() would have
- * done, and then undo it!
- */
- nsec -= system_timer->offset() * NSEC_PER_USEC;
-
- wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
- wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
- set_normalized_timespec(&xtime, sec, nsec);
- set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
- ntp_clear();
- write_sequnlock_irq(&xtime_lock);
- clock_was_set();
- return 0;
+ return system_timer->offset() * 1000;
}
-
-EXPORT_SYMBOL(do_settimeofday);
-#endif /* !CONFIG_GENERIC_TIME */
+#endif /* CONFIG_ARCH_USES_GETTIMEOFFSET */

/**
* save_time_delta - Save the offset between system time and RTC time
@@ -391,7 +340,7 @@ device_initcall(timer_init_sysfs);

void __init time_init(void)
{
-#ifndef CONFIG_GENERIC_TIME
+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
if (system_timer->offset == NULL)
system_timer->offset = dummy_gettimeoffset;
#endif
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 323b47f..e82979c 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -8,47 +8,41 @@ choice
config ARCH_AT91RM9200
bool "AT91RM9200"
select CPU_ARM920T
- select GENERIC_TIME
select GENERIC_CLOCKEVENTS

config ARCH_AT91SAM9260
bool "AT91SAM9260 or AT91SAM9XE"
select CPU_ARM926T
- select GENERIC_TIME
select GENERIC_CLOCKEVENTS

config ARCH_AT91SAM9261
bool "AT91SAM9261"
select CPU_ARM926T
- select GENERIC_TIME
select GENERIC_CLOCKEVENTS

config ARCH_AT91SAM9263
bool "AT91SAM9263"
select CPU_ARM926T
- select GENERIC_TIME
select GENERIC_CLOCKEVENTS

config ARCH_AT91SAM9RL
bool "AT91SAM9RL"
select CPU_ARM926T
- select GENERIC_TIME
select GENERIC_CLOCKEVENTS

config ARCH_AT91SAM9G20
bool "AT91SAM9G20"
select CPU_ARM926T
- select GENERIC_TIME
select GENERIC_CLOCKEVENTS

config ARCH_AT91CAP9
bool "AT91CAP9"
select CPU_ARM926T
- select GENERIC_TIME
select GENERIC_CLOCKEVENTS

config ARCH_AT91X40
bool "AT91x40"
+ select ARCH_USES_GETTIMEOFFSET

endchoice


2009-04-15 01:43:39

by john stultz

[permalink] [raw]
Subject: [RFC][PATCH 3/8] Convert blackfin to use arch_getoffset() infrastructure.

This patch converts blackfin to use GENERIC_TIME via the
arch_getoffset() infrastructure

I do not have cross compilers for these architectures, and in some cases
the architectures can be compiles both with and without clocksources. So
I've taken my best swing at converting this, but I'm not confident I got
it right. Any assistance from arch maintainers or testers would be
great.

Signed-off-by: John Stultz <[email protected]>

diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index 3640cdc..2b41547 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -606,9 +606,7 @@ comment "Kernel Timer/Scheduler"
source kernel/Kconfig.hz

config GENERIC_TIME
- bool "Generic time"
- depends on !SMP
- default y
+ def_bool y

config GENERIC_CLOCKEVENTS
bool "Generic clock events"
@@ -628,6 +626,10 @@ config CYCLES_CLOCKSOURCE
still be able to read it (such as for performance monitoring), but
writing the registers will most likely crash the kernel.

+config ARCH_USES_GETTIMEOFFSET
+ depends on !CYCLES_CLOCKSOURCE
+ def_bool y
+
source kernel/time/Kconfig

comment "Misc"
diff --git a/arch/blackfin/kernel/time.c b/arch/blackfin/kernel/time.c
index 1bbacfb..ddd1827 100644
--- a/arch/blackfin/kernel/time.c
+++ b/arch/blackfin/kernel/time.c
@@ -85,11 +85,11 @@ time_sched_init(irqreturn_t(*timer_routine) (int, void *))
#endif
}

+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
/*
* Should return useconds since last timer tick
*/
-#ifndef CONFIG_GENERIC_TIME
-static unsigned long gettimeoffset(void)
+u32 arch_gettimeoffset(void)
{
unsigned long offset;
unsigned long clocks_per_jiffy;
@@ -199,64 +199,29 @@ void __init time_init(void)
time_sched_init(timer_interrupt);
}

-#ifndef CONFIG_GENERIC_TIME
-void do_gettimeofday(struct timeval *tv)
-{
- unsigned long flags;
- unsigned long seq;
- unsigned long usec, sec;
-
- do {
- seq = read_seqbegin_irqsave(&xtime_lock, flags);
- usec = gettimeoffset();
- sec = xtime.tv_sec;
- usec += (xtime.tv_nsec / NSEC_PER_USEC);
- }
- while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
- while (usec >= USEC_PER_SEC) {
- usec -= USEC_PER_SEC;
- sec++;
- }
-
- tv->tv_sec = sec;
- tv->tv_usec = usec;
-}
-EXPORT_SYMBOL(do_gettimeofday);
-
-int do_settimeofday(struct timespec *tv)
+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
+/*
+ * Should return nseconds since last timer tick
+ */
+u32 arch_gettimeoffset(void)
{
- time_t wtm_sec, sec = tv->tv_sec;
- long wtm_nsec, nsec = tv->tv_nsec;
-
- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
- return -EINVAL;
-
- write_seqlock_irq(&xtime_lock);
- /*
- * This is revolting. We need to set the xtime.tv_usec
- * correctly. However, the value in this location is
- * is value at the last tick.
- * Discover what correction gettimeofday
- * would have done, and then undo it!
- */
- nsec -= (gettimeoffset() * NSEC_PER_USEC);
-
- wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
- wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
- set_normalized_timespec(&xtime, sec, nsec);
- set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
+ unsigned long offset;
+ unsigned long clocks_per_jiffy;

- ntp_clear();
+ clocks_per_jiffy = bfin_read_TPERIOD();
+ offset =
+ (clocks_per_jiffy -
+ bfin_read_TCOUNT()) / (((clocks_per_jiffy + 1) * HZ) /
+ USEC_PER_SEC);

- write_sequnlock_irq(&xtime_lock);
- clock_was_set();
+ /* Check if we just wrapped the counters and maybe missed a tick */
+ if ((bfin_read_ILAT() & (1 << IRQ_CORETMR))
+ && (offset < (100000 / HZ / 2)))
+ offset += (USEC_PER_SEC / HZ);

- return 0;
+ return offset*1000;
}
-EXPORT_SYMBOL(do_settimeofday);
-#endif /* !CONFIG_GENERIC_TIME */
+#endif /* !CONFIG_ARCH_USES_GETTIMEOFFSET */

/*
* Scheduler clock - returns current time in nanosec units.

2009-04-15 01:44:51

by john stultz

[permalink] [raw]
Subject: [RFC][PATCH 4/8] Convert cris to use arch_getoffset() infrastructure.

This patch converts cris to use GENERIC_TIME via the arch_getoffset()
infrastructure

I do not have cross compilers for these architectures, and in some cases
the architectures can be compiles both with and without clocksources. So
I've taken my best swing at converting this, but I'm not confident I got
it right. Any assistance from arch maintainers or testers would be
great.

NOT FOR INCLUSION
Signed-off-by: John Stultz <[email protected]>

diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index 7adac38..059eac6 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -20,6 +20,12 @@ config RWSEM_GENERIC_SPINLOCK
config RWSEM_XCHGADD_ALGORITHM
bool

+config GENERIC_TIME
+ def_bool y
+
+config ARCH_USES_GETTIMEOFFSET
+ def_bool y
+
config GENERIC_IOMAP
bool
default y
diff --git a/arch/cris/kernel/time.c b/arch/cris/kernel/time.c
index 074fe7d..a05dd31 100644
--- a/arch/cris/kernel/time.c
+++ b/arch/cris/kernel/time.c
@@ -42,75 +42,11 @@ unsigned long loops_per_usec;
extern unsigned long do_slow_gettimeoffset(void);
static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;

-/*
- * This version of gettimeofday has near microsecond resolution.
- *
- * Note: Division is quite slow on CRIS and do_gettimeofday is called
- * rather often. Maybe we should do some kind of approximation here
- * (a naive approximation would be to divide by 1024).
- */
-void do_gettimeofday(struct timeval *tv)
-{
- unsigned long flags;
- signed long usec, sec;
- local_irq_save(flags);
- usec = do_gettimeoffset();
-
- /*
- * If time_adjust is negative then NTP is slowing the clock
- * so make sure not to go into next possible interval.
- * Better to lose some accuracy than have time go backwards..
- */
- if (unlikely(time_adjust < 0) && usec > tickadj)
- usec = tickadj;
-
- sec = xtime.tv_sec;
- usec += xtime.tv_nsec / 1000;
- local_irq_restore(flags);
-
- while (usec >= 1000000) {
- usec -= 1000000;
- sec++;
- }
-
- tv->tv_sec = sec;
- tv->tv_usec = usec;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-
-int do_settimeofday(struct timespec *tv)
+u32 arch_gettimeoffset(void)
{
- time_t wtm_sec, sec = tv->tv_sec;
- long wtm_nsec, nsec = tv->tv_nsec;
-
- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
- return -EINVAL;
-
- write_seqlock_irq(&xtime_lock);
- /*
- * This is revolting. We need to set "xtime" correctly. However, the
- * value in this location is the value at the most recent update of
- * wall time. Discover what correction gettimeofday() would have
- * made, and then undo it!
- */
- nsec -= do_gettimeoffset() * NSEC_PER_USEC;
-
- wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
- wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
- set_normalized_timespec(&xtime, sec, nsec);
- set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
- ntp_clear();
- write_sequnlock_irq(&xtime_lock);
- clock_was_set();
- return 0;
+ return do_gettimeoffset() * 1000;
}

-EXPORT_SYMBOL(do_settimeofday);
-
-
/*
* BUG: This routine does not handle hour overflow properly; it just
* sets the minutes. Usually you'll only notice that after reboot!

2009-04-15 01:45:44

by john stultz

[permalink] [raw]
Subject: [RFC][PATCH 5/8] Convert m32r to use arch_getoffset() infrastructure.

This patch converts m32r to use GENERIC_TIME via the arch_getoffset()
infrastructure

I do not have cross compilers for these architectures, and in some cases
the architectures can be compiles both with and without clocksources. So
I've taken my best swing at converting this, but I'm not confident I got
it right. Any assistance from arch maintainers or testers would be
great.

NOT FOR INCLUSION
Signed-off-by: John Stultz <[email protected]>

diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig
index cabba33..c41234f 100644
--- a/arch/m32r/Kconfig
+++ b/arch/m32r/Kconfig
@@ -41,6 +41,12 @@ config HZ
int
default 100

+config GENERIC_TIME
+ def_bool y
+
+config ARCH_USES_GETTIMEOFFSET
+ def_bool y
+
source "init/Kconfig"

source "kernel/Kconfig.freezer"
diff --git a/arch/m32r/kernel/time.c b/arch/m32r/kernel/time.c
index cada3ba..ba61c4c 100644
--- a/arch/m32r/kernel/time.c
+++ b/arch/m32r/kernel/time.c
@@ -48,7 +48,7 @@ extern void smp_local_timer_interrupt(void);

static unsigned long latch;

-static unsigned long do_gettimeoffset(void)
+u32 arch_gettimeoffset(void)
{
unsigned long elapsed_time = 0; /* [us] */

@@ -93,79 +93,10 @@ static unsigned long do_gettimeoffset(void)
#error no chip configuration
#endif

- return elapsed_time;
+ return elapsed_time * 1000;
}

/*
- * This version of gettimeofday has near microsecond resolution.
- */
-void do_gettimeofday(struct timeval *tv)
-{
- unsigned long seq;
- unsigned long usec, sec;
- unsigned long max_ntp_tick = tick_usec - tickadj;
-
- do {
- seq = read_seqbegin(&xtime_lock);
-
- usec = do_gettimeoffset();
-
- /*
- * If time_adjust is negative then NTP is slowing the clock
- * so make sure not to go into next possible interval.
- * Better to lose some accuracy than have time go backwards..
- */
- if (unlikely(time_adjust < 0))
- usec = min(usec, max_ntp_tick);
-
- sec = xtime.tv_sec;
- usec += (xtime.tv_nsec / 1000);
- } while (read_seqretry(&xtime_lock, seq));
-
- while (usec >= 1000000) {
- usec -= 1000000;
- sec++;
- }
-
- tv->tv_sec = sec;
- tv->tv_usec = usec;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-
-int do_settimeofday(struct timespec *tv)
-{
- time_t wtm_sec, sec = tv->tv_sec;
- long wtm_nsec, nsec = tv->tv_nsec;
-
- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
- return -EINVAL;
-
- write_seqlock_irq(&xtime_lock);
- /*
- * This is revolting. We need to set "xtime" correctly. However, the
- * value in this location is the value at the most recent update of
- * wall time. Discover what correction gettimeofday() would have
- * made, and then undo it!
- */
- nsec -= do_gettimeoffset() * NSEC_PER_USEC;
-
- wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
- wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
- set_normalized_timespec(&xtime, sec, nsec);
- set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
- ntp_clear();
- write_sequnlock_irq(&xtime_lock);
- clock_was_set();
-
- return 0;
-}
-
-EXPORT_SYMBOL(do_settimeofday);
-
-/*
* In order to set the CMOS clock precisely, set_rtc_mmss has to be
* called 500 ms after the second nowtime has started, because when
* nowtime is written into the registers of the CMOS clock, it will
@@ -192,6 +123,7 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
#ifndef CONFIG_SMP
profile_tick(CPU_PROFILING);
#endif
+ /* XXX FIXME. Uh, the xtime_lock should be held here, no? */
do_timer(1);

#ifndef CONFIG_SMP

2009-04-15 01:46:55

by john stultz

[permalink] [raw]
Subject: [RFC][PATCH 6/8] Convert m68k to use arch_getoffset() infrastructure.

This patch converts m68k to use GENERIC_TIME via the arch_getoffset()
infrastructure

I do not have cross compilers for these architectures, and in some cases
the architectures can be compiles both with and without clocksources. So
I've taken my best swing at converting this, but I'm not confident I got
it right. Any assistance from arch maintainers or testers would be
great.

NOT FOR INCLUSION
Signed-off-by: John Stultz <[email protected]>

diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index fb87c08..29dd848 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -58,6 +58,12 @@ config HZ
int
default 100

+config GENERIC_TIME
+ def_bool y
+
+config ARCH_USES_GETTIMEOFFSET
+ def_bool y
+
mainmenu "Linux/68k Kernel Configuration"

source "init/Kconfig"
diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c
index 54d9807..17dc2a3 100644
--- a/arch/m68k/kernel/time.c
+++ b/arch/m68k/kernel/time.c
@@ -91,77 +91,11 @@ void __init time_init(void)
mach_sched_init(timer_interrupt);
}

-/*
- * This version of gettimeofday has near microsecond resolution.
- */
-void do_gettimeofday(struct timeval *tv)
+u32 arch_gettimeoffset(void)
{
- unsigned long flags;
- unsigned long seq;
- unsigned long usec, sec;
- unsigned long max_ntp_tick = tick_usec - tickadj;
-
- do {
- seq = read_seqbegin_irqsave(&xtime_lock, flags);
-
- usec = mach_gettimeoffset();
-
- /*
- * If time_adjust is negative then NTP is slowing the clock
- * so make sure not to go into next possible interval.
- * Better to lose some accuracy than have time go backwards..
- */
- if (unlikely(time_adjust < 0))
- usec = min(usec, max_ntp_tick);
-
- sec = xtime.tv_sec;
- usec += xtime.tv_nsec/1000;
- } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
-
- while (usec >= 1000000) {
- usec -= 1000000;
- sec++;
- }
-
- tv->tv_sec = sec;
- tv->tv_usec = usec;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-
-int do_settimeofday(struct timespec *tv)
-{
- time_t wtm_sec, sec = tv->tv_sec;
- long wtm_nsec, nsec = tv->tv_nsec;
-
- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
- return -EINVAL;
-
- write_seqlock_irq(&xtime_lock);
- /* This is revolting. We need to set the xtime.tv_nsec
- * correctly. However, the value in this location is
- * is value at the last tick.
- * Discover what correction gettimeofday
- * would have done, and then undo it!
- */
- nsec -= 1000 * mach_gettimeoffset();
-
- wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
- wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
- set_normalized_timespec(&xtime, sec, nsec);
- set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
- ntp_clear();
- write_sequnlock_irq(&xtime_lock);
- clock_was_set();
- return 0;
+ return mach_gettimeoffset() * 1000;
}

-EXPORT_SYMBOL(do_settimeofday);
-
-
static int __init rtc_init(void)
{
struct platform_device *pdev;

2009-04-15 01:51:41

by john stultz

[permalink] [raw]
Subject: Re: [RFC][PATCH 7/8] Convert sparc to use arch_getoffset() infrastructure.

Hey Dave,
You acked this patch earlier, but I've just tried building with a
cross-compiler environment I had access to and had problems getting it
to build.

It seems the pci_do_get/settimeofday() and the bus_do_get/settimeofday()
redirection code is causing some trouble. I'm really not sure how the
BTFIXUPSET_CALL code works, so I don't want to just kill it off.

Any advice here on how to do this right?

thanks
-john


This patch converts sparc to use GENERIC_TIME via the arch_getoffset()
infrastructure

NOT FOR INCLUSION
Signed-off-by: John Stultz <[email protected]>

diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index cc12cd4..1358aab 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -55,8 +55,11 @@ config BITS
default 64 if SPARC64

config GENERIC_TIME
+ def_bool y
+
+config ARCH_USES_GETTIMEOFFSET
bool
- default y if SPARC64
+ default y if SPARC32

config GENERIC_CMOS_UPDATE
bool
diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c
index 614ac7b..e946b55 100644
--- a/arch/sparc/kernel/time_32.c
+++ b/arch/sparc/kernel/time_32.c
@@ -227,7 +227,7 @@ void __init time_init(void)
sbus_time_init();
}

-static inline unsigned long do_gettimeoffset(void)
+u32 arch_gettimeoffset(void)
{
unsigned long val = *master_l10_counter;
unsigned long usec = (val >> 10) & 0x1fffff;
@@ -236,84 +236,7 @@ static inline unsigned long do_gettimeoffset(void)
if (val & 0x80000000)
usec += 1000000 / HZ;

- return usec;
-}
-
-/* Ok, my cute asm atomicity trick doesn't work anymore.
- * There are just too many variables that need to be protected
- * now (both members of xtime, et al.)
- */
-void do_gettimeofday(struct timeval *tv)
-{
- unsigned long flags;
- unsigned long seq;
- unsigned long usec, sec;
- unsigned long max_ntp_tick = tick_usec - tickadj;
-
- do {
- seq = read_seqbegin_irqsave(&xtime_lock, flags);
- usec = do_gettimeoffset();
-
- /*
- * If time_adjust is negative then NTP is slowing the clock
- * so make sure not to go into next possible interval.
- * Better to lose some accuracy than have time go backwards..
- */
- if (unlikely(time_adjust < 0))
- usec = min(usec, max_ntp_tick);
-
- sec = xtime.tv_sec;
- usec += (xtime.tv_nsec / 1000);
- } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
- while (usec >= 1000000) {
- usec -= 1000000;
- sec++;
- }
-
- tv->tv_sec = sec;
- tv->tv_usec = usec;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-
-int do_settimeofday(struct timespec *tv)
-{
- int ret;
-
- write_seqlock_irq(&xtime_lock);
- ret = bus_do_settimeofday(tv);
- write_sequnlock_irq(&xtime_lock);
- clock_was_set();
- return ret;
-}
-
-EXPORT_SYMBOL(do_settimeofday);
-
-static int sbus_do_settimeofday(struct timespec *tv)
-{
- time_t wtm_sec, sec = tv->tv_sec;
- long wtm_nsec, nsec = tv->tv_nsec;
-
- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
- return -EINVAL;
-
- /*
- * This is revolting. We need to set "xtime" correctly. However, the
- * value in this location is the value at the most recent update of
- * wall time. Discover what correction gettimeofday() would have
- * made, and then undo it!
- */
- nsec -= 1000 * do_gettimeoffset();
-
- wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
- wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
- set_normalized_timespec(&xtime, sec, nsec);
- set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
- ntp_clear();
- return 0;
+ return usec * 1000;
}

static int set_rtc_mmss(unsigned long secs)

2009-04-15 01:53:52

by john stultz

[permalink] [raw]
Subject: [RFC][PATCH 8/8] Remove CONFIG_GENERIC_TIME

This removes all references to CONFIG_GENERIC_TIME in the timekeeping
core as well as the arch Kconfig files.

Arch defconfig files were left alone.

Signed-off-by: John Stultz <[email protected]>

diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 6172e43..d6769ff 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -64,7 +64,6 @@ parameter is applicable:
MTD MTD (Memory Technology Device) support is enabled.
NET Appropriate network support is enabled.
NUMA NUMA support is enabled.
- GENERIC_TIME The generic timeofday code is enabled.
NFS Appropriate NFS support is enabled.
OSS OSS sound support is enabled.
PV_OPS A paravirtualized kernel is enabled.
@@ -426,7 +425,7 @@ and is between 256 and 4096 characters. It is defined in the file
clocksource is not available, it defaults to PIT.
Format: { pit | tsc | cyclone | pmtmr }

- clocksource= [GENERIC_TIME] Override the default clocksource
+ clocksource= Override the default clocksource
Format: <string>
Override the default clocksource and use the clocksource
with the name specified.
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 4434481..e2251b5 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -45,10 +45,6 @@ config GENERIC_CALIBRATE_DELAY
bool
default y

-config GENERIC_TIME
- bool
- default y
-
config ARCH_USES_GETTIMEOFFSET
bool
default y
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 61c88e1..37f3bda 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -36,10 +36,6 @@ config GENERIC_GPIO
bool
default n

-config GENERIC_TIME
- bool
- default y
-
config GENERIC_CLOCKEVENTS
bool
default n
diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig
index 35e3bd9..0b1e70d 100644
--- a/arch/avr32/Kconfig
+++ b/arch/avr32/Kconfig
@@ -45,9 +45,6 @@ config GENERIC_IRQ_PROBE
config RWSEM_GENERIC_SPINLOCK
def_bool y

-config GENERIC_TIME
- def_bool y
-
config GENERIC_CLOCKEVENTS
def_bool y

diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index 2b41547..7be2b94 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -605,12 +605,8 @@ comment "Kernel Timer/Scheduler"

source kernel/Kconfig.hz

-config GENERIC_TIME
- def_bool y
-
config GENERIC_CLOCKEVENTS
bool "Generic clock events"
- depends on GENERIC_TIME
default y

config CYCLES_CLOCKSOURCE
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index 059eac6..a668ce1 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -20,9 +20,6 @@ config RWSEM_GENERIC_SPINLOCK
config RWSEM_XCHGADD_ALGORITHM
bool

-config GENERIC_TIME
- def_bool y
-
config ARCH_USES_GETTIMEOFFSET
def_bool y

diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index 9d1552a..42c3497 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -38,10 +38,6 @@ config GENERIC_HARDIRQS_NO__DO_IRQ
bool
default y

-config GENERIC_TIME
- bool
- default y
-
config TIME_LOW_RES
bool
default y
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
index 9420648..3bf6e51 100644
--- a/arch/h8300/Kconfig
+++ b/arch/h8300/Kconfig
@@ -58,10 +58,6 @@ config GENERIC_CALIBRATE_DELAY
bool
default y

-config GENERIC_TIME
- bool
- default y
-
config GENERIC_BUG
bool
depends on BUG
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 294a3b1..5e1df8c 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -80,10 +80,6 @@ config GENERIC_CALIBRATE_DELAY
bool
default y

-config GENERIC_TIME
- bool
- default y
-
config GENERIC_TIME_VSYSCALL
bool
default y
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig
index c41234f..32ad821 100644
--- a/arch/m32r/Kconfig
+++ b/arch/m32r/Kconfig
@@ -41,9 +41,6 @@ config HZ
int
default 100

-config GENERIC_TIME
- def_bool y
-
config ARCH_USES_GETTIMEOFFSET
def_bool y

diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 29dd848..7b0f880 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -58,9 +58,6 @@ config HZ
int
default 100

-config GENERIC_TIME
- def_bool y
-
config ARCH_USES_GETTIMEOFFSET
def_bool y

diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
index 4beb59d..2806400 100644
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -58,10 +58,6 @@ config GENERIC_CALIBRATE_DELAY
bool
default y

-config GENERIC_TIME
- bool
- default y
-
config GENERIC_CMOS_UPDATE
bool
default y
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index 8cc312b..73d9963 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -37,9 +37,6 @@ config GENERIC_IRQ_PROBE
config GENERIC_CALIBRATE_DELAY
def_bool y

-config GENERIC_TIME
- def_bool y
-
config GENERIC_TIME_VSYSCALL
def_bool n

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 998e5db..8e1be85 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -680,10 +680,6 @@ config GENERIC_CLOCKEVENTS
bool
default y

-config GENERIC_TIME
- bool
- default y
-
config GENERIC_CMOS_UPDATE
bool
default y
diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig
index 3559267..bab6c1f 100644
--- a/arch/mn10300/Kconfig
+++ b/arch/mn10300/Kconfig
@@ -42,9 +42,6 @@ config GENERIC_FIND_NEXT_BIT
config GENERIC_HWEIGHT
def_bool y

-config GENERIC_TIME
- def_bool y
-
config GENERIC_BUG
def_bool y

diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 9038f39..c42c0b4 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -64,10 +64,6 @@ config GENERIC_CALIBRATE_DELAY
bool
default y

-config GENERIC_TIME
- bool
- default y
-
config TIME_LOW_RES
bool
depends on SMP
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 5b50e1a..c3f6489 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -29,9 +29,6 @@ config MMU
config GENERIC_CMOS_UPDATE
def_bool y

-config GENERIC_TIME
- def_bool y
-
config GENERIC_TIME_VSYSCALL
def_bool y

diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 2eca5fe..dae9e1b 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -40,9 +40,6 @@ config ARCH_HAS_ILOG2_U64
config GENERIC_HWEIGHT
def_bool y

-config GENERIC_TIME
- def_bool y
-
config GENERIC_TIME_VSYSCALL
def_bool y

diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 8a13c1a..23ffcae 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -73,9 +73,6 @@ config GENERIC_CALIBRATE_DELAY
config GENERIC_IOMAP
bool

-config GENERIC_TIME
- def_bool y
-
config GENERIC_CLOCKEVENTS
def_bool n

@@ -446,7 +443,6 @@ config SH_TMU
bool "TMU timer support"
depends on CPU_SH3 || CPU_SH4
default y
- select GENERIC_TIME
select GENERIC_CLOCKEVENTS
help
This enables the use of the TMU as the system timer.
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 1358aab..527efea 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -54,9 +54,6 @@ config BITS
default 32 if SPARC32
default 64 if SPARC64

-config GENERIC_TIME
- def_bool y
-
config ARCH_USES_GETTIMEOFFSET
bool
default y if SPARC32
diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common
index 0d207e7..7c8e277 100644
--- a/arch/um/Kconfig.common
+++ b/arch/um/Kconfig.common
@@ -55,10 +55,6 @@ config GENERIC_BUG
default y
depends on BUG

-config GENERIC_TIME
- bool
- default y
-
config GENERIC_CLOCKEVENTS
bool
default y
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index bc25b9f..c73cb50 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -52,9 +52,6 @@ config ARCH_DEFCONFIG
default "arch/x86/configs/i386_defconfig" if X86_32
default "arch/x86/configs/x86_64_defconfig" if X86_64

-config GENERIC_TIME
- def_bool y
-
config GENERIC_CMOS_UPDATE
def_bool y

@@ -1942,7 +1939,7 @@ config SCx200

config SCx200HR_TIMER
tristate "NatSemi SCx200 27MHz High-Resolution Timer Support"
- depends on SCx200 && GENERIC_TIME
+ depends on SCx200
default y
---help---
This driver provides a clocksource built upon the on-chip
@@ -1954,7 +1951,7 @@ config SCx200HR_TIMER
config GEODE_MFGPT_TIMER
def_bool y
prompt "Geode Multi-Function General Purpose Timer (MFGPT) events"
- depends on MGEODE_LX && GENERIC_TIME && GENERIC_CLOCKEVENTS
+ depends on MGEODE_LX && GENERIC_CLOCKEVENTS
---help---
This driver provides a clock event source based on the MFGPT
timer(s) in the CS5535 and CS5536 companion chip for the geode.
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index fa6dc4d..7bbc6c1 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -48,9 +48,6 @@ config HZ
int
default 100

-config GENERIC_TIME
- def_bool y
-
source "init/Kconfig"
source "kernel/Kconfig.freezer"

diff --git a/drivers/Makefile b/drivers/Makefile
index 2618a61..953bc52 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -97,7 +97,9 @@ obj-$(CONFIG_SGI_SN) += sn/
obj-y += firmware/
obj-$(CONFIG_CRYPTO) += crypto/
obj-$(CONFIG_SUPERH) += sh/
-obj-$(CONFIG_GENERIC_TIME) += clocksource/
+ifndef CONFIG_ARCH_USES_GETTIMEOFFSET
+obj-y += clocksource/
+endif
obj-$(CONFIG_DMA_ENGINE) += dma/
obj-$(CONFIG_DCA) += dca/
obj-$(CONFIG_HID) += hid/
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 6fe1214..84bee72 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -215,7 +215,7 @@ int acpi_processor_resume(struct acpi_device * device)
return 0;
}

-#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
+#if defined (CONFIG_X86)
static int tsc_halts_in_c(int state)
{
switch (boot_cpu_data.x86_vendor) {
@@ -871,7 +871,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
kt2 = ktime_get_real();
idle_time = ktime_to_us(ktime_sub(kt2, kt1));

-#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
+#if defined (CONFIG_X86)
/* TSC could halt in idle, so notify users */
if (tsc_halts_in_c(cx->type))
mark_tsc_unstable("TSC halts in idle");;
@@ -989,7 +989,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
spin_unlock(&c3_lock);
}

-#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
+#if defined (CONFIG_X86)
/* TSC could halt in idle, so notify users */
if (tsc_halts_in_c(ACPI_STATE_C3))
mark_tsc_unstable("TSC halts in idle");
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 6d1ac18..1a2be66 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -32,7 +32,7 @@ config ATMEL_TCLIB

config ATMEL_TCB_CLKSRC
bool "TC Block Clocksource"
- depends on ATMEL_TCLIB && GENERIC_TIME
+ depends on ATMEL_TCLIB
default y
help
Select this to get a high precision clocksource based on a
diff --git a/kernel/time.c b/kernel/time.c
index 2951194..f001888 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -302,22 +302,6 @@ struct timespec timespec_trunc(struct timespec t, unsigned gran)
}
EXPORT_SYMBOL(timespec_trunc);

-#ifndef CONFIG_GENERIC_TIME
-/*
- * Simulate gettimeofday using do_gettimeofday which only allows a timeval
- * and therefore only yields usec accuracy
- */
-void getnstimeofday(struct timespec *tv)
-{
- struct timeval x;
-
- do_gettimeofday(&x);
- tv->tv_sec = x.tv_sec;
- tv->tv_nsec = x.tv_usec * NSEC_PER_USEC;
-}
-EXPORT_SYMBOL_GPL(getnstimeofday);
-#endif
-
/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
* Assumes input in normal date format, i.e. 1980-12-31 23:59:59
* => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
diff --git a/kernel/time/Kconfig b/kernel/time/Kconfig
index 95ed429..f06a8a3 100644
--- a/kernel/time/Kconfig
+++ b/kernel/time/Kconfig
@@ -6,7 +6,7 @@ config TICK_ONESHOT

config NO_HZ
bool "Tickless System (Dynamic Ticks)"
- depends on GENERIC_TIME && GENERIC_CLOCKEVENTS
+ depends on !ARCH_USES_GETTIMEOFFSET && GENERIC_CLOCKEVENTS
select TICK_ONESHOT
help
This option enables a tickless system: timer interrupts will
@@ -15,7 +15,7 @@ config NO_HZ

config HIGH_RES_TIMERS
bool "High Resolution Timer Support"
- depends on GENERIC_TIME && GENERIC_CLOCKEVENTS
+ depends on !ARCH_USES_GETTIMEOFFSET && GENERIC_CLOCKEVENTS
select TICK_ONESHOT
help
This option enables high resolution timer support. If your
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 45d777f..7b0575c 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -59,7 +59,6 @@ void update_xtime_cache(u64 nsec)
struct clocksource *clock;


-#ifdef CONFIG_GENERIC_TIME
/**
* clocksource_forward_now - update clock to the current time
*
@@ -182,6 +181,7 @@ int do_settimeofday(struct timespec *tv)

EXPORT_SYMBOL(do_settimeofday);

+#ifndef CONFIG_ARCH_USES_GETTIMEOFFSET
/**
* change_clocksource - Swaps clocksources if a new one is available
*
@@ -217,7 +217,6 @@ static void change_clocksource(void)
*/
}
#else
-static inline void clocksource_forward_now(void) { }
static inline void change_clocksource(void) { }
#endif

@@ -492,10 +491,10 @@ void update_wall_time(void)
if (unlikely(timekeeping_suspended))
return;

-#ifdef CONFIG_GENERIC_TIME
- offset = (clocksource_read(clock) - clock->cycle_last) & clock->mask;
-#else
+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
offset = clock->cycle_interval;
+#else
+ offset = (clocksource_read(clock) - clock->cycle_last) & clock->mask;
#endif
clock->xtime_nsec = (s64)xtime.tv_nsec << clock->shift;

diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index 417d198..b156fee 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -108,7 +108,7 @@ config IRQSOFF_TRACER
bool "Interrupts-off Latency Tracer"
default n
depends on TRACE_IRQFLAGS_SUPPORT
- depends on GENERIC_TIME
+ depends on !ARCH_USES_GETTIMEOFFSET
select TRACE_IRQFLAGS
select TRACING
select TRACER_MAX_TRACE
@@ -129,7 +129,7 @@ config IRQSOFF_TRACER
config PREEMPT_TRACER
bool "Preemption-off Latency Tracer"
default n
- depends on GENERIC_TIME
+ depends on !ARCH_USES_GETTIMEOFFSET
depends on PREEMPT
select TRACING
select TRACER_MAX_TRACE

2009-04-15 02:51:53

by David Miller

[permalink] [raw]
Subject: Re: [RFC][PATCH 7/8] Convert sparc to use arch_getoffset() infrastructure.

From: john stultz <[email protected]>
Date: Tue, 14 Apr 2009 18:51:26 -0700

> You acked this patch earlier, but I've just tried building with a
> cross-compiler environment I had access to and had problems getting it
> to build.
>
> It seems the pci_do_get/settimeofday() and the bus_do_get/settimeofday()
> redirection code is causing some trouble. I'm really not sure how the
> BTFIXUPSET_CALL code works, so I don't want to just kill it off.
>
> Any advice here on how to do this right?

BTFIXUP is basically a kernel boot time patching service, but
it only works if we can declare function prototypes in the
sparc specific header files.

Since do_gettimeofday() doesn't fall into that requirement, the code
in pci_time_init() is patching the first two instructions of
do_gettimeofday() such that is makes a call to pci_do_gettimeofday().

2009-04-16 07:38:19

by Russell King

[permalink] [raw]
Subject: Re: [RFC][PATCH 2/8] Convert arm to use arch_getoffset() infrastructure.

You really need to also post this (and the generic part) to the
linux-arm-kernel mailing list; there's far too much here for one
person (me) to deal with.

On Tue, Apr 14, 2009 at 06:41:08PM -0700, john stultz wrote:
> This patch converts arm to use GENERIC_TIME via the arch_getoffset()
> infrastructure
>
> I do not have cross compilers for these architectures, and in some cases
> the architectures can be compiles both with and without clocksources. So
> I've taken my best swing at converting this, but I'm not confident I got
> it right. Any assistance from arch maintainers or testers would be
> great.
>
> NOT FOR INCLUSION
> Signed-off-by: John Stultz <[email protected]>
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index e02b893..61c88e1 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -38,7 +38,7 @@ config GENERIC_GPIO
>
> config GENERIC_TIME
> bool
> - default n
> + default y
>
> config GENERIC_CLOCKEVENTS
> bool
> @@ -203,6 +203,7 @@ config ARCH_AAEC2000
> select CPU_ARM920T
> select ARM_AMBA
> select HAVE_CLK
> + select ARCH_USES_GETTIMEOFFSET
> help
> This enables support for systems based on the Agilent AAEC-2000
>
> @@ -212,6 +213,7 @@ config ARCH_INTEGRATOR
> select HAVE_CLK
> select COMMON_CLKDEV
> select ICST525
> + select ARCH_USES_GETTIMEOFFSET
> help
> Support for ARM's Integrator platform.
>
> @@ -221,7 +223,6 @@ config ARCH_REALVIEW
> select HAVE_CLK
> select COMMON_CLKDEV
> select ICST307
> - select GENERIC_TIME
> select GENERIC_CLOCKEVENTS
> help
> This enables support for ARM Ltd RealView boards.
> @@ -233,7 +234,6 @@ config ARCH_VERSATILE
> select HAVE_CLK
> select COMMON_CLKDEV
> select ICST307
> - select GENERIC_TIME
> select GENERIC_CLOCKEVENTS
> help
> This enables support for ARM Ltd Versatile board.
> @@ -243,6 +243,7 @@ config ARCH_AT91
> select GENERIC_GPIO
> select ARCH_REQUIRE_GPIOLIB
> select HAVE_CLK
> + select ARCH_USES_GETTIMEOFFSET
> help
> This enables support for systems based on the Atmel AT91RM9200,
> AT91SAM9 and AT91CAP9 processors.
> @@ -258,6 +259,7 @@ config ARCH_EBSA110
> select CPU_SA110
> select ISA
> select NO_IOPORT
> + select ARCH_USES_GETTIMEOFFSET
> help
> This is an evaluation board for the StrongARM processor available
> from Digital. It has limited hardware on-board, including an
> @@ -273,6 +275,7 @@ config ARCH_EP93XX
> select HAVE_CLK
> select COMMON_CLKDEV
> select ARCH_REQUIRE_GPIOLIB
> + select ARCH_USES_GETTIMEOFFSET
> help
> This enables support for the Cirrus EP93xx series of CPUs.
>
> @@ -288,6 +291,7 @@ config ARCH_FOOTBRIDGE
> bool "FootBridge"
> select CPU_SA110
> select FOOTBRIDGE
> + select ARCH_USES_GETTIMEOFFSET
> help
> Support for systems based on the DC21285 companion chip
> ("FootBridge"), such as the Simtec CATS and the Rebel NetWinder.
> @@ -297,7 +301,6 @@ config ARCH_NETX
> select CPU_ARM926T
> select ARM_VIC
> select GENERIC_CLOCKEVENTS
> - select GENERIC_TIME
> help
> This enables support for systems based on the Hilscher NetX Soc
>
> @@ -305,6 +308,7 @@ config ARCH_H720X
> bool "Hynix HMS720x-based"
> select CPU_ARM720T
> select ISA_DMA_API
> + select ARCH_USES_GETTIMEOFFSET
> help
> This enables support for systems based on the Hynix HMS720x
>
> @@ -312,7 +316,6 @@ config ARCH_IMX
> bool "IMX"
> select CPU_ARM920T
> select GENERIC_GPIO
> - select GENERIC_TIME
> select GENERIC_CLOCKEVENTS
> help
> Support for Motorola's i.MX family of processors (MX1, MXL).
> @@ -325,6 +328,7 @@ config ARCH_IOP13XX
> select PCI
> select ARCH_SUPPORTS_MSI
> select VMSPLIT_1G
> + select ARCH_USES_GETTIMEOFFSET
> help
> Support for Intel's IOP13XX (XScale) family of processors.
>
> @@ -336,6 +340,7 @@ config ARCH_IOP32X
> select PCI
> select GENERIC_GPIO
> select ARCH_REQUIRE_GPIOLIB
> + select ARCH_USES_GETTIMEOFFSET
> help
> Support for Intel's 80219 and IOP32X (XScale) family of
> processors.
> @@ -348,6 +353,7 @@ config ARCH_IOP33X
> select PCI
> select GENERIC_GPIO
> select ARCH_REQUIRE_GPIOLIB
> + select ARCH_USES_GETTIMEOFFSET
> help
> Support for Intel's IOP33X (XScale) family of processors.
>
> @@ -356,6 +362,7 @@ config ARCH_IXP23XX
> depends on MMU
> select CPU_XSC3
> select PCI
> + select ARCH_USES_GETTIMEOFFSET
> help
> Support for Intel's IXP23xx (XScale) family of processors.
>
> @@ -364,6 +371,7 @@ config ARCH_IXP2000
> depends on MMU
> select CPU_XSCALE
> select PCI
> + select ARCH_USES_GETTIMEOFFSET
> help
> Support for Intel's IXP2400/2800 (XScale) family of processors.
>
> @@ -372,7 +380,6 @@ config ARCH_IXP4XX
> depends on MMU
> select CPU_XSCALE
> select GENERIC_GPIO
> - select GENERIC_TIME
> select GENERIC_CLOCKEVENTS
> select DMABOUNCE if PCI
> help
> @@ -382,6 +389,7 @@ config ARCH_L7200
> bool "LinkUp-L7200"
> select CPU_ARM720T
> select FIQ
> + select ARCH_USES_GETTIMEOFFSET
> help
> Say Y here if you intend to run this kernel on a LinkUp Systems
> L7200 Software Development Board which uses an ARM720T processor.
> @@ -397,7 +405,6 @@ config ARCH_KIRKWOOD
> select CPU_FEROCEON
> select PCI
> select GENERIC_GPIO
> - select GENERIC_TIME
> select GENERIC_CLOCKEVENTS
> select PLAT_ORION
> help
> @@ -409,6 +416,7 @@ config ARCH_KS8695
> select CPU_ARM922T
> select GENERIC_GPIO
> select ARCH_REQUIRE_GPIOLIB
> + select ARCH_USES_GETTIMEOFFSET
> help
> Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based
> System-on-Chip devices.
> @@ -417,7 +425,6 @@ config ARCH_NS9XXX
> bool "NetSilicon NS9xxx"
> select CPU_ARM926T
> select GENERIC_GPIO
> - select GENERIC_TIME
> select GENERIC_CLOCKEVENTS
> select HAVE_CLK
> help
> @@ -429,7 +436,6 @@ config ARCH_NS9XXX
> config ARCH_LOKI
> bool "Marvell Loki (88RC8480)"
> select CPU_FEROCEON
> - select GENERIC_TIME
> select GENERIC_CLOCKEVENTS
> select PLAT_ORION
> help
> @@ -440,7 +446,6 @@ config ARCH_MV78XX0
> select CPU_FEROCEON
> select PCI
> select GENERIC_GPIO
> - select GENERIC_TIME
> select GENERIC_CLOCKEVENTS
> select PLAT_ORION
> help
> @@ -449,7 +454,6 @@ config ARCH_MV78XX0
>
> config ARCH_MXC
> bool "Freescale MXC/iMX-based"
> - select GENERIC_TIME
> select GENERIC_CLOCKEVENTS
> select ARCH_MTD_XIP
> select GENERIC_GPIO
> @@ -463,7 +467,6 @@ config ARCH_ORION5X
> select CPU_FEROCEON
> select PCI
> select GENERIC_GPIO
> - select GENERIC_TIME
> select GENERIC_CLOCKEVENTS
> select PLAT_ORION
> help
> @@ -475,6 +478,7 @@ config ARCH_PNX4008
> bool "Philips Nexperia PNX4008 Mobile"
> select CPU_ARM926T
> select HAVE_CLK
> + select ARCH_USES_GETTIMEOFFSET
> help
> This enables support for Philips PNX4008 mobile platform.
>
> @@ -488,7 +492,6 @@ config ARCH_PXA
> select ARCH_REQUIRE_GPIOLIB
> select HAVE_CLK
> select COMMON_CLKDEV
> - select GENERIC_TIME
> select GENERIC_CLOCKEVENTS
> select TICK_ONESHOT
> select PLAT_PXA
> @@ -502,7 +505,6 @@ config ARCH_MMP
> select ARCH_REQUIRE_GPIOLIB
> select HAVE_CLK
> select COMMON_CLKDEV
> - select GENERIC_TIME
> select GENERIC_CLOCKEVENTS
> select TICK_ONESHOT
> select PLAT_PXA
> @@ -519,6 +521,7 @@ config ARCH_RPC
> select ISA_DMA_API
> select NO_IOPORT
> select ARCH_SPARSEMEM_ENABLE
> + select ARCH_USES_GETTIMEOFFSET
> help
> On the Acorn Risc-PC, Linux can support the internal IDE disk and
> CD-ROM interface, serial and parallel port, and the floppy drive.
> @@ -530,7 +533,6 @@ config ARCH_SA1100
> select ARCH_SPARSEMEM_ENABLE
> select ARCH_MTD_XIP
> select GENERIC_GPIO
> - select GENERIC_TIME
> select GENERIC_CLOCKEVENTS
> select HAVE_CLK
> select TICK_ONESHOT
> @@ -542,6 +544,7 @@ config ARCH_S3C2410
> bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443"
> select GENERIC_GPIO
> select HAVE_CLK
> + select ARCH_USES_GETTIMEOFFSET
> help
> Samsung S3C2410X CPU based systems, such as the Simtec Electronics
> BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or
> @@ -551,6 +554,7 @@ config ARCH_S3C64XX
> bool "Samsung S3C64XX"
> select GENERIC_GPIO
> select HAVE_CLK
> + select ARCH_USES_GETTIMEOFFSET
> help
> Samsung S3C64XX series based systems
>
> @@ -561,6 +565,7 @@ config ARCH_SHARK
> select ISA_DMA
> select ZONE_DMA
> select PCI
> + select ARCH_USES_GETTIMEOFFSET
> help
> Support for the StrongARM based Digital DNARD machine, also known
> as "Shark" (<http://www.shark-linux.de/shark.html>).
> @@ -570,6 +575,7 @@ config ARCH_LH7A40X
> select CPU_ARM922T
> select ARCH_DISCONTIGMEM_ENABLE if !LH7A40X_CONTIGMEM
> select ARCH_SPARSEMEM_ENABLE if !LH7A40X_CONTIGMEM
> + select ARCH_USES_GETTIMEOFFSET
> help
> Say Y here for systems based on one of the Sharp LH7A40X
> System on a Chip processors. These CPUs include an ARM922T
> @@ -579,7 +585,6 @@ config ARCH_LH7A40X
> config ARCH_DAVINCI
> bool "TI DaVinci"
> select CPU_ARM926T
> - select GENERIC_TIME
> select GENERIC_CLOCKEVENTS
> select GENERIC_GPIO
> select ARCH_REQUIRE_GPIOLIB
> @@ -593,7 +598,6 @@ config ARCH_OMAP
> select GENERIC_GPIO
> select HAVE_CLK
> select ARCH_REQUIRE_GPIOLIB
> - select GENERIC_TIME
> select GENERIC_CLOCKEVENTS
> help
> Support for TI's OMAP platform (OMAP1 and OMAP2).
> @@ -601,7 +605,6 @@ config ARCH_OMAP
> config ARCH_MSM
> bool "Qualcomm MSM"
> select CPU_V6
> - select GENERIC_TIME
> select GENERIC_CLOCKEVENTS
> help
> Support for Qualcomm MSM7K based systems. This runs on the ARM11
> @@ -612,6 +615,7 @@ config ARCH_MSM
> config ARCH_W90X900
> bool "Nuvoton W90X900 CPU"
> select CPU_ARM926T
> + select ARCH_USES_GETTIMEOFFSET
> help
> Support for Nuvoton (Winbond logic dept.) ARM9 processor,You
> can login http://www.mcuos.com or http://www.nuvoton.com to know more.
> diff --git a/arch/arm/include/asm/mach/time.h b/arch/arm/include/asm/mach/time.h
> index b2cc1fc..20c1d84 100644
> --- a/arch/arm/include/asm/mach/time.h
> +++ b/arch/arm/include/asm/mach/time.h
> @@ -38,7 +38,7 @@ struct sys_timer {
> void (*init)(void);
> void (*suspend)(void);
> void (*resume)(void);
> -#ifndef CONFIG_GENERIC_TIME
> +#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
> unsigned long (*offset)(void);
> #endif
> };
> diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
> index 4cdc4a0..d9d8d6d 100644
> --- a/arch/arm/kernel/time.c
> +++ b/arch/arm/kernel/time.c
> @@ -81,7 +81,7 @@ EXPORT_SYMBOL(profile_pc);
> */
> int (*set_rtc)(void);
>
> -#ifndef CONFIG_GENERIC_TIME
> +#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
> static unsigned long dummy_gettimeoffset(void)
> {
> return 0;
> @@ -236,63 +236,12 @@ static inline void do_leds(void)
> #define do_leds()
> #endif
>
> -#ifndef CONFIG_GENERIC_TIME
> -void do_gettimeofday(struct timeval *tv)
> +#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
> +u32 arch_gettimeoffset(void)
> {
> - unsigned long flags;
> - unsigned long seq;
> - unsigned long usec, sec;
> -
> - do {
> - seq = read_seqbegin_irqsave(&xtime_lock, flags);
> - usec = system_timer->offset();
> - sec = xtime.tv_sec;
> - usec += xtime.tv_nsec / 1000;
> - } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
> -
> - /* usec may have gone up a lot: be safe */
> - while (usec >= 1000000) {
> - usec -= 1000000;
> - sec++;
> - }
> -
> - tv->tv_sec = sec;
> - tv->tv_usec = usec;
> -}
> -
> -EXPORT_SYMBOL(do_gettimeofday);
> -
> -int do_settimeofday(struct timespec *tv)
> -{
> - time_t wtm_sec, sec = tv->tv_sec;
> - long wtm_nsec, nsec = tv->tv_nsec;
> -
> - if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
> - return -EINVAL;
> -
> - write_seqlock_irq(&xtime_lock);
> - /*
> - * This is revolting. We need to set "xtime" correctly. However, the
> - * value in this location is the value at the most recent update of
> - * wall time. Discover what correction gettimeofday() would have
> - * done, and then undo it!
> - */
> - nsec -= system_timer->offset() * NSEC_PER_USEC;
> -
> - wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
> - wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
> -
> - set_normalized_timespec(&xtime, sec, nsec);
> - set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
> -
> - ntp_clear();
> - write_sequnlock_irq(&xtime_lock);
> - clock_was_set();
> - return 0;
> + return system_timer->offset() * 1000;
> }
> -
> -EXPORT_SYMBOL(do_settimeofday);
> -#endif /* !CONFIG_GENERIC_TIME */
> +#endif /* CONFIG_ARCH_USES_GETTIMEOFFSET */
>
> /**
> * save_time_delta - Save the offset between system time and RTC time
> @@ -391,7 +340,7 @@ device_initcall(timer_init_sysfs);
>
> void __init time_init(void)
> {
> -#ifndef CONFIG_GENERIC_TIME
> +#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
> if (system_timer->offset == NULL)
> system_timer->offset = dummy_gettimeoffset;
> #endif
> diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
> index 323b47f..e82979c 100644
> --- a/arch/arm/mach-at91/Kconfig
> +++ b/arch/arm/mach-at91/Kconfig
> @@ -8,47 +8,41 @@ choice
> config ARCH_AT91RM9200
> bool "AT91RM9200"
> select CPU_ARM920T
> - select GENERIC_TIME
> select GENERIC_CLOCKEVENTS
>
> config ARCH_AT91SAM9260
> bool "AT91SAM9260 or AT91SAM9XE"
> select CPU_ARM926T
> - select GENERIC_TIME
> select GENERIC_CLOCKEVENTS
>
> config ARCH_AT91SAM9261
> bool "AT91SAM9261"
> select CPU_ARM926T
> - select GENERIC_TIME
> select GENERIC_CLOCKEVENTS
>
> config ARCH_AT91SAM9263
> bool "AT91SAM9263"
> select CPU_ARM926T
> - select GENERIC_TIME
> select GENERIC_CLOCKEVENTS
>
> config ARCH_AT91SAM9RL
> bool "AT91SAM9RL"
> select CPU_ARM926T
> - select GENERIC_TIME
> select GENERIC_CLOCKEVENTS
>
> config ARCH_AT91SAM9G20
> bool "AT91SAM9G20"
> select CPU_ARM926T
> - select GENERIC_TIME
> select GENERIC_CLOCKEVENTS
>
> config ARCH_AT91CAP9
> bool "AT91CAP9"
> select CPU_ARM926T
> - select GENERIC_TIME
> select GENERIC_CLOCKEVENTS
>
> config ARCH_AT91X40
> bool "AT91x40"
> + select ARCH_USES_GETTIMEOFFSET
>
> endchoice
>
>
>

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: