mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-09-18 22:09:30 +02:00
Merge tag 'timers-cleanups-2026-08-17' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull treewide timer related cleanups from Thomas Gleixner: - Remove the leftover CLOCK_TICK_RATE which has been scheduled for removal more than a decade ago along with some now empty asm/timex.h files. - Consolidate delay timer calibration The construct of having a define in a header requires that architectures provided asm/timex.h for no reason. Also the function name for reading the delay timer is confusing at best. Use a config switch to enable that functionality and rename the function to delay_read_timer() to make the purpose clear. This removes some more now empty asm/timex.h files as well. * tag 'timers-cleanups-2026-08-17' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: calibrate: Rework delay timer calibration treewide: Remove CLOCK_TICK_RATE x86: Use PIT_TICK_RATE instead of CLOCK_TICK_RATE
This commit is contained in:
@@ -377,6 +377,9 @@ config ARCH_HAS_DMA_CLEAR_UNCACHED
|
||||
config ARCH_HAS_CPU_FINALIZE_INIT
|
||||
bool
|
||||
|
||||
config ARCH_HAS_DELAY_TIMER
|
||||
bool
|
||||
|
||||
# The architecture has a per-task state that includes the mm's PASID
|
||||
config ARCH_HAS_CPU_PASID
|
||||
bool
|
||||
|
||||
@@ -7,10 +7,6 @@
|
||||
#ifndef _ASMALPHA_TIMEX_H
|
||||
#define _ASMALPHA_TIMEX_H
|
||||
|
||||
/* With only one or two oddballs, we use the RTC as the ticker, selecting
|
||||
the 32.768kHz reference clock, which nicely divides down to our HZ. */
|
||||
#define CLOCK_TICK_RATE 32768
|
||||
|
||||
/*
|
||||
* Standard way to access the cycle counter.
|
||||
* Currently only used on SMP for scheduling.
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
|
||||
*/
|
||||
|
||||
#ifndef _ASM_ARC_TIMEX_H
|
||||
#define _ASM_ARC_TIMEX_H
|
||||
|
||||
#define CLOCK_TICK_RATE 80000000 /* slated to be removed */
|
||||
|
||||
#include <asm-generic/timex.h>
|
||||
|
||||
/* XXX: get_cycles() to be implemented with RTSC insn */
|
||||
|
||||
#endif /* _ASM_ARC_TIMEX_H */
|
||||
@@ -11,6 +11,7 @@ config ARM
|
||||
select ARCH_HAS_CPU_FINALIZE_INIT if MMU
|
||||
select ARCH_HAS_CURRENT_STACK_POINTER
|
||||
select ARCH_HAS_DEBUG_VIRTUAL if MMU
|
||||
select ARCH_HAS_DELAY_TIMER
|
||||
select ARCH_HAS_DMA_ALLOC if MMU
|
||||
select ARCH_HAS_DMA_OPS
|
||||
select ARCH_HAS_DMA_WRITE_COMBINE if !ARM_DMA_MEM_BUFFERABLE
|
||||
|
||||
@@ -91,7 +91,6 @@ extern void __loop_udelay(unsigned long usecs);
|
||||
extern void __loop_const_udelay(unsigned long);
|
||||
|
||||
/* Delay-loop timer registration. */
|
||||
#define ARCH_HAS_READ_CURRENT_TIMER
|
||||
extern void register_current_timer_delay(const struct delay_timer *timer);
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
@@ -10,7 +10,10 @@
|
||||
#define _ASMARM_TIMEX_H
|
||||
|
||||
typedef unsigned long cycles_t;
|
||||
#define get_cycles() ({ cycles_t c; read_current_timer(&c) ? 0 : c; })
|
||||
// Temporary workaround until timex.h is cleaned up
|
||||
bool delay_read_timer(unsigned long *t);
|
||||
|
||||
#define get_cycles() ({ cycles_t c; delay_read_timer(&c) ? 0 : c; })
|
||||
#define random_get_entropy() (((unsigned long)get_cycles()) ?: random_get_entropy_fallback())
|
||||
|
||||
#endif
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/timex.h>
|
||||
|
||||
/*
|
||||
* Default to the loop-based delay implementation.
|
||||
@@ -27,15 +26,14 @@ static const struct delay_timer *delay_timer;
|
||||
static bool delay_calibrated;
|
||||
static u64 delay_res;
|
||||
|
||||
int read_current_timer(unsigned long *timer_val)
|
||||
bool delay_read_timer(unsigned long *timer_val)
|
||||
{
|
||||
if (!delay_timer)
|
||||
return -ENXIO;
|
||||
|
||||
return false;
|
||||
*timer_val = delay_timer->read_current_timer();
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(read_current_timer);
|
||||
EXPORT_SYMBOL_GPL(delay_read_timer);
|
||||
|
||||
static inline u64 cyc_to_ns(u64 cyc, u32 mult, u32 shift)
|
||||
{
|
||||
|
||||
@@ -74,7 +74,7 @@ config OMAP_32K_TIMER
|
||||
currently only available for OMAP16XX, 24XX, 34XX, OMAP4/5 and DRA7XX.
|
||||
|
||||
On OMAP2PLUS this value is only used for CONFIG_HZ and
|
||||
CLOCK_TICK_RATE compile time calculation.
|
||||
timer frequency compile time calculation.
|
||||
The actual timer selection is done in the board file
|
||||
through the (DT_)MACHINE_START structure.
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ comment "Linux Kernel Configuration for Hexagon"
|
||||
config HEXAGON
|
||||
def_bool y
|
||||
select ARCH_32BIT_OFF_T
|
||||
select ARCH_HAS_DELAY_TIMER
|
||||
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
|
||||
select ARCH_NO_PREEMPT
|
||||
select ARCH_WANT_FRAME_POINTERS
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _ASM_TIMEX_H
|
||||
#define _ASM_TIMEX_H
|
||||
|
||||
#include <asm-generic/timex.h>
|
||||
#include <asm/hexagon_vm.h>
|
||||
|
||||
/* Using TCX0 as our clock. CLOCK_TICK_RATE scheduled to be removed. */
|
||||
#define CLOCK_TICK_RATE 19200
|
||||
|
||||
#define ARCH_HAS_READ_CURRENT_TIMER
|
||||
|
||||
static inline int read_current_timer(unsigned long *timer_val)
|
||||
{
|
||||
*timer_val = __vmgettime();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/interrupt.h>
|
||||
@@ -17,7 +18,6 @@
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/delay.h>
|
||||
#include <asm/hexagon_vm.h>
|
||||
#include <asm/time.h>
|
||||
|
||||
@@ -231,3 +231,9 @@ void __udelay(unsigned long usecs)
|
||||
cpu_relax(); /* not sure how this improves readability */
|
||||
}
|
||||
EXPORT_SYMBOL(__udelay);
|
||||
|
||||
bool delay_read_timer(unsigned long *timer_val)
|
||||
{
|
||||
*timer_val = __vmgettime();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -7,21 +7,6 @@
|
||||
#ifndef _ASMm68K_TIMEX_H
|
||||
#define _ASMm68K_TIMEX_H
|
||||
|
||||
#ifdef CONFIG_COLDFIRE
|
||||
/*
|
||||
* CLOCK_TICK_RATE should give the underlying frequency of the tick timer
|
||||
* to make ntp work best. For Coldfires, that's the main clock.
|
||||
*/
|
||||
#include <asm/coldfire.h>
|
||||
#define CLOCK_TICK_RATE MCF_CLK
|
||||
#else
|
||||
/*
|
||||
* This default CLOCK_TICK_RATE is probably wrong for many 68k boards
|
||||
* Users of those boards will need to check and modify accordingly
|
||||
*/
|
||||
#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
|
||||
#endif
|
||||
|
||||
typedef unsigned long cycles_t;
|
||||
|
||||
static inline cycles_t get_cycles(void)
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2006 Atmark Techno, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _ASM_MICROBLAZE_TIMEX_H
|
||||
#define _ASM_MICROBLAZE_TIMEX_H
|
||||
|
||||
#include <asm-generic/timex.h>
|
||||
|
||||
#define CLOCK_TICK_RATE 1000 /* Timer input freq. */
|
||||
|
||||
#endif /* _ASM_TIMEX_H */
|
||||
@@ -18,14 +18,6 @@
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/cpu-type.h>
|
||||
|
||||
/*
|
||||
* This is the clock rate of the i8253 PIT. A MIPS system may not have
|
||||
* a PIT by the symbol is used all over the kernel including some APIs.
|
||||
* So keeping it defined to the number for the PIT is the only sane thing
|
||||
* for now.
|
||||
*/
|
||||
#define CLOCK_TICK_RATE 1193182
|
||||
|
||||
/*
|
||||
* Standard way to access the cycle counter.
|
||||
* Currently only used on SMP for scheduling.
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
config OPENRISC
|
||||
def_bool y
|
||||
select ARCH_32BIT_OFF_T
|
||||
select ARCH_HAS_DELAY_TIMER
|
||||
select ARCH_HAS_DMA_SET_UNCACHED
|
||||
select ARCH_HAS_DMA_CLEAR_UNCACHED
|
||||
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
|
||||
|
||||
@@ -25,9 +25,4 @@ static inline cycles_t get_cycles(void)
|
||||
}
|
||||
#define get_cycles get_cycles
|
||||
|
||||
/* This isn't really used any more */
|
||||
#define CLOCK_TICK_RATE 1000
|
||||
|
||||
#define ARCH_HAS_READ_CURRENT_TIMER
|
||||
|
||||
#endif
|
||||
|
||||
@@ -13,18 +13,17 @@
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/timex.h>
|
||||
|
||||
#include <asm/param.h>
|
||||
#include <asm/delay.h>
|
||||
#include <asm/timex.h>
|
||||
#include <asm/processor.h>
|
||||
|
||||
int read_current_timer(unsigned long *timer_value)
|
||||
bool delay_read_timer(unsigned long *timer_value)
|
||||
{
|
||||
*timer_value = get_cycles();
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void __delay(unsigned long cycles)
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
|
||||
#include <asm/special_insns.h>
|
||||
|
||||
#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
|
||||
|
||||
typedef unsigned long cycles_t;
|
||||
|
||||
static inline cycles_t get_cycles(void)
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
#include <asm/cputable.h>
|
||||
#include <asm/vdso/timebase.h>
|
||||
|
||||
#define CLOCK_TICK_RATE 1024000 /* Underlying HZ */
|
||||
|
||||
typedef unsigned long cycles_t;
|
||||
|
||||
static inline cycles_t get_cycles(void)
|
||||
|
||||
@@ -29,6 +29,7 @@ config RISCV
|
||||
select ARCH_HAS_DEBUG_VIRTUAL if MMU
|
||||
select ARCH_HAS_DEBUG_VM_PGTABLE
|
||||
select ARCH_HAS_DEBUG_WX
|
||||
select ARCH_HAS_DELAY_TIMER
|
||||
select ARCH_HAS_ELF_CORE_EFLAGS if BINFMT_ELF && ELF_CORE
|
||||
select ARCH_HAS_FAST_MULTIPLIER
|
||||
select ARCH_HAS_FORTIFY_SOURCE
|
||||
|
||||
@@ -80,12 +80,4 @@ static inline u64 get_cycles64(void)
|
||||
return ((u64)hi << 32) | lo;
|
||||
}
|
||||
#endif /* CONFIG_64BIT */
|
||||
|
||||
#define ARCH_HAS_READ_CURRENT_TIMER
|
||||
static inline int read_current_timer(unsigned long *timer_val)
|
||||
{
|
||||
*timer_val = get_cycles();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* _ASM_RISCV_TIMEX_H */
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/math.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/timex.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/export.h>
|
||||
|
||||
@@ -109,3 +108,9 @@ void ndelay(unsigned long nsecs)
|
||||
__delay(ncycles >> NDELAY_SHIFT);
|
||||
}
|
||||
EXPORT_SYMBOL(ndelay);
|
||||
|
||||
bool delay_read_timer(unsigned long *timer_val)
|
||||
{
|
||||
*timer_val = get_cycles();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -159,8 +159,6 @@ static inline void local_tick_enable(unsigned long comp)
|
||||
set_clock_comparator(get_lowcore()->clock_comparator);
|
||||
}
|
||||
|
||||
#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
|
||||
|
||||
typedef unsigned long cycles_t;
|
||||
|
||||
static __always_inline unsigned long get_tod_clock(void)
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* linux/include/asm-sh/timex.h
|
||||
*
|
||||
* sh architecture timex specifications
|
||||
*/
|
||||
#ifndef __ASM_SH_TIMEX_H
|
||||
#define __ASM_SH_TIMEX_H
|
||||
|
||||
/*
|
||||
* Only parts using the legacy CPG code for their clock framework
|
||||
* implementation need to define their own Pclk value. If provided, this
|
||||
* can be used for accurately setting CLOCK_TICK_RATE, otherwise we
|
||||
* simply fall back on the i8253 PIT value.
|
||||
*/
|
||||
#ifdef CONFIG_SH_PCLK_FREQ
|
||||
#define CLOCK_TICK_RATE (CONFIG_SH_PCLK_FREQ / 4) /* Underlying HZ */
|
||||
#else
|
||||
#define CLOCK_TICK_RATE 1193180
|
||||
#endif
|
||||
|
||||
#include <asm-generic/timex.h>
|
||||
|
||||
#endif /* __ASM_SH_TIMEX_H */
|
||||
@@ -70,6 +70,7 @@ config SPARC32
|
||||
config SPARC64
|
||||
def_bool 64BIT
|
||||
select ALTERNATE_USER_ADDRESS_SPACE
|
||||
select ARCH_HAS_DELAY_TIMER
|
||||
select HAVE_FUNCTION_TRACER
|
||||
select HAVE_FUNCTION_GRAPH_TRACER
|
||||
select HAVE_KRETPROBES
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
#if defined(__sparc__) && defined(__arch64__)
|
||||
#include <asm/timex_64.h>
|
||||
#else
|
||||
#include <asm/timex_32.h>
|
||||
#include <asm-generic/timex.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* linux/include/asm/timex.h
|
||||
*
|
||||
* sparc architecture timex specifications
|
||||
*/
|
||||
#ifndef _ASMsparc_TIMEX_H
|
||||
#define _ASMsparc_TIMEX_H
|
||||
|
||||
#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
|
||||
|
||||
#include <asm-generic/timex.h>
|
||||
|
||||
#endif
|
||||
@@ -9,12 +9,8 @@
|
||||
|
||||
#include <asm/timer.h>
|
||||
|
||||
#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
|
||||
|
||||
/* Getting on the cycle counter on sparc64. */
|
||||
typedef unsigned long cycles_t;
|
||||
#define get_cycles() tick_ops->get_tick()
|
||||
|
||||
#define ARCH_HAS_READ_CURRENT_TIMER
|
||||
|
||||
#endif
|
||||
|
||||
@@ -894,8 +894,8 @@ unsigned long long sched_clock(void)
|
||||
return ((get_tick() * quotient) >> SPARC64_NSEC_PER_CYC_SHIFT) - offset;
|
||||
}
|
||||
|
||||
int read_current_timer(unsigned long *timer_val)
|
||||
bool delay_read_timer(unsigned long *timer_val)
|
||||
{
|
||||
*timer_val = get_tick();
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __UM_TIMEX_H
|
||||
#define __UM_TIMEX_H
|
||||
|
||||
#define CLOCK_TICK_RATE (HZ)
|
||||
|
||||
#include <asm-generic/timex.h>
|
||||
|
||||
#endif
|
||||
@@ -80,6 +80,7 @@ config X86
|
||||
select ARCH_HAS_CURRENT_STACK_POINTER
|
||||
select ARCH_HAS_DEBUG_VIRTUAL
|
||||
select ARCH_HAS_DEBUG_VM_PGTABLE if !X86_PAE
|
||||
select ARCH_HAS_DELAY_TIMER
|
||||
select ARCH_HAS_DEVMEM_IS_ALLOWED
|
||||
select ARCH_HAS_DMA_OPS if GART_IOMMU || XEN
|
||||
select ARCH_HAS_EARLY_DEBUG if KGDB
|
||||
|
||||
@@ -13,9 +13,4 @@ static inline unsigned long random_get_entropy(void)
|
||||
}
|
||||
#define random_get_entropy random_get_entropy
|
||||
|
||||
/* Assume we use the PIT time source for the clock tick */
|
||||
#define CLOCK_TICK_RATE PIT_TICK_RATE
|
||||
|
||||
#define ARCH_HAS_READ_CURRENT_TIMER
|
||||
|
||||
#endif /* _ASM_X86_TIMEX_H */
|
||||
|
||||
@@ -1267,7 +1267,7 @@ void __init setup_arch(char **cmdline_p)
|
||||
|
||||
mcheck_init();
|
||||
|
||||
register_refined_jiffies(CLOCK_TICK_RATE);
|
||||
register_refined_jiffies(PIT_TICK_RATE);
|
||||
|
||||
#ifdef CONFIG_EFI
|
||||
if (efi_enabled(EFI_BOOT))
|
||||
|
||||
@@ -14,12 +14,10 @@
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/timex.h>
|
||||
#include <linux/preempt.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/processor.h>
|
||||
#include <asm/delay.h>
|
||||
#include <asm/timer.h>
|
||||
#include <asm/mwait.h>
|
||||
|
||||
@@ -189,13 +187,13 @@ void use_mwaitx_delay(void)
|
||||
delay_fn = delay_halt;
|
||||
}
|
||||
|
||||
int read_current_timer(unsigned long *timer_val)
|
||||
bool delay_read_timer(unsigned long *timer_val)
|
||||
{
|
||||
if (delay_fn == delay_tsc) {
|
||||
*timer_val = rdtsc();
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
void __delay(unsigned long loops)
|
||||
|
||||
@@ -13,11 +13,4 @@ static inline cycles_t get_cycles(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Architectures are encouraged to implement read_current_timer
|
||||
* and define this in order to avoid the expensive delay loop
|
||||
* calibration during boot.
|
||||
*/
|
||||
#undef ARCH_HAS_READ_CURRENT_TIMER
|
||||
|
||||
#endif /* __ASM_GENERIC_TIMEX_H */
|
||||
|
||||
@@ -17,6 +17,8 @@ extern unsigned long loops_per_jiffy;
|
||||
|
||||
#include <asm/delay.h>
|
||||
|
||||
bool delay_read_timer(unsigned long *t);
|
||||
|
||||
/*
|
||||
* Using udelay() for intervals greater than a few milliseconds can
|
||||
* risk overflow for high loops_per_jiffy (high bogomips) machines. The
|
||||
|
||||
@@ -156,8 +156,6 @@ extern int do_clock_adjtime(const clockid_t which_clock, struct __kernel_timex *
|
||||
|
||||
extern void hardpps(const struct timespec64 *, const struct timespec64 *);
|
||||
|
||||
int read_current_timer(unsigned long *timer_val);
|
||||
|
||||
/* The clock frequency of the i8253/i8254 PIT */
|
||||
#define PIT_TICK_RATE 1193182ul
|
||||
|
||||
|
||||
+9
-10
@@ -13,7 +13,6 @@
|
||||
#include <linux/printk.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/timex.h>
|
||||
|
||||
unsigned long lpj_fine;
|
||||
unsigned long preset_lpj;
|
||||
@@ -25,9 +24,9 @@ static int __init lpj_setup(char *str)
|
||||
|
||||
__setup("lpj=", lpj_setup);
|
||||
|
||||
#ifdef ARCH_HAS_READ_CURRENT_TIMER
|
||||
#ifdef CONFIG_ARCH_HAS_DELAY_TIMER
|
||||
|
||||
/* This routine uses the read_current_timer() routine and gets the
|
||||
/* This routine uses the delay_read_timer() routine and gets the
|
||||
* loops per jiffy directly, instead of guessing it using delay().
|
||||
* Also, this code tries to handle non-maskable asynchronous events
|
||||
* (like SMIs)
|
||||
@@ -48,13 +47,13 @@ static unsigned long calibrate_delay_direct(void)
|
||||
int min = -1;
|
||||
int i;
|
||||
|
||||
if (read_current_timer(&pre_start) < 0 )
|
||||
if (!delay_read_timer(&pre_start))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* A simple loop like
|
||||
* while ( jiffies < start_jiffies+1)
|
||||
* start = read_current_timer();
|
||||
* start = delay_read_timer();
|
||||
* will not do. As we don't really know whether jiffy switch
|
||||
* happened first or timer_value was read first. And some asynchronous
|
||||
* event can happen between these two events introducing errors in lpj.
|
||||
@@ -72,22 +71,22 @@ static unsigned long calibrate_delay_direct(void)
|
||||
|
||||
for (i = 0; i < MAX_DIRECT_CALIBRATION_RETRIES; i++) {
|
||||
pre_start = 0;
|
||||
read_current_timer(&start);
|
||||
delay_read_timer(&start);
|
||||
start_jiffies = jiffies;
|
||||
while (time_before_eq(jiffies, start_jiffies + 1)) {
|
||||
pre_start = start;
|
||||
read_current_timer(&start);
|
||||
delay_read_timer(&start);
|
||||
}
|
||||
read_current_timer(&post_start);
|
||||
delay_read_timer(&post_start);
|
||||
|
||||
pre_end = 0;
|
||||
end = post_start;
|
||||
while (time_before_eq(jiffies, start_jiffies + 1 +
|
||||
DELAY_CALIBRATION_TICKS)) {
|
||||
pre_end = end;
|
||||
read_current_timer(&end);
|
||||
delay_read_timer(&end);
|
||||
}
|
||||
read_current_timer(&post_end);
|
||||
delay_read_timer(&post_end);
|
||||
|
||||
timer_rate_max = (post_end - pre_start) /
|
||||
DELAY_CALIBRATION_TICKS;
|
||||
|
||||
Reference in New Issue
Block a user