aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorCyrill Gorcunov <gorcunov@gmail.com>2008-07-15 13:02:55 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-18 08:17:30 -0400
commit836c129de971d526b6e85b8ad760bd635a00215e (patch)
tree7136ff5e981c80e7950224cc5cb099d96f578f0e /arch/x86
parent89b3b1f41bd94085da2f08dcb719bdbf7e8e9d57 (diff)
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>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kernel/apic_32.c93
1 files changed, 50 insertions, 43 deletions
diff --git a/arch/x86/kernel/apic_32.c b/arch/x86/kernel/apic_32.c
index 2bc1186cc95a..d2a7eb511d6b 100644
--- a/arch/x86/kernel/apic_32.c
+++ b/arch/x86/kernel/apic_32.c
@@ -369,12 +369,7 @@ static void __init lapic_cal_handler(struct clock_event_device *dev)
369 } 369 }
370} 370}
371 371
372/* 372static int __init calibrate_APIC_clock(void)
373 * Setup the boot APIC
374 *
375 * Calibrate and verify the result.
376 */
377void __init setup_boot_APIC_clock(void)
378{ 373{
379 struct clock_event_device *levt = &__get_cpu_var(lapic_events); 374 struct clock_event_device *levt = &__get_cpu_var(lapic_events);
380 const long pm_100ms = PMTMR_TICKS_PER_SEC/10; 375 const long pm_100ms = PMTMR_TICKS_PER_SEC/10;
@@ -384,24 +379,6 @@ void __init setup_boot_APIC_clock(void)
384 long delta, deltapm; 379 long delta, deltapm;
385 int pm_referenced = 0; 380 int pm_referenced = 0;
386 381
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
405 local_irq_disable(); 382 local_irq_disable();
406 383
407 /* Replace the global interrupt handler */ 384 /* Replace the global interrupt handler */
@@ -486,8 +463,6 @@ void __init setup_boot_APIC_clock(void)
486 calibration_result / (1000000 / HZ), 463 calibration_result / (1000000 / HZ),
487 calibration_result % (1000000 / HZ)); 464 calibration_result % (1000000 / HZ));
488 465
489 local_apic_timer_verify_ok = 1;
490
491 /* 466 /*
492 * Do a sanity check on the APIC calibration result 467 * Do a sanity check on the APIC calibration result
493 */ 468 */
@@ -495,12 +470,11 @@ void __init setup_boot_APIC_clock(void)
495 local_irq_enable(); 470 local_irq_enable();
496 printk(KERN_WARNING 471 printk(KERN_WARNING
497 "APIC frequency too slow, disabling apic timer\n"); 472 "APIC frequency too slow, disabling apic timer\n");
498 /* No broadcast on UP ! */ 473 return -1;
499 if (num_possible_cpus() > 1)
500 setup_APIC_timer();
501 return;
502 } 474 }
503 475
476 local_apic_timer_verify_ok = 1;
477
504 /* We trust the pm timer based calibration */ 478 /* We trust the pm timer based calibration */
505 if (!pm_referenced) { 479 if (!pm_referenced) {
506 apic_printk(APIC_VERBOSE, "... verify APIC timer\n"); 480 apic_printk(APIC_VERBOSE, "... verify APIC timer\n");
@@ -540,22 +514,55 @@ void __init setup_boot_APIC_clock(void)
540 if (!local_apic_timer_verify_ok) { 514 if (!local_apic_timer_verify_ok) {
541 printk(KERN_WARNING 515 printk(KERN_WARNING
542 "APIC timer disabled due to verification failure.\n"); 516 "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 */
528void __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) {
543 /* No broadcast on UP ! */ 537 /* No broadcast on UP ! */
544 if (num_possible_cpus() == 1) 538 if (num_possible_cpus() > 1) {
545 return; 539 lapic_clockevent.mult = 1;
546 } else { 540 setup_APIC_timer();
547 /* 541 }
548 * If nmi_watchdog is set to IO_APIC, we need the 542 return;
549 * PIT/HPET going. Otherwise register lapic as a dummy 543 }
550 * device. 544
551 */ 545 apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n"
552 if (nmi_watchdog != NMI_IO_APIC) 546 "calibrating APIC timer ...\n");
553 lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY; 547
554 else 548 if (calibrate_APIC_clock()) {
555 printk(KERN_WARNING "APIC timer registered as dummy," 549 /* No broadcast on UP ! */
556 " due to nmi_watchdog=%d!\n", nmi_watchdog); 550 if (num_possible_cpus() > 1)
551 setup_APIC_timer();
552 return;
557 } 553 }
558 554
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
559 /* Setup the lapic or request the broadcast */ 566 /* Setup the lapic or request the broadcast */
560 setup_APIC_timer(); 567 setup_APIC_timer();
561} 568}