Skip to content

Commit 836c129

Browse files
cyrillosIngo Molnar
authored andcommitted
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: Cyrill Gorcunov <gorcunov@gmail.com> Cc: Cyrill Gorcunov <gorcunov@gmail.com> Cc: macro@linux-mips.org Cc: yhlu.kernel@gmail.com Signed-off-by: Ingo Molnar <mingo@elte.hu>
1 parent 89b3b1f commit 836c129

File tree

1 file changed

+50
-43
lines changed

1 file changed

+50
-43
lines changed

arch/x86/kernel/apic_32.c

Lines changed: 50 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -369,12 +369,7 @@ static void __init lapic_cal_handler(struct clock_event_device *dev)
369369
}
370370
}
371371

372-
/*
373-
* Setup the boot APIC
374-
*
375-
* Calibrate and verify the result.
376-
*/
377-
void __init setup_boot_APIC_clock(void)
372+
static int __init calibrate_APIC_clock(void)
378373
{
379374
struct clock_event_device *levt = &__get_cpu_var(lapic_events);
380375
const long pm_100ms = PMTMR_TICKS_PER_SEC/10;
@@ -384,24 +379,6 @@ void __init setup_boot_APIC_clock(void)
384379
long delta, deltapm;
385380
int pm_referenced = 0;
386381

387-
/*
388-
* The local apic timer can be disabled via the kernel
389-
* commandline or from the CPU detection code. Register the lapic
390-
* timer as a dummy clock event source on SMP systems, so the
391-
* broadcast mechanism is used. On UP systems simply ignore it.
392-
*/
393-
if (local_apic_timer_disabled) {
394-
/* No broadcast on UP ! */
395-
if (num_possible_cpus() > 1) {
396-
lapic_clockevent.mult = 1;
397-
setup_APIC_timer();
398-
}
399-
return;
400-
}
401-
402-
apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n"
403-
"calibrating APIC timer ...\n");
404-
405382
local_irq_disable();
406383

407384
/* Replace the global interrupt handler */
@@ -486,21 +463,18 @@ void __init setup_boot_APIC_clock(void)
486463
calibration_result / (1000000 / HZ),
487464
calibration_result % (1000000 / HZ));
488465

489-
local_apic_timer_verify_ok = 1;
490-
491466
/*
492467
* Do a sanity check on the APIC calibration result
493468
*/
494469
if (calibration_result < (1000000 / HZ)) {
495470
local_irq_enable();
496471
printk(KERN_WARNING
497472
"APIC frequency too slow, disabling apic timer\n");
498-
/* No broadcast on UP ! */
499-
if (num_possible_cpus() > 1)
500-
setup_APIC_timer();
501-
return;
473+
return -1;
502474
}
503475

476+
local_apic_timer_verify_ok = 1;
477+
504478
/* We trust the pm timer based calibration */
505479
if (!pm_referenced) {
506480
apic_printk(APIC_VERBOSE, "... verify APIC timer\n");
@@ -540,22 +514,55 @@ void __init setup_boot_APIC_clock(void)
540514
if (!local_apic_timer_verify_ok) {
541515
printk(KERN_WARNING
542516
"APIC timer disabled due to verification failure.\n");
517+
return -1;
518+
}
519+
520+
return 0;
521+
}
522+
523+
/*
524+
* Setup the boot APIC
525+
*
526+
* Calibrate and verify the result.
527+
*/
528+
void __init setup_boot_APIC_clock(void)
529+
{
530+
/*
531+
* The local apic timer can be disabled via the kernel
532+
* commandline or from the CPU detection code. Register the lapic
533+
* timer as a dummy clock event source on SMP systems, so the
534+
* broadcast mechanism is used. On UP systems simply ignore it.
535+
*/
536+
if (local_apic_timer_disabled) {
543537
/* No broadcast on UP ! */
544-
if (num_possible_cpus() == 1)
545-
return;
546-
} else {
547-
/*
548-
* If nmi_watchdog is set to IO_APIC, we need the
549-
* PIT/HPET going. Otherwise register lapic as a dummy
550-
* device.
551-
*/
552-
if (nmi_watchdog != NMI_IO_APIC)
553-
lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
554-
else
555-
printk(KERN_WARNING "APIC timer registered as dummy,"
556-
" due to nmi_watchdog=%d!\n", nmi_watchdog);
538+
if (num_possible_cpus() > 1) {
539+
lapic_clockevent.mult = 1;
540+
setup_APIC_timer();
541+
}
542+
return;
543+
}
544+
545+
apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n"
546+
"calibrating APIC timer ...\n");
547+
548+
if (calibrate_APIC_clock()) {
549+
/* No broadcast on UP ! */
550+
if (num_possible_cpus() > 1)
551+
setup_APIC_timer();
552+
return;
557553
}
558554

555+
/*
556+
* If nmi_watchdog is set to IO_APIC, we need the
557+
* PIT/HPET going. Otherwise register lapic as a dummy
558+
* device.
559+
*/
560+
if (nmi_watchdog != NMI_IO_APIC)
561+
lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
562+
else
563+
printk(KERN_WARNING "APIC timer registered as dummy,"
564+
" due to nmi_watchdog=%d!\n", nmi_watchdog);
565+
559566
/* Setup the lapic or request the broadcast */
560567
setup_APIC_timer();
561568
}

0 commit comments

Comments
 (0)