Commit e99286744599a66195de4cd975d7ef4d643c2789

Authored by Andi Kleen
Committed by Linus Torvalds
1 parent b347d25fbc

[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

... ... @@ -41,6 +41,10 @@
41 41 bool
42 42 default y
43 43  
  44 +config DMI
  45 + bool
  46 + default y
  47 +
44 48 source "init/Kconfig"
45 49  
46 50 menu "Processor type and features"
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  
... ... @@ -69,6 +69,10 @@
69 69 bool
70 70 default y
71 71  
  72 +config DMI
  73 + bool
  74 + default y
  75 +
72 76 source "init/Kconfig"
73 77  
74 78  
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 */
... ... @@ -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; }