* [patch 0/3] Provide generic function to calc mult/shift factors for clocks
@ 2009-11-11 14:05 Thomas Gleixner
2009-11-11 14:05 ` [patch 1/3] clockevents: Use u32 for mult and shift factors Thomas Gleixner
` (5 more replies)
0 siblings, 6 replies; 10+ messages in thread
From: Thomas Gleixner @ 2009-11-11 14:05 UTC (permalink / raw)
To: LKML
Cc: Mikael Pettersson, Ralf Baechle, Linus Walleij, John Stultz,
Ingo Molnar
The MIPS tree has functions to calculate the mult/shift factors for
clock events and clock sources. ARM needs such functions as well.
This patch set provides a generic function which replaces the MIPS
implementation.
Thanks,
tglx
^ permalink raw reply [flat|nested] 10+ messages in thread
* [patch 1/3] clockevents: Use u32 for mult and shift factors
2009-11-11 14:05 [patch 0/3] Provide generic function to calc mult/shift factors for clocks Thomas Gleixner
@ 2009-11-11 14:05 ` Thomas Gleixner
2009-11-13 19:48 ` [tip:timers/core] " tip-bot for Thomas Gleixner
2009-11-11 14:05 ` [patch 2/3] clocksource: Provide a generic mult/shift factor calculation Thomas Gleixner
` (4 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Thomas Gleixner @ 2009-11-11 14:05 UTC (permalink / raw)
To: LKML
Cc: Mikael Pettersson, Ralf Baechle, Linus Walleij, John Stultz,
Ingo Molnar
[-- Attachment #1: clockevents-use-u32-for-mult-and-shift-factors.patch --]
[-- Type: text/plain, Size: 1985 bytes --]
The mult and shift factors of clock events differ in their data type
from those of clock sources for no reason. u32 is sufficient for
both. shift is always <= 32 and mult is limited to 2^32-1 to avoid
64bit multiplication overflows in the conversion.
Preparatory patch for a generic mult/shift factor calculation
function.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Mikael Pettersson <mikpe@it.uu.se>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Linus Walleij <linus.walleij@stericsson.com>
Cc: John Stultz <johnstul@us.ibm.com>
Cc: Ingo Molnar <mingo@elte.hu>
---
include/linux/clockchips.h | 4 ++--
kernel/time/timer_list.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
Index: linux-2.6-tip/include/linux/clockchips.h
===================================================================
--- linux-2.6-tip.orig/include/linux/clockchips.h
+++ linux-2.6-tip/include/linux/clockchips.h
@@ -79,8 +79,8 @@ struct clock_event_device {
unsigned int features;
unsigned long max_delta_ns;
unsigned long min_delta_ns;
- unsigned long mult;
- int shift;
+ u32 mult;
+ u32 shift;
int rating;
int irq;
const struct cpumask *cpumask;
Index: linux-2.6-tip/kernel/time/timer_list.c
===================================================================
--- linux-2.6-tip.orig/kernel/time/timer_list.c
+++ linux-2.6-tip/kernel/time/timer_list.c
@@ -206,8 +206,8 @@ print_tickdevice(struct seq_file *m, str
SEQ_printf(m, "%s\n", dev->name);
SEQ_printf(m, " max_delta_ns: %lu\n", dev->max_delta_ns);
SEQ_printf(m, " min_delta_ns: %lu\n", dev->min_delta_ns);
- SEQ_printf(m, " mult: %lu\n", dev->mult);
- SEQ_printf(m, " shift: %d\n", dev->shift);
+ SEQ_printf(m, " mult: %u\n", dev->mult);
+ SEQ_printf(m, " shift: %u\n", dev->shift);
SEQ_printf(m, " mode: %d\n", dev->mode);
SEQ_printf(m, " next_event: %Ld nsecs\n",
(unsigned long long) ktime_to_ns(dev->next_event));
^ permalink raw reply [flat|nested] 10+ messages in thread
* [patch 2/3] clocksource: Provide a generic mult/shift factor calculation
2009-11-11 14:05 [patch 0/3] Provide generic function to calc mult/shift factors for clocks Thomas Gleixner
2009-11-11 14:05 ` [patch 1/3] clockevents: Use u32 for mult and shift factors Thomas Gleixner
@ 2009-11-11 14:05 ` Thomas Gleixner
2009-11-13 19:49 ` [tip:timers/core] " tip-bot for Thomas Gleixner
2009-11-11 14:05 ` [patch 3/3] mips: Use generic mult/shift factor calculation for clocks Thomas Gleixner
` (3 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Thomas Gleixner @ 2009-11-11 14:05 UTC (permalink / raw)
To: LKML
Cc: Mikael Pettersson, Ralf Baechle, Linus Walleij, John Stultz,
Ingo Molnar
[-- Attachment #1: clocks-provide-generic-shift-mult-calc.patch --]
[-- Type: text/plain, Size: 4877 bytes --]
MIPS has two functions to calculcate the mult/shift factors for clock
sources and clock events at run time. ARM needs such functions as
well.
Implement a function which calculates the mult/shift factors based on
the frequencies to which and from which is converted. The function
also has a parameter to specify the minimum conversion range in
seconds. This range is guaranteed not to produce a 64bit overflow when
a value is multiplied with the calculated mult factor. The larger the
conversion range the less becomes the conversion accuracy.
Provide two inline wrappers which handle clock events and clock
sources. For clock events the "from" frequency is nano seconds per
second which corresponds to 1GHz and "to" is the device frequency. For
clock sources "from" is the device frequency and "to" is nano seconds
per second.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Mikael Pettersson <mikpe@it.uu.se>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Linus Walleij <linus.walleij@stericsson.com>
Cc: John Stultz <johnstul@us.ibm.com>
Cc: Ingo Molnar <mingo@elte.hu>
---
include/linux/clockchips.h | 7 +++++
include/linux/clocksource.h | 10 ++++++++
kernel/time/clocksource.c | 53 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 70 insertions(+)
Index: linux-2.6-tip/include/linux/clockchips.h
===================================================================
--- linux-2.6-tip.orig/include/linux/clockchips.h
+++ linux-2.6-tip/include/linux/clockchips.h
@@ -130,6 +130,13 @@ extern int clockevents_program_event(str
extern void clockevents_handle_noop(struct clock_event_device *dev);
+static inline void
+clockevents_calc_mult_shift(struct clock_event_device *ce, u32 freq, u32 minsec)
+{
+ return clocks_calc_mult_shift(&ce->mult, &ce->shift, NSEC_PER_SEC,
+ freq, minsec);
+}
+
#ifdef CONFIG_GENERIC_CLOCKEVENTS
extern void clockevents_notify(unsigned long reason, void *arg);
#else
Index: linux-2.6-tip/include/linux/clocksource.h
===================================================================
--- linux-2.6-tip.orig/include/linux/clocksource.h
+++ linux-2.6-tip/include/linux/clocksource.h
@@ -279,6 +279,16 @@ extern void clocksource_resume(void);
extern struct clocksource * __init __weak clocksource_default_clock(void);
extern void clocksource_mark_unstable(struct clocksource *cs);
+extern void
+clocks_calc_mult_shift(u32 *mult, u32 *shift, u32 from, u32 to, u32 minsec);
+
+static inline void
+clocksource_calc_mult_shift(struct clocksource *cs, u32 freq, u32 minsec)
+{
+ return clocks_calc_mult_shift(&cs->mult, &cs->shift, freq,
+ NSEC_PER_SEC, minsec);
+}
+
#ifdef CONFIG_GENERIC_TIME_VSYSCALL
extern void update_vsyscall(struct timespec *ts, struct clocksource *c);
extern void update_vsyscall_tz(void);
Index: linux-2.6-tip/kernel/time/clocksource.c
===================================================================
--- linux-2.6-tip.orig/kernel/time/clocksource.c
+++ linux-2.6-tip/kernel/time/clocksource.c
@@ -107,6 +107,59 @@ u64 timecounter_cyc2time(struct timecoun
}
EXPORT_SYMBOL(timecounter_cyc2time);
+/**
+ * clocks_calc_mult_shift - calculate mult/shift factors for scaled math of clocks
+ * @mult: pointer to mult variable
+ * @shift: pointer to shift variable
+ * @from: frequency to convert from
+ * @to: frequency to convert to
+ * @minsec: guaranteed runtime conversion range in seconds
+ *
+ * The function evaluates the shift/mult pair for the scaled math
+ * operations of clocksources and clockevents.
+ *
+ * @to and @from are frequency values in HZ. For clock sources @to is
+ * NSEC_PER_SEC == 1GHz and @from is the counter frequency. For clock
+ * event @to is the counter frequency and @from is NSEC_PER_SEC.
+ *
+ * The @minsec conversion range argument controls the time frame in
+ * seconds which must be covered by the runtime conversion with the
+ * calculated mult and shift factors. This guarantees that no 64bit
+ * overflow happens when the input value of the conversion is
+ * multiplied with the calculated mult factor. Larger ranges may
+ * reduce the conversion accuracy by chosing smaller mult and shift
+ * factors.
+ */
+void
+clocks_calc_mult_shift(u32 *mult, u32 *shift, u32 from, u32 to, u32 minsec)
+{
+ u64 tmp;
+ u32 sft, sftacc= 32;
+
+ /*
+ * Calculate the shift factor which is limiting the conversion
+ * range:
+ */
+ tmp = ((u64)minsec * from) >> 32;
+ while (tmp) {
+ tmp >>=1;
+ sftacc--;
+ }
+
+ /*
+ * Find the conversion shift/mult pair which has the best
+ * accuracy and fits the maxsec conversion range:
+ */
+ for (sft = 32; sft > 0; sft--) {
+ tmp = (u64) to << sft;
+ do_div(tmp, from);
+ if ((tmp >> sftacc) == 0)
+ break;
+ }
+ *mult = tmp;
+ *shift = sft;
+}
+
/*[Clocksource internal variables]---------
* curr_clocksource:
* currently selected clocksource.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [patch 3/3] mips: Use generic mult/shift factor calculation for clocks
2009-11-11 14:05 [patch 0/3] Provide generic function to calc mult/shift factors for clocks Thomas Gleixner
2009-11-11 14:05 ` [patch 1/3] clockevents: Use u32 for mult and shift factors Thomas Gleixner
2009-11-11 14:05 ` [patch 2/3] clocksource: Provide a generic mult/shift factor calculation Thomas Gleixner
@ 2009-11-11 14:05 ` Thomas Gleixner
2009-11-13 19:49 ` [tip:timers/core] " tip-bot for Thomas Gleixner
2009-11-11 14:08 ` [patch 0/3] Provide generic function to calc mult/shift factors forclocks Linus Walleij
` (2 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Thomas Gleixner @ 2009-11-11 14:05 UTC (permalink / raw)
To: LKML
Cc: Mikael Pettersson, Ralf Baechle, Linus Walleij, John Stultz,
Ingo Molnar
[-- Attachment #1: mips-use-generic-shift-mult-calculation.patch --]
[-- Type: text/plain, Size: 2591 bytes --]
Replace the MIPS functions of mult/shift factor calculation for clock
events and clock sources with inline functions which call the generic
functions. The minimum guaranteed conversion range is set to 4 seconds
which corresponds to the current MIPS implementation.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Mikael Pettersson <mikpe@it.uu.se>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Linus Walleij <linus.walleij@stericsson.com>
Cc: John Stultz <johnstul@us.ibm.com>
Cc: Ingo Molnar <mingo@elte.hu>
---
arch/mips/include/asm/time.h | 14 +++++++++++---
arch/mips/kernel/time.c | 33 ---------------------------------
2 files changed, 11 insertions(+), 36 deletions(-)
Index: linux-2.6-tip/arch/mips/include/asm/time.h
===================================================================
--- linux-2.6-tip.orig/arch/mips/include/asm/time.h
+++ linux-2.6-tip/arch/mips/include/asm/time.h
@@ -84,8 +84,16 @@ static inline int init_mips_clocksource(
#endif
}
-extern void clocksource_set_clock(struct clocksource *cs, unsigned int clock);
-extern void clockevent_set_clock(struct clock_event_device *cd,
- unsigned int clock);
+static inline void clocksource_set_clock(struct clocksource *cs,
+ unsigned int clock)
+{
+ clocksource_calc_mult_shift(cs, clock, 4);
+}
+
+static inline void clockevent_set_clock(struct clock_event_device *cd,
+ unsigned int clock)
+{
+ clockevents_calc_mult_shift(cd, clock, 4);
+}
#endif /* _ASM_TIME_H */
Index: linux-2.6-tip/arch/mips/kernel/time.c
===================================================================
--- linux-2.6-tip.orig/arch/mips/kernel/time.c
+++ linux-2.6-tip/arch/mips/kernel/time.c
@@ -71,39 +71,6 @@ EXPORT_SYMBOL(perf_irq);
unsigned int mips_hpt_frequency;
-void __init clocksource_set_clock(struct clocksource *cs, unsigned int clock)
-{
- u64 temp;
- u32 shift;
-
- /* Find a shift value */
- for (shift = 32; shift > 0; shift--) {
- temp = (u64) NSEC_PER_SEC << shift;
- do_div(temp, clock);
- if ((temp >> 32) == 0)
- break;
- }
- cs->shift = shift;
- cs->mult = (u32) temp;
-}
-
-void __cpuinit clockevent_set_clock(struct clock_event_device *cd,
- unsigned int clock)
-{
- u64 temp;
- u32 shift;
-
- /* Find a shift value */
- for (shift = 32; shift > 0; shift--) {
- temp = (u64) clock << shift;
- do_div(temp, NSEC_PER_SEC);
- if ((temp >> 32) == 0)
- break;
- }
- cd->shift = shift;
- cd->mult = (u32) temp;
-}
-
/*
* This function exists in order to cause an error due to a duplicate
* definition if platform code should have its own implementation. The hook
^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: [patch 0/3] Provide generic function to calc mult/shift factors forclocks
2009-11-11 14:05 [patch 0/3] Provide generic function to calc mult/shift factors for clocks Thomas Gleixner
` (2 preceding siblings ...)
2009-11-11 14:05 ` [patch 3/3] mips: Use generic mult/shift factor calculation for clocks Thomas Gleixner
@ 2009-11-11 14:08 ` Linus Walleij
2009-11-12 11:37 ` [patch 0/3] Provide generic function to calc mult/shift factors for clocks Ralf Baechle
2009-11-12 16:59 ` Mikael Pettersson
5 siblings, 0 replies; 10+ messages in thread
From: Linus Walleij @ 2009-11-11 14:08 UTC (permalink / raw)
To: Thomas Gleixner, LKML
Cc: Mikael Pettersson, Ralf Baechle, John Stultz, Ingo Molnar
[tglx]
> This patch set provides a generic function which replaces the MIPS
> implementation.
Sweet as pie!
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Linus Walleij
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [patch 0/3] Provide generic function to calc mult/shift factors for clocks
2009-11-11 14:05 [patch 0/3] Provide generic function to calc mult/shift factors for clocks Thomas Gleixner
` (3 preceding siblings ...)
2009-11-11 14:08 ` [patch 0/3] Provide generic function to calc mult/shift factors forclocks Linus Walleij
@ 2009-11-12 11:37 ` Ralf Baechle
2009-11-12 16:59 ` Mikael Pettersson
5 siblings, 0 replies; 10+ messages in thread
From: Ralf Baechle @ 2009-11-12 11:37 UTC (permalink / raw)
To: Thomas Gleixner
Cc: LKML, Mikael Pettersson, Linus Walleij, John Stultz, Ingo Molnar
On Wed, Nov 11, 2009 at 02:05:19PM -0000, Thomas Gleixner wrote:
> The MIPS tree has functions to calculate the mult/shift factors for
> clock events and clock sources. ARM needs such functions as well.
>
> This patch set provides a generic function which replaces the MIPS
> implementation.
Looks good to me, feel free to throw in my Ack-by. I suggest you merge the
MIPS part of the series through your tree.
Ralf
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [patch 0/3] Provide generic function to calc mult/shift factors for clocks
2009-11-11 14:05 [patch 0/3] Provide generic function to calc mult/shift factors for clocks Thomas Gleixner
` (4 preceding siblings ...)
2009-11-12 11:37 ` [patch 0/3] Provide generic function to calc mult/shift factors for clocks Ralf Baechle
@ 2009-11-12 16:59 ` Mikael Pettersson
5 siblings, 0 replies; 10+ messages in thread
From: Mikael Pettersson @ 2009-11-12 16:59 UTC (permalink / raw)
To: Thomas Gleixner
Cc: LKML, Mikael Pettersson, Ralf Baechle, Linus Walleij, John Stultz,
Ingo Molnar
Thomas Gleixner writes:
> The MIPS tree has functions to calculate the mult/shift factors for
> clock events and clock sources. ARM needs such functions as well.
>
> This patch set provides a generic function which replaces the MIPS
> implementation.
I rebased my ARM IOP clocksource/clockevent patch kit on these
generic functions, and it works fine and results in the exact
same shift/mult values as with my clone of the MIPS code.
Tested-by: Mikael Pettersson <mikpe@it.uu.se>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [tip:timers/core] clockevents: Use u32 for mult and shift factors
2009-11-11 14:05 ` [patch 1/3] clockevents: Use u32 for mult and shift factors Thomas Gleixner
@ 2009-11-13 19:48 ` tip-bot for Thomas Gleixner
0 siblings, 0 replies; 10+ messages in thread
From: tip-bot for Thomas Gleixner @ 2009-11-13 19:48 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, hpa, mingo, linus.walleij, johnstul, mikpe, ralf,
tglx
Commit-ID: 23af368e9a904f59256c27d371ce223d6cee0430
Gitweb: http://git.kernel.org/tip/23af368e9a904f59256c27d371ce223d6cee0430
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Wed, 11 Nov 2009 14:05:25 +0000
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitDate: Fri, 13 Nov 2009 20:46:23 +0100
clockevents: Use u32 for mult and shift factors
The mult and shift factors of clock events differ in their data type
from those of clock sources for no reason. u32 is sufficient for
both. shift is always <= 32 and mult is limited to 2^32-1 to avoid
64bit multiplication overflows in the conversion.
Preparatory patch for a generic mult/shift factor calculation
function.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Mikael Pettersson <mikpe@it.uu.se>
Acked-by: Ralf Baechle <ralf@linux-mips.org>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Cc: John Stultz <johnstul@us.ibm.com>
LKML-Reference: <20091111134229.725664788@linutronix.de>
---
include/linux/clockchips.h | 4 ++--
kernel/time/timer_list.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
index 3a1dbba..3b58410 100644
--- a/include/linux/clockchips.h
+++ b/include/linux/clockchips.h
@@ -79,8 +79,8 @@ struct clock_event_device {
unsigned int features;
unsigned long max_delta_ns;
unsigned long min_delta_ns;
- unsigned long mult;
- int shift;
+ u32 mult;
+ u32 shift;
int rating;
int irq;
const struct cpumask *cpumask;
diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c
index 1b5b7aa..fa00da1 100644
--- a/kernel/time/timer_list.c
+++ b/kernel/time/timer_list.c
@@ -206,8 +206,8 @@ print_tickdevice(struct seq_file *m, struct tick_device *td, int cpu)
SEQ_printf(m, "%s\n", dev->name);
SEQ_printf(m, " max_delta_ns: %lu\n", dev->max_delta_ns);
SEQ_printf(m, " min_delta_ns: %lu\n", dev->min_delta_ns);
- SEQ_printf(m, " mult: %lu\n", dev->mult);
- SEQ_printf(m, " shift: %d\n", dev->shift);
+ SEQ_printf(m, " mult: %u\n", dev->mult);
+ SEQ_printf(m, " shift: %u\n", dev->shift);
SEQ_printf(m, " mode: %d\n", dev->mode);
SEQ_printf(m, " next_event: %Ld nsecs\n",
(unsigned long long) ktime_to_ns(dev->next_event));
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [tip:timers/core] clocksource: Provide a generic mult/shift factor calculation
2009-11-11 14:05 ` [patch 2/3] clocksource: Provide a generic mult/shift factor calculation Thomas Gleixner
@ 2009-11-13 19:49 ` tip-bot for Thomas Gleixner
0 siblings, 0 replies; 10+ messages in thread
From: tip-bot for Thomas Gleixner @ 2009-11-13 19:49 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, hpa, mingo, linus.walleij, johnstul, mikpe, ralf,
tglx
Commit-ID: 7d2f944a2b836c69a9d260a0a5f0d1720d57fdff
Gitweb: http://git.kernel.org/tip/7d2f944a2b836c69a9d260a0a5f0d1720d57fdff
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Wed, 11 Nov 2009 14:05:29 +0000
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitDate: Fri, 13 Nov 2009 20:46:23 +0100
clocksource: Provide a generic mult/shift factor calculation
MIPS has two functions to calculcate the mult/shift factors for clock
sources and clock events at run time. ARM needs such functions as
well.
Implement a function which calculates the mult/shift factors based on
the frequencies to which and from which is converted. The function
also has a parameter to specify the minimum conversion range in
seconds. This range is guaranteed not to produce a 64bit overflow when
a value is multiplied with the calculated mult factor. The larger the
conversion range the less becomes the conversion accuracy.
Provide two inline wrappers which handle clock events and clock
sources. For clock events the "from" frequency is nano seconds per
second which corresponds to 1GHz and "to" is the device frequency. For
clock sources "from" is the device frequency and "to" is nano seconds
per second.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Mikael Pettersson <mikpe@it.uu.se>
Acked-by: Ralf Baechle <ralf@linux-mips.org>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Cc: John Stultz <johnstul@us.ibm.com>
LKML-Reference: <20091111134229.766673305@linutronix.de>
---
include/linux/clockchips.h | 7 +++++
include/linux/clocksource.h | 10 ++++++++
kernel/time/clocksource.c | 53 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 70 insertions(+), 0 deletions(-)
diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
index 3b58410..4d438b0 100644
--- a/include/linux/clockchips.h
+++ b/include/linux/clockchips.h
@@ -130,6 +130,13 @@ extern int clockevents_program_event(struct clock_event_device *dev,
extern void clockevents_handle_noop(struct clock_event_device *dev);
+static inline void
+clockevents_calc_mult_shift(struct clock_event_device *ce, u32 freq, u32 minsec)
+{
+ return clocks_calc_mult_shift(&ce->mult, &ce->shift, NSEC_PER_SEC,
+ freq, minsec);
+}
+
#ifdef CONFIG_GENERIC_CLOCKEVENTS
extern void clockevents_notify(unsigned long reason, void *arg);
#else
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
index 83d2fbd..f57f882 100644
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -279,6 +279,16 @@ extern void clocksource_resume(void);
extern struct clocksource * __init __weak clocksource_default_clock(void);
extern void clocksource_mark_unstable(struct clocksource *cs);
+extern void
+clocks_calc_mult_shift(u32 *mult, u32 *shift, u32 from, u32 to, u32 minsec);
+
+static inline void
+clocksource_calc_mult_shift(struct clocksource *cs, u32 freq, u32 minsec)
+{
+ return clocks_calc_mult_shift(&cs->mult, &cs->shift, freq,
+ NSEC_PER_SEC, minsec);
+}
+
#ifdef CONFIG_GENERIC_TIME_VSYSCALL
extern void update_vsyscall(struct timespec *ts, struct clocksource *c);
extern void update_vsyscall_tz(void);
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index 5e18c6a..407c089 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -107,6 +107,59 @@ u64 timecounter_cyc2time(struct timecounter *tc,
}
EXPORT_SYMBOL(timecounter_cyc2time);
+/**
+ * clocks_calc_mult_shift - calculate mult/shift factors for scaled math of clocks
+ * @mult: pointer to mult variable
+ * @shift: pointer to shift variable
+ * @from: frequency to convert from
+ * @to: frequency to convert to
+ * @minsec: guaranteed runtime conversion range in seconds
+ *
+ * The function evaluates the shift/mult pair for the scaled math
+ * operations of clocksources and clockevents.
+ *
+ * @to and @from are frequency values in HZ. For clock sources @to is
+ * NSEC_PER_SEC == 1GHz and @from is the counter frequency. For clock
+ * event @to is the counter frequency and @from is NSEC_PER_SEC.
+ *
+ * The @minsec conversion range argument controls the time frame in
+ * seconds which must be covered by the runtime conversion with the
+ * calculated mult and shift factors. This guarantees that no 64bit
+ * overflow happens when the input value of the conversion is
+ * multiplied with the calculated mult factor. Larger ranges may
+ * reduce the conversion accuracy by chosing smaller mult and shift
+ * factors.
+ */
+void
+clocks_calc_mult_shift(u32 *mult, u32 *shift, u32 from, u32 to, u32 minsec)
+{
+ u64 tmp;
+ u32 sft, sftacc= 32;
+
+ /*
+ * Calculate the shift factor which is limiting the conversion
+ * range:
+ */
+ tmp = ((u64)minsec * from) >> 32;
+ while (tmp) {
+ tmp >>=1;
+ sftacc--;
+ }
+
+ /*
+ * Find the conversion shift/mult pair which has the best
+ * accuracy and fits the maxsec conversion range:
+ */
+ for (sft = 32; sft > 0; sft--) {
+ tmp = (u64) to << sft;
+ do_div(tmp, from);
+ if ((tmp >> sftacc) == 0)
+ break;
+ }
+ *mult = tmp;
+ *shift = sft;
+}
+
/*[Clocksource internal variables]---------
* curr_clocksource:
* currently selected clocksource.
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [tip:timers/core] mips: Use generic mult/shift factor calculation for clocks
2009-11-11 14:05 ` [patch 3/3] mips: Use generic mult/shift factor calculation for clocks Thomas Gleixner
@ 2009-11-13 19:49 ` tip-bot for Thomas Gleixner
0 siblings, 0 replies; 10+ messages in thread
From: tip-bot for Thomas Gleixner @ 2009-11-13 19:49 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, hpa, mingo, linus.walleij, johnstul, mikpe, ralf,
tglx
Commit-ID: e3a4fab0c0c30e21e104712f4e9cb39f175d0f21
Gitweb: http://git.kernel.org/tip/e3a4fab0c0c30e21e104712f4e9cb39f175d0f21
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Wed, 11 Nov 2009 14:05:34 +0000
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitDate: Fri, 13 Nov 2009 20:46:24 +0100
mips: Use generic mult/shift factor calculation for clocks
Replace the MIPS functions of mult/shift factor calculation for clock
events and clock sources with inline functions which call the generic
functions. The minimum guaranteed conversion range is set to 4 seconds
which corresponds to the current MIPS implementation.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Mikael Pettersson <mikpe@it.uu.se>
Acked-by: Ralf Baechle <ralf@linux-mips.org>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Cc: John Stultz <johnstul@us.ibm.com>
LKML-Reference: <20091111134229.807255074@linutronix.de>
---
arch/mips/include/asm/time.h | 14 +++++++++++---
arch/mips/kernel/time.c | 33 ---------------------------------
2 files changed, 11 insertions(+), 36 deletions(-)
diff --git a/arch/mips/include/asm/time.h b/arch/mips/include/asm/time.h
index df6a430..c7f1bfe 100644
--- a/arch/mips/include/asm/time.h
+++ b/arch/mips/include/asm/time.h
@@ -84,8 +84,16 @@ static inline int init_mips_clocksource(void)
#endif
}
-extern void clocksource_set_clock(struct clocksource *cs, unsigned int clock);
-extern void clockevent_set_clock(struct clock_event_device *cd,
- unsigned int clock);
+static inline void clocksource_set_clock(struct clocksource *cs,
+ unsigned int clock)
+{
+ clocksource_calc_mult_shift(cs, clock, 4);
+}
+
+static inline void clockevent_set_clock(struct clock_event_device *cd,
+ unsigned int clock)
+{
+ clockevents_calc_mult_shift(cd, clock, 4);
+}
#endif /* _ASM_TIME_H */
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index 1f467d5..fb74974 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -71,39 +71,6 @@ EXPORT_SYMBOL(perf_irq);
unsigned int mips_hpt_frequency;
-void __init clocksource_set_clock(struct clocksource *cs, unsigned int clock)
-{
- u64 temp;
- u32 shift;
-
- /* Find a shift value */
- for (shift = 32; shift > 0; shift--) {
- temp = (u64) NSEC_PER_SEC << shift;
- do_div(temp, clock);
- if ((temp >> 32) == 0)
- break;
- }
- cs->shift = shift;
- cs->mult = (u32) temp;
-}
-
-void __cpuinit clockevent_set_clock(struct clock_event_device *cd,
- unsigned int clock)
-{
- u64 temp;
- u32 shift;
-
- /* Find a shift value */
- for (shift = 32; shift > 0; shift--) {
- temp = (u64) clock << shift;
- do_div(temp, NSEC_PER_SEC);
- if ((temp >> 32) == 0)
- break;
- }
- cd->shift = shift;
- cd->mult = (u32) temp;
-}
-
/*
* This function exists in order to cause an error due to a duplicate
* definition if platform code should have its own implementation. The hook
^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2009-11-13 19:49 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-11-11 14:05 [patch 0/3] Provide generic function to calc mult/shift factors for clocks Thomas Gleixner
2009-11-11 14:05 ` [patch 1/3] clockevents: Use u32 for mult and shift factors Thomas Gleixner
2009-11-13 19:48 ` [tip:timers/core] " tip-bot for Thomas Gleixner
2009-11-11 14:05 ` [patch 2/3] clocksource: Provide a generic mult/shift factor calculation Thomas Gleixner
2009-11-13 19:49 ` [tip:timers/core] " tip-bot for Thomas Gleixner
2009-11-11 14:05 ` [patch 3/3] mips: Use generic mult/shift factor calculation for clocks Thomas Gleixner
2009-11-13 19:49 ` [tip:timers/core] " tip-bot for Thomas Gleixner
2009-11-11 14:08 ` [patch 0/3] Provide generic function to calc mult/shift factors forclocks Linus Walleij
2009-11-12 11:37 ` [patch 0/3] Provide generic function to calc mult/shift factors for clocks Ralf Baechle
2009-11-12 16:59 ` Mikael Pettersson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox