aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorKarsten Wiese <fzu@wemgehoertderstaat.de>2006-12-06 20:14:11 -0500
committerAndi Kleen <andi@basil.nowhere.org>2006-12-06 20:14:11 -0500
commitf990fff427d68af3e4e1d16fe799c106abc0bf53 (patch)
tree74681deb5738ddbc10fc34f71837902238378f15 /arch
parent9a8cb626a08f2c8251291f3c0a049b29665895d2 (diff)
[PATCH] x86: Regard MSRs in lapic_suspend()/lapic_resume()
Read/Write APIC_LVTPC and APIC_LVTTHMR only, if get_maxlvt() returns certain values. This is done like everywhere else in i386/kernel/apic.c, so I guess its correct. Suspends/Resumes to disk fine and eleminates an smp_error_interrupt() here on a K8. AK: ported to x86-64 too Signed-off-by: Karsten Wiese <fzu@wemgehoertderstaat.de> Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'arch')
-rw-r--r--arch/i386/kernel/apic.c22
-rw-r--r--arch/x86_64/kernel/apic.c22
2 files changed, 36 insertions, 8 deletions
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index 2fd4b7d927c2..776d9be26af9 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -647,23 +647,30 @@ static struct {
647static int lapic_suspend(struct sys_device *dev, pm_message_t state) 647static int lapic_suspend(struct sys_device *dev, pm_message_t state)
648{ 648{
649 unsigned long flags; 649 unsigned long flags;
650 int maxlvt;
650 651
651 if (!apic_pm_state.active) 652 if (!apic_pm_state.active)
652 return 0; 653 return 0;
653 654
655 maxlvt = get_maxlvt();
656
654 apic_pm_state.apic_id = apic_read(APIC_ID); 657 apic_pm_state.apic_id = apic_read(APIC_ID);
655 apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI); 658 apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI);
656 apic_pm_state.apic_ldr = apic_read(APIC_LDR); 659 apic_pm_state.apic_ldr = apic_read(APIC_LDR);
657 apic_pm_state.apic_dfr = apic_read(APIC_DFR); 660 apic_pm_state.apic_dfr = apic_read(APIC_DFR);
658 apic_pm_state.apic_spiv = apic_read(APIC_SPIV); 661 apic_pm_state.apic_spiv = apic_read(APIC_SPIV);
659 apic_pm_state.apic_lvtt = apic_read(APIC_LVTT); 662 apic_pm_state.apic_lvtt = apic_read(APIC_LVTT);
660 apic_pm_state.apic_lvtpc = apic_read(APIC_LVTPC); 663 if (maxlvt >= 4)
664 apic_pm_state.apic_lvtpc = apic_read(APIC_LVTPC);
661 apic_pm_state.apic_lvt0 = apic_read(APIC_LVT0); 665 apic_pm_state.apic_lvt0 = apic_read(APIC_LVT0);
662 apic_pm_state.apic_lvt1 = apic_read(APIC_LVT1); 666 apic_pm_state.apic_lvt1 = apic_read(APIC_LVT1);
663 apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR); 667 apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR);
664 apic_pm_state.apic_tmict = apic_read(APIC_TMICT); 668 apic_pm_state.apic_tmict = apic_read(APIC_TMICT);
665 apic_pm_state.apic_tdcr = apic_read(APIC_TDCR); 669 apic_pm_state.apic_tdcr = apic_read(APIC_TDCR);
666 apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR); 670#ifdef CONFIG_X86_MCE_P4THERMAL
671 if (maxlvt >= 5)
672 apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR);
673#endif
667 674
668 local_irq_save(flags); 675 local_irq_save(flags);
669 disable_local_APIC(); 676 disable_local_APIC();
@@ -675,10 +682,13 @@ static int lapic_resume(struct sys_device *dev)
675{ 682{
676 unsigned int l, h; 683 unsigned int l, h;
677 unsigned long flags; 684 unsigned long flags;
685 int maxlvt;
678 686
679 if (!apic_pm_state.active) 687 if (!apic_pm_state.active)
680 return 0; 688 return 0;
681 689
690 maxlvt = get_maxlvt();
691
682 local_irq_save(flags); 692 local_irq_save(flags);
683 693
684 /* 694 /*
@@ -700,8 +710,12 @@ static int lapic_resume(struct sys_device *dev)
700 apic_write(APIC_SPIV, apic_pm_state.apic_spiv); 710 apic_write(APIC_SPIV, apic_pm_state.apic_spiv);
701 apic_write(APIC_LVT0, apic_pm_state.apic_lvt0); 711 apic_write(APIC_LVT0, apic_pm_state.apic_lvt0);
702 apic_write(APIC_LVT1, apic_pm_state.apic_lvt1); 712 apic_write(APIC_LVT1, apic_pm_state.apic_lvt1);
703 apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr); 713#ifdef CONFIG_X86_MCE_P4THERMAL
704 apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc); 714 if (maxlvt >= 5)
715 apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr);
716#endif
717 if (maxlvt >= 4)
718 apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc);
705 apic_write(APIC_LVTT, apic_pm_state.apic_lvtt); 719 apic_write(APIC_LVTT, apic_pm_state.apic_lvtt);
706 apic_write(APIC_TDCR, apic_pm_state.apic_tdcr); 720 apic_write(APIC_TDCR, apic_pm_state.apic_tdcr);
707 apic_write(APIC_TMICT, apic_pm_state.apic_tmict); 721 apic_write(APIC_TMICT, apic_pm_state.apic_tmict);
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
index 5c468971e645..f0b00d8731cb 100644
--- a/arch/x86_64/kernel/apic.c
+++ b/arch/x86_64/kernel/apic.c
@@ -459,23 +459,30 @@ static struct {
459static int lapic_suspend(struct sys_device *dev, pm_message_t state) 459static int lapic_suspend(struct sys_device *dev, pm_message_t state)
460{ 460{
461 unsigned long flags; 461 unsigned long flags;
462 int maxlvt;
462 463
463 if (!apic_pm_state.active) 464 if (!apic_pm_state.active)
464 return 0; 465 return 0;
465 466
467 maxlvt = get_maxlvt();
468
466 apic_pm_state.apic_id = apic_read(APIC_ID); 469 apic_pm_state.apic_id = apic_read(APIC_ID);
467 apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI); 470 apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI);
468 apic_pm_state.apic_ldr = apic_read(APIC_LDR); 471 apic_pm_state.apic_ldr = apic_read(APIC_LDR);
469 apic_pm_state.apic_dfr = apic_read(APIC_DFR); 472 apic_pm_state.apic_dfr = apic_read(APIC_DFR);
470 apic_pm_state.apic_spiv = apic_read(APIC_SPIV); 473 apic_pm_state.apic_spiv = apic_read(APIC_SPIV);
471 apic_pm_state.apic_lvtt = apic_read(APIC_LVTT); 474 apic_pm_state.apic_lvtt = apic_read(APIC_LVTT);
472 apic_pm_state.apic_lvtpc = apic_read(APIC_LVTPC); 475 if (maxlvt >= 4)
476 apic_pm_state.apic_lvtpc = apic_read(APIC_LVTPC);
473 apic_pm_state.apic_lvt0 = apic_read(APIC_LVT0); 477 apic_pm_state.apic_lvt0 = apic_read(APIC_LVT0);
474 apic_pm_state.apic_lvt1 = apic_read(APIC_LVT1); 478 apic_pm_state.apic_lvt1 = apic_read(APIC_LVT1);
475 apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR); 479 apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR);
476 apic_pm_state.apic_tmict = apic_read(APIC_TMICT); 480 apic_pm_state.apic_tmict = apic_read(APIC_TMICT);
477 apic_pm_state.apic_tdcr = apic_read(APIC_TDCR); 481 apic_pm_state.apic_tdcr = apic_read(APIC_TDCR);
478 apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR); 482#ifdef CONFIG_X86_MCE_INTEL
483 if (maxlvt >= 5)
484 apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR);
485#endif
479 local_irq_save(flags); 486 local_irq_save(flags);
480 disable_local_APIC(); 487 disable_local_APIC();
481 local_irq_restore(flags); 488 local_irq_restore(flags);
@@ -486,10 +493,13 @@ static int lapic_resume(struct sys_device *dev)
486{ 493{
487 unsigned int l, h; 494 unsigned int l, h;
488 unsigned long flags; 495 unsigned long flags;
496 int maxlvt;
489 497
490 if (!apic_pm_state.active) 498 if (!apic_pm_state.active)
491 return 0; 499 return 0;
492 500
501 maxlvt = get_maxlvt();
502
493 local_irq_save(flags); 503 local_irq_save(flags);
494 rdmsr(MSR_IA32_APICBASE, l, h); 504 rdmsr(MSR_IA32_APICBASE, l, h);
495 l &= ~MSR_IA32_APICBASE_BASE; 505 l &= ~MSR_IA32_APICBASE_BASE;
@@ -503,8 +513,12 @@ static int lapic_resume(struct sys_device *dev)
503 apic_write(APIC_SPIV, apic_pm_state.apic_spiv); 513 apic_write(APIC_SPIV, apic_pm_state.apic_spiv);
504 apic_write(APIC_LVT0, apic_pm_state.apic_lvt0); 514 apic_write(APIC_LVT0, apic_pm_state.apic_lvt0);
505 apic_write(APIC_LVT1, apic_pm_state.apic_lvt1); 515 apic_write(APIC_LVT1, apic_pm_state.apic_lvt1);
506 apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr); 516#ifdef CONFIG_X86_MCE_INTEL
507 apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc); 517 if (maxlvt >= 5)
518 apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr);
519#endif
520 if (maxlvt >= 4)
521 apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc);
508 apic_write(APIC_LVTT, apic_pm_state.apic_lvtt); 522 apic_write(APIC_LVTT, apic_pm_state.apic_lvtt);
509 apic_write(APIC_TDCR, apic_pm_state.apic_tdcr); 523 apic_write(APIC_TDCR, apic_pm_state.apic_tdcr);
510 apic_write(APIC_TMICT, apic_pm_state.apic_tmict); 524 apic_write(APIC_TMICT, apic_pm_state.apic_tmict);