aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/Kconfig.debug9
-rw-r--r--arch/x86/boot/compressed/misc_32.c8
-rw-r--r--arch/x86/boot/compressed/misc_64.c8
-rw-r--r--arch/x86/kernel/Makefile_322
-rw-r--r--arch/x86/kernel/Makefile_642
-rw-r--r--arch/x86/kernel/io_delay.c106
-rw-r--r--arch/x86/kernel/setup_32.c2
-rw-r--r--arch/x86/kernel/setup_64.c2
8 files changed, 129 insertions, 10 deletions
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index 761ca7b5f120..40aba670fb37 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -112,4 +112,13 @@ config IOMMU_LEAK
112 Add a simple leak tracer to the IOMMU code. This is useful when you 112 Add a simple leak tracer to the IOMMU code. This is useful when you
113 are debugging a buggy device driver that leaks IOMMU mappings. 113 are debugging a buggy device driver that leaks IOMMU mappings.
114 114
115config UDELAY_IO_DELAY
116 bool "Delay I/O through udelay instead of outb"
117 depends on DEBUG_KERNEL
118 help
119 Make inb_p/outb_p use udelay() based delays by default. Please note
120 that udelay() does not have the same bus-level side-effects that
121 the normal outb based delay does meaning this could cause drivers
122 to change behaviour and/or bugs to surface.
123
115endmenu 124endmenu
diff --git a/arch/x86/boot/compressed/misc_32.c b/arch/x86/boot/compressed/misc_32.c
index b74d60d1b2fa..288e16283ef9 100644
--- a/arch/x86/boot/compressed/misc_32.c
+++ b/arch/x86/boot/compressed/misc_32.c
@@ -276,10 +276,10 @@ static void putstr(const char *s)
276 RM_SCREEN_INFO.orig_y = y; 276 RM_SCREEN_INFO.orig_y = y;
277 277
278 pos = (x + cols * y) * 2; /* Update cursor position */ 278 pos = (x + cols * y) * 2; /* Update cursor position */
279 outb_p(14, vidport); 279 outb(14, vidport);
280 outb_p(0xff & (pos >> 9), vidport+1); 280 outb(0xff & (pos >> 9), vidport+1);
281 outb_p(15, vidport); 281 outb(15, vidport);
282 outb_p(0xff & (pos >> 1), vidport+1); 282 outb(0xff & (pos >> 1), vidport+1);
283} 283}
284 284
285static void* memset(void* s, int c, unsigned n) 285static void* memset(void* s, int c, unsigned n)
diff --git a/arch/x86/boot/compressed/misc_64.c b/arch/x86/boot/compressed/misc_64.c
index 6ea015aa65e4..43e5fcc37be9 100644
--- a/arch/x86/boot/compressed/misc_64.c
+++ b/arch/x86/boot/compressed/misc_64.c
@@ -269,10 +269,10 @@ static void putstr(const char *s)
269 RM_SCREEN_INFO.orig_y = y; 269 RM_SCREEN_INFO.orig_y = y;
270 270
271 pos = (x + cols * y) * 2; /* Update cursor position */ 271 pos = (x + cols * y) * 2; /* Update cursor position */
272 outb_p(14, vidport); 272 outb(14, vidport);
273 outb_p(0xff & (pos >> 9), vidport+1); 273 outb(0xff & (pos >> 9), vidport+1);
274 outb_p(15, vidport); 274 outb(15, vidport);
275 outb_p(0xff & (pos >> 1), vidport+1); 275 outb(0xff & (pos >> 1), vidport+1);
276} 276}
277 277
278static void* memset(void* s, int c, unsigned n) 278static void* memset(void* s, int c, unsigned n)
diff --git a/arch/x86/kernel/Makefile_32 b/arch/x86/kernel/Makefile_32
index a7bc93c27662..0cc1981d1e38 100644
--- a/arch/x86/kernel/Makefile_32
+++ b/arch/x86/kernel/Makefile_32
@@ -8,7 +8,7 @@ CPPFLAGS_vmlinux.lds += -Ui386
8obj-y := process_32.o signal_32.o entry_32.o traps_32.o irq_32.o \ 8obj-y := process_32.o signal_32.o entry_32.o traps_32.o irq_32.o \
9 ptrace_32.o time_32.o ioport_32.o ldt_32.o setup_32.o i8259_32.o sys_i386_32.o \ 9 ptrace_32.o time_32.o ioport_32.o ldt_32.o setup_32.o i8259_32.o sys_i386_32.o \
10 pci-dma_32.o i386_ksyms_32.o i387_32.o bootflag.o e820_32.o\ 10 pci-dma_32.o i386_ksyms_32.o i387_32.o bootflag.o e820_32.o\
11 quirks.o i8237.o topology.o alternative.o i8253.o tsc_32.o 11 quirks.o i8237.o topology.o alternative.o i8253.o tsc_32.o io_delay.o
12 12
13obj-$(CONFIG_STACKTRACE) += stacktrace.o 13obj-$(CONFIG_STACKTRACE) += stacktrace.o
14obj-y += cpu/ 14obj-y += cpu/
diff --git a/arch/x86/kernel/Makefile_64 b/arch/x86/kernel/Makefile_64
index 5a88890d8ee9..08a68f0d8fda 100644
--- a/arch/x86/kernel/Makefile_64
+++ b/arch/x86/kernel/Makefile_64
@@ -11,7 +11,7 @@ obj-y := process_64.o signal_64.o entry_64.o traps_64.o irq_64.o \
11 x8664_ksyms_64.o i387_64.o syscall_64.o vsyscall_64.o \ 11 x8664_ksyms_64.o i387_64.o syscall_64.o vsyscall_64.o \
12 setup64.o bootflag.o e820_64.o reboot_64.o quirks.o i8237.o \ 12 setup64.o bootflag.o e820_64.o reboot_64.o quirks.o i8237.o \
13 pci-dma_64.o pci-nommu_64.o alternative.o hpet.o tsc_64.o bugs_64.o \ 13 pci-dma_64.o pci-nommu_64.o alternative.o hpet.o tsc_64.o bugs_64.o \
14 i8253.o 14 i8253.o io_delay.o
15 15
16obj-$(CONFIG_STACKTRACE) += stacktrace.o 16obj-$(CONFIG_STACKTRACE) += stacktrace.o
17obj-y += cpu/ 17obj-y += cpu/
diff --git a/arch/x86/kernel/io_delay.c b/arch/x86/kernel/io_delay.c
new file mode 100644
index 000000000000..4d955e74b974
--- /dev/null
+++ b/arch/x86/kernel/io_delay.c
@@ -0,0 +1,106 @@
1/*
2 * I/O delay strategies for inb_p/outb_p
3 */
4#include <linux/kernel.h>
5#include <linux/module.h>
6#include <linux/init.h>
7#include <linux/delay.h>
8#include <linux/dmi.h>
9#include <asm/io.h>
10
11/*
12 * Allow for a DMI based override of port 0x80 needed for certain HP laptops
13 */
14#define IO_DELAY_PORT_STD 0x80
15#define IO_DELAY_PORT_ALT 0xed
16
17static void standard_io_delay(void)
18{
19 asm volatile ("outb %%al, %0" : : "N" (IO_DELAY_PORT_STD));
20}
21
22static void alternate_io_delay(void)
23{
24 asm volatile ("outb %%al, %0" : : "N" (IO_DELAY_PORT_ALT));
25}
26
27/*
28 * 2 usecs is an upper-bound for the outb delay but note that udelay doesn't
29 * have the bus-level side-effects that outb does
30 */
31#define IO_DELAY_USECS 2
32
33/*
34 * High on a hill was a lonely goatherd
35 */
36static void udelay_io_delay(void)
37{
38 udelay(IO_DELAY_USECS);
39}
40
41#ifndef CONFIG_UDELAY_IO_DELAY
42static void (*io_delay)(void) = standard_io_delay;
43#else
44static void (*io_delay)(void) = udelay_io_delay;
45#endif
46
47/*
48 * Paravirt wants native_io_delay to be a constant.
49 */
50void native_io_delay(void)
51{
52 io_delay();
53}
54EXPORT_SYMBOL(native_io_delay);
55
56#ifndef CONFIG_UDELAY_IO_DELAY
57static int __init dmi_alternate_io_delay_port(const struct dmi_system_id *id)
58{
59 printk(KERN_NOTICE "%s: using alternate I/O delay port\n", id->ident);
60 io_delay = alternate_io_delay;
61 return 0;
62}
63
64static struct dmi_system_id __initdata alternate_io_delay_port_dmi_table[] = {
65 {
66 .callback = dmi_alternate_io_delay_port,
67 .ident = "HP Pavilion dv9000z",
68 .matches = {
69 DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
70 DMI_MATCH(DMI_BOARD_NAME, "30B9")
71 }
72 },
73 {
74 }
75};
76
77static int __initdata io_delay_override;
78
79void __init io_delay_init(void)
80{
81 if (!io_delay_override)
82 dmi_check_system(alternate_io_delay_port_dmi_table);
83}
84#endif
85
86static int __init io_delay_param(char *s)
87{
88 if (!s)
89 return -EINVAL;
90
91 if (!strcmp(s, "standard"))
92 io_delay = standard_io_delay;
93 else if (!strcmp(s, "alternate"))
94 io_delay = alternate_io_delay;
95 else if (!strcmp(s, "udelay"))
96 io_delay = udelay_io_delay;
97 else
98 return -EINVAL;
99
100#ifndef CONFIG_UDELAY_IO_DELAY
101 io_delay_override = 1;
102#endif
103 return 0;
104}
105
106early_param("io_delay", io_delay_param);
diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c
index 9c24b45b513c..51bdc0b1b72e 100644
--- a/arch/x86/kernel/setup_32.c
+++ b/arch/x86/kernel/setup_32.c
@@ -648,6 +648,8 @@ void __init setup_arch(char **cmdline_p)
648 648
649 dmi_scan_machine(); 649 dmi_scan_machine();
650 650
651 io_delay_init();;
652
651#ifdef CONFIG_X86_GENERICARCH 653#ifdef CONFIG_X86_GENERICARCH
652 generic_apic_probe(); 654 generic_apic_probe();
653#endif 655#endif
diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c
index 30d94d1d5f5f..ec976edf0399 100644
--- a/arch/x86/kernel/setup_64.c
+++ b/arch/x86/kernel/setup_64.c
@@ -311,6 +311,8 @@ void __init setup_arch(char **cmdline_p)
311 311
312 dmi_scan_machine(); 312 dmi_scan_machine();
313 313
314 io_delay_init();
315
314#ifdef CONFIG_SMP 316#ifdef CONFIG_SMP
315 /* setup to use the static apicid table during kernel startup */ 317 /* setup to use the static apicid table during kernel startup */
316 x86_cpu_to_apicid_ptr = (void *)&x86_cpu_to_apicid_init; 318 x86_cpu_to_apicid_ptr = (void *)&x86_cpu_to_apicid_init;