Commit e99286744599a66195de4cd975d7ef4d643c2789
Committed by
Linus Torvalds
1 parent
b347d25fbc
Exists in
master
and in
7 other branches
[PATCH] x86_64: Generalize DMI and enable for x86-64
Some people need it now on 64bit so reuse the i386 code for x86-64. This will be also useful for future bug workarounds. It is a bit simplified there because there is no need to do it very early on x86-64. This means it doesn't need early ioremap et.al. We run it as a core initcall right now. I hope it's not needed for early setup. I added a general CONFIG_DMI symbol in case IA64 or someone else wants to reuse the code later too. Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Showing 9 changed files with 44 additions and 11 deletions Side-by-side Diff
arch/i386/Kconfig
arch/i386/kernel/dmi_scan.c
... | ... | @@ -4,8 +4,8 @@ |
4 | 4 | #include <linux/module.h> |
5 | 5 | #include <linux/dmi.h> |
6 | 6 | #include <linux/bootmem.h> |
7 | +#include <linux/slab.h> | |
7 | 8 | |
8 | - | |
9 | 9 | static char * __init dmi_string(struct dmi_header *dm, u8 s) |
10 | 10 | { |
11 | 11 | u8 *bp = ((u8 *) dm) + dm->length; |
... | ... | @@ -19,7 +19,7 @@ |
19 | 19 | } |
20 | 20 | |
21 | 21 | if (*bp != 0) { |
22 | - str = alloc_bootmem(strlen(bp) + 1); | |
22 | + str = dmi_alloc(strlen(bp) + 1); | |
23 | 23 | if (str != NULL) |
24 | 24 | strcpy(str, bp); |
25 | 25 | else |
... | ... | @@ -40,7 +40,7 @@ |
40 | 40 | u8 *buf, *data; |
41 | 41 | int i = 0; |
42 | 42 | |
43 | - buf = bt_ioremap(base, len); | |
43 | + buf = dmi_ioremap(base, len); | |
44 | 44 | if (buf == NULL) |
45 | 45 | return -1; |
46 | 46 | |
... | ... | @@ -65,7 +65,7 @@ |
65 | 65 | data += 2; |
66 | 66 | i++; |
67 | 67 | } |
68 | - bt_iounmap(buf, len); | |
68 | + dmi_iounmap(buf, len); | |
69 | 69 | return 0; |
70 | 70 | } |
71 | 71 | |
... | ... | @@ -112,7 +112,7 @@ |
112 | 112 | if ((*d & 0x80) == 0) |
113 | 113 | continue; |
114 | 114 | |
115 | - dev = alloc_bootmem(sizeof(*dev)); | |
115 | + dev = dmi_alloc(sizeof(*dev)); | |
116 | 116 | if (!dev) { |
117 | 117 | printk(KERN_ERR "dmi_save_devices: out of memory.\n"); |
118 | 118 | break; |
... | ... | @@ -131,7 +131,7 @@ |
131 | 131 | struct dmi_device *dev; |
132 | 132 | void * data; |
133 | 133 | |
134 | - data = alloc_bootmem(dm->length); | |
134 | + data = dmi_alloc(dm->length); | |
135 | 135 | if (data == NULL) { |
136 | 136 | printk(KERN_ERR "dmi_save_ipmi_device: out of memory.\n"); |
137 | 137 | return; |
... | ... | @@ -139,7 +139,7 @@ |
139 | 139 | |
140 | 140 | memcpy(data, dm, dm->length); |
141 | 141 | |
142 | - dev = alloc_bootmem(sizeof(*dev)); | |
142 | + dev = dmi_alloc(sizeof(*dev)); | |
143 | 143 | if (!dev) { |
144 | 144 | printk(KERN_ERR "dmi_save_ipmi_device: out of memory.\n"); |
145 | 145 | return; |
... | ... | @@ -221,7 +221,7 @@ |
221 | 221 | } |
222 | 222 | } |
223 | 223 | |
224 | -out: printk(KERN_INFO "DMI not present.\n"); | |
224 | +out: printk(KERN_INFO "DMI not present or invalid.\n"); | |
225 | 225 | } |
226 | 226 | |
227 | 227 |
arch/i386/kernel/setup.c
... | ... | @@ -45,6 +45,7 @@ |
45 | 45 | #include <linux/nodemask.h> |
46 | 46 | #include <linux/kexec.h> |
47 | 47 | #include <linux/crash_dump.h> |
48 | +#include <linux/dmi.h> | |
48 | 49 | |
49 | 50 | #include <video/edid.h> |
50 | 51 | |
... | ... | @@ -146,7 +147,6 @@ |
146 | 147 | struct e820map e820; |
147 | 148 | |
148 | 149 | extern void early_cpu_init(void); |
149 | -extern void dmi_scan_machine(void); | |
150 | 150 | extern void generic_apic_probe(char *); |
151 | 151 | extern int root_mountflags; |
152 | 152 |
arch/x86_64/Kconfig
arch/x86_64/kernel/Makefile
... | ... | @@ -7,7 +7,8 @@ |
7 | 7 | obj-y := process.o signal.o entry.o traps.o irq.o \ |
8 | 8 | ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_x86_64.o \ |
9 | 9 | x8664_ksyms.o i387.o syscall.o vsyscall.o \ |
10 | - setup64.o bootflag.o e820.o reboot.o quirks.o i8237.o | |
10 | + setup64.o bootflag.o e820.o reboot.o quirks.o i8237.o \ | |
11 | + dmi_scan.o | |
11 | 12 | |
12 | 13 | obj-$(CONFIG_X86_MCE) += mce.o |
13 | 14 | obj-$(CONFIG_X86_MCE_INTEL) += mce_intel.o |
... | ... | @@ -47,4 +48,5 @@ |
47 | 48 | quirks-y += ../../i386/kernel/quirks.o |
48 | 49 | i8237-y += ../../i386/kernel/i8237.o |
49 | 50 | msr-$(subst m,y,$(CONFIG_X86_MSR)) += ../../i386/kernel/msr.o |
51 | +dmi_scan-y += ../../i386/kernel/dmi_scan.o |
arch/x86_64/kernel/setup.c
... | ... | @@ -44,6 +44,7 @@ |
44 | 44 | #include <linux/mmzone.h> |
45 | 45 | #include <linux/kexec.h> |
46 | 46 | #include <linux/cpufreq.h> |
47 | +#include <linux/dmi.h> | |
47 | 48 | |
48 | 49 | #include <asm/mtrr.h> |
49 | 50 | #include <asm/uaccess.h> |
... | ... | @@ -1392,4 +1393,11 @@ |
1392 | 1393 | .stop = c_stop, |
1393 | 1394 | .show = show_cpuinfo, |
1394 | 1395 | }; |
1396 | + | |
1397 | +static int __init run_dmi_scan(void) | |
1398 | +{ | |
1399 | + dmi_scan_machine(); | |
1400 | + return 0; | |
1401 | +} | |
1402 | +core_initcall(run_dmi_scan); |
include/asm-i386/io.h
... | ... | @@ -131,6 +131,11 @@ |
131 | 131 | extern void *bt_ioremap(unsigned long offset, unsigned long size); |
132 | 132 | extern void bt_iounmap(void *addr, unsigned long size); |
133 | 133 | |
134 | +/* Use early IO mappings for DMI because it's initialized early */ | |
135 | +#define dmi_ioremap bt_ioremap | |
136 | +#define dmi_iounmap bt_iounmap | |
137 | +#define dmi_alloc alloc_bootmem | |
138 | + | |
134 | 139 | /* |
135 | 140 | * ISA I/O bus memory addresses are 1:1 with the physical address. |
136 | 141 | */ |
include/asm-x86_64/io.h
... | ... | @@ -143,6 +143,11 @@ |
143 | 143 | extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size); |
144 | 144 | extern void iounmap(volatile void __iomem *addr); |
145 | 145 | |
146 | +/* Use normal IO mappings for DMI */ | |
147 | +#define dmi_ioremap ioremap | |
148 | +#define dmi_iounmap(x,l) iounmap(x) | |
149 | +#define dmi_alloc(l) kmalloc(l, GFP_ATOMIC) | |
150 | + | |
146 | 151 | /* |
147 | 152 | * ISA I/O bus memory addresses are 1:1 with the physical address. |
148 | 153 | */ |
include/linux/dmi.h
... | ... | @@ -2,6 +2,7 @@ |
2 | 2 | #define __DMI_H__ |
3 | 3 | |
4 | 4 | #include <linux/list.h> |
5 | +#include <linux/config.h> | |
5 | 6 | |
6 | 7 | enum dmi_field { |
7 | 8 | DMI_NONE, |
8 | 9 | |
... | ... | @@ -60,12 +61,14 @@ |
60 | 61 | void *device_data; /* Type specific data */ |
61 | 62 | }; |
62 | 63 | |
63 | -#if defined(CONFIG_X86_32) | |
64 | +#ifdef CONFIG_DMI | |
64 | 65 | |
65 | 66 | extern int dmi_check_system(struct dmi_system_id *list); |
66 | 67 | extern char * dmi_get_system_info(int field); |
67 | 68 | extern struct dmi_device * dmi_find_device(int type, const char *name, |
68 | 69 | struct dmi_device *from); |
70 | +extern void dmi_scan_machine(void); | |
71 | + | |
69 | 72 | #else |
70 | 73 | |
71 | 74 | static inline int dmi_check_system(struct dmi_system_id *list) { return 0; } |