x86/apic: Unify duplicated local apic timer clockevent initialization
Local APIC timer clockevent parameters can be calculated based on platform
specific methods. However the code is mostly duplicated with the interrupt
based calibration. The commit which increased the max_delta parameter
updated only one place and made the implementations diverge.
Unify it to prevent further damage.
[ tglx: Rename function to lapic_init_clockevent() and adjust changelog a bit ]
Fixes: 4aed89d6b5
("x86, lapic-timer: Increase the max_delta to 31 bits")
Reported-by: Daniel Drake <drake@endlessm.com>
Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Len Brown <lenb@kernel.org>
Link: https://lkml.kernel.org/r/1556213272-63568-1-git-send-email-jacob.jun.pan@linux.intel.com
This commit is contained in:
parent
085b775580
commit
6eb4f08293
|
@ -802,6 +802,24 @@ calibrate_by_pmtimer(long deltapm, long *delta, long *deltatsc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __init lapic_init_clockevent(void)
|
||||
{
|
||||
if (!lapic_timer_frequency)
|
||||
return -1;
|
||||
|
||||
/* Calculate the scaled math multiplication factor */
|
||||
lapic_clockevent.mult = div_sc(lapic_timer_frequency/APIC_DIVISOR,
|
||||
TICK_NSEC, lapic_clockevent.shift);
|
||||
lapic_clockevent.max_delta_ns =
|
||||
clockevent_delta2ns(0x7FFFFFFF, &lapic_clockevent);
|
||||
lapic_clockevent.max_delta_ticks = 0x7FFFFFFF;
|
||||
lapic_clockevent.min_delta_ns =
|
||||
clockevent_delta2ns(0xF, &lapic_clockevent);
|
||||
lapic_clockevent.min_delta_ticks = 0xF;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init calibrate_APIC_clock(void)
|
||||
{
|
||||
struct clock_event_device *levt = this_cpu_ptr(&lapic_events);
|
||||
|
@ -810,25 +828,21 @@ static int __init calibrate_APIC_clock(void)
|
|||
long delta, deltatsc;
|
||||
int pm_referenced = 0;
|
||||
|
||||
/**
|
||||
* check if lapic timer has already been calibrated by platform
|
||||
* specific routine, such as tsc calibration code. if so, we just fill
|
||||
if (boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Check if lapic timer has already been calibrated by platform
|
||||
* specific routine, such as tsc calibration code. If so just fill
|
||||
* in the clockevent structure and return.
|
||||
*/
|
||||
|
||||
if (boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER)) {
|
||||
return 0;
|
||||
} else if (lapic_timer_frequency) {
|
||||
if (!lapic_init_clockevent()) {
|
||||
apic_printk(APIC_VERBOSE, "lapic timer already calibrated %d\n",
|
||||
lapic_timer_frequency);
|
||||
lapic_clockevent.mult = div_sc(lapic_timer_frequency/APIC_DIVISOR,
|
||||
TICK_NSEC, lapic_clockevent.shift);
|
||||
lapic_clockevent.max_delta_ns =
|
||||
clockevent_delta2ns(0x7FFFFF, &lapic_clockevent);
|
||||
lapic_clockevent.max_delta_ticks = 0x7FFFFF;
|
||||
lapic_clockevent.min_delta_ns =
|
||||
clockevent_delta2ns(0xF, &lapic_clockevent);
|
||||
lapic_clockevent.min_delta_ticks = 0xF;
|
||||
lapic_timer_frequency);
|
||||
/*
|
||||
* Direct calibration methods must have an always running
|
||||
* local APIC timer, no need for broadcast timer.
|
||||
*/
|
||||
lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
|
||||
return 0;
|
||||
}
|
||||
|
@ -869,17 +883,8 @@ static int __init calibrate_APIC_clock(void)
|
|||
pm_referenced = !calibrate_by_pmtimer(lapic_cal_pm2 - lapic_cal_pm1,
|
||||
&delta, &deltatsc);
|
||||
|
||||
/* Calculate the scaled math multiplication factor */
|
||||
lapic_clockevent.mult = div_sc(delta, TICK_NSEC * LAPIC_CAL_LOOPS,
|
||||
lapic_clockevent.shift);
|
||||
lapic_clockevent.max_delta_ns =
|
||||
clockevent_delta2ns(0x7FFFFFFF, &lapic_clockevent);
|
||||
lapic_clockevent.max_delta_ticks = 0x7FFFFFFF;
|
||||
lapic_clockevent.min_delta_ns =
|
||||
clockevent_delta2ns(0xF, &lapic_clockevent);
|
||||
lapic_clockevent.min_delta_ticks = 0xF;
|
||||
|
||||
lapic_timer_frequency = (delta * APIC_DIVISOR) / LAPIC_CAL_LOOPS;
|
||||
lapic_init_clockevent();
|
||||
|
||||
apic_printk(APIC_VERBOSE, "..... delta %ld\n", delta);
|
||||
apic_printk(APIC_VERBOSE, "..... mult: %u\n", lapic_clockevent.mult);
|
||||
|
|
Loading…
Reference in New Issue