aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel/apic.c
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/x86_64/kernel/apic.c
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/x86_64/kernel/apic.c')
-rw-r--r--arch/x86_64/kernel/apic.c22
1 files changed, 18 insertions, 4 deletions
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);