diff options
author | Cyrill Gorcunov <gorcunov@gmail.com> | 2008-07-15 13:02:55 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-18 08:17:30 -0400 |
commit | 836c129de971d526b6e85b8ad760bd635a00215e (patch) | |
tree | 7136ff5e981c80e7950224cc5cb099d96f578f0e /arch/x86 | |
parent | 89b3b1f41bd94085da2f08dcb719bdbf7e8e9d57 (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.c | 93 |
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 | /* | 372 | static int __init calibrate_APIC_clock(void) |
373 | * Setup the boot APIC | ||
374 | * | ||
375 | * Calibrate and verify the result. | ||
376 | */ | ||
377 | void __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 | */ | ||
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) { | ||
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 | } |