1 // SPDX-License-Identifier: GPL-2.0-only
3 #include <linux/types.h>
4 #include <linux/slab.h>
5 #include <linux/syscore_ops.h>
6 #include <asm/cpufeature.h>
8 #include <asm/processor.h>
11 void mtrr_set_if(void)
13 switch (boot_cpu_data
.x86_vendor
) {
15 /* Pre-Athlon (K6) AMD CPU MTRRs */
16 if (cpu_feature_enabled(X86_FEATURE_K6_MTRR
))
17 mtrr_if
= &amd_mtrr_ops
;
19 case X86_VENDOR_CENTAUR
:
20 if (cpu_feature_enabled(X86_FEATURE_CENTAUR_MCR
))
21 mtrr_if
= ¢aur_mtrr_ops
;
23 case X86_VENDOR_CYRIX
:
24 if (cpu_feature_enabled(X86_FEATURE_CYRIX_ARR
))
25 mtrr_if
= &cyrix_mtrr_ops
;
33 * The suspend/resume methods are only for CPUs without MTRR. CPUs using generic
34 * MTRR driver don't require this.
42 static struct mtrr_value
*mtrr_value
;
44 static int mtrr_save(void)
51 for (i
= 0; i
< num_var_ranges
; i
++) {
52 mtrr_if
->get(i
, &mtrr_value
[i
].lbase
,
54 &mtrr_value
[i
].ltype
);
59 static void mtrr_restore(void)
63 for (i
= 0; i
< num_var_ranges
; i
++) {
64 if (mtrr_value
[i
].lsize
) {
65 mtrr_if
->set(i
, mtrr_value
[i
].lbase
,
72 static struct syscore_ops mtrr_syscore_ops
= {
74 .resume
= mtrr_restore
,
77 void mtrr_register_syscore(void)
79 mtrr_value
= kcalloc(num_var_ranges
, sizeof(*mtrr_value
), GFP_KERNEL
);
82 * The CPU has no MTRR and seems to not support SMP. They have
83 * specific drivers, we use a tricky method to support
84 * suspend/resume for them.
86 * TBD: is there any system with such CPU which supports
87 * suspend/resume? If no, we should remove the code.
89 register_syscore_ops(&mtrr_syscore_ops
);