Commit 836c129d authored by Cyrill Gorcunov's avatar Cyrill Gorcunov Committed by Ingo Molnar

x86: apic_32 - introduce calibrate_APIC_clock

Introduce calibrate_APIC_clock so it could help in further 32/64bit
apic code merging.
Signed-off-by: default avatarCyrill Gorcunov <gorcunov@gmail.com>
Cc: Cyrill Gorcunov <gorcunov@gmail.com>
Cc: macro@linux-mips.org
Cc: yhlu.kernel@gmail.com
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 89b3b1f4
...@@ -369,12 +369,7 @@ static void __init lapic_cal_handler(struct clock_event_device *dev) ...@@ -369,12 +369,7 @@ static void __init lapic_cal_handler(struct clock_event_device *dev)
} }
} }
/* static int __init calibrate_APIC_clock(void)
* Setup the boot APIC
*
* Calibrate and verify the result.
*/
void __init setup_boot_APIC_clock(void)
{ {
struct clock_event_device *levt = &__get_cpu_var(lapic_events); struct clock_event_device *levt = &__get_cpu_var(lapic_events);
const long pm_100ms = PMTMR_TICKS_PER_SEC/10; const long pm_100ms = PMTMR_TICKS_PER_SEC/10;
...@@ -384,24 +379,6 @@ void __init setup_boot_APIC_clock(void) ...@@ -384,24 +379,6 @@ void __init setup_boot_APIC_clock(void)
long delta, deltapm; long delta, deltapm;
int pm_referenced = 0; int pm_referenced = 0;
/*
* The local apic timer can be disabled via the kernel
* commandline or from the CPU detection code. Register the lapic
* timer as a dummy clock event source on SMP systems, so the
* broadcast mechanism is used. On UP systems simply ignore it.
*/
if (local_apic_timer_disabled) {
/* No broadcast on UP ! */
if (num_possible_cpus() > 1) {
lapic_clockevent.mult = 1;
setup_APIC_timer();
}
return;
}
apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n"
"calibrating APIC timer ...\n");
local_irq_disable(); local_irq_disable();
/* Replace the global interrupt handler */ /* Replace the global interrupt handler */
...@@ -486,8 +463,6 @@ void __init setup_boot_APIC_clock(void) ...@@ -486,8 +463,6 @@ void __init setup_boot_APIC_clock(void)
calibration_result / (1000000 / HZ), calibration_result / (1000000 / HZ),
calibration_result % (1000000 / HZ)); calibration_result % (1000000 / HZ));
local_apic_timer_verify_ok = 1;
/* /*
* Do a sanity check on the APIC calibration result * Do a sanity check on the APIC calibration result
*/ */
...@@ -495,12 +470,11 @@ void __init setup_boot_APIC_clock(void) ...@@ -495,12 +470,11 @@ void __init setup_boot_APIC_clock(void)
local_irq_enable(); local_irq_enable();
printk(KERN_WARNING printk(KERN_WARNING
"APIC frequency too slow, disabling apic timer\n"); "APIC frequency too slow, disabling apic timer\n");
/* No broadcast on UP ! */ return -1;
if (num_possible_cpus() > 1)
setup_APIC_timer();
return;
} }
local_apic_timer_verify_ok = 1;
/* We trust the pm timer based calibration */ /* We trust the pm timer based calibration */
if (!pm_referenced) { if (!pm_referenced) {
apic_printk(APIC_VERBOSE, "... verify APIC timer\n"); apic_printk(APIC_VERBOSE, "... verify APIC timer\n");
...@@ -540,22 +514,55 @@ void __init setup_boot_APIC_clock(void) ...@@ -540,22 +514,55 @@ void __init setup_boot_APIC_clock(void)
if (!local_apic_timer_verify_ok) { if (!local_apic_timer_verify_ok) {
printk(KERN_WARNING printk(KERN_WARNING
"APIC timer disabled due to verification failure.\n"); "APIC timer disabled due to verification failure.\n");
return -1;
}
return 0;
}
/*
* Setup the boot APIC
*
* Calibrate and verify the result.
*/
void __init setup_boot_APIC_clock(void)
{
/*
* The local apic timer can be disabled via the kernel
* commandline or from the CPU detection code. Register the lapic
* timer as a dummy clock event source on SMP systems, so the
* broadcast mechanism is used. On UP systems simply ignore it.
*/
if (local_apic_timer_disabled) {
/* No broadcast on UP ! */ /* No broadcast on UP ! */
if (num_possible_cpus() == 1) if (num_possible_cpus() > 1) {
return; lapic_clockevent.mult = 1;
} else { setup_APIC_timer();
/* }
* If nmi_watchdog is set to IO_APIC, we need the return;
* PIT/HPET going. Otherwise register lapic as a dummy }
* device.
*/ apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n"
if (nmi_watchdog != NMI_IO_APIC) "calibrating APIC timer ...\n");
lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
else if (calibrate_APIC_clock()) {
printk(KERN_WARNING "APIC timer registered as dummy," /* No broadcast on UP ! */
" due to nmi_watchdog=%d!\n", nmi_watchdog); if (num_possible_cpus() > 1)
setup_APIC_timer();
return;
} }
/*
* If nmi_watchdog is set to IO_APIC, we need the
* PIT/HPET going. Otherwise register lapic as a dummy
* device.
*/
if (nmi_watchdog != NMI_IO_APIC)
lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
else
printk(KERN_WARNING "APIC timer registered as dummy,"
" due to nmi_watchdog=%d!\n", nmi_watchdog);
/* Setup the lapic or request the broadcast */ /* Setup the lapic or request the broadcast */
setup_APIC_timer(); setup_APIC_timer();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment