2 * I/O delay strategies for inb_p/outb_p
4 #include <linux/kernel.h>
5 #include <linux/module.h>
6 #include <linux/init.h>
7 #include <linux/delay.h>
12 * Allow for a DMI based override of port 0x80 needed for certain HP laptops
14 #define IO_DELAY_PORT_STD 0x80
15 #define IO_DELAY_PORT_ALT 0xed
17 static void standard_io_delay(void)
19 asm volatile ("outb %%al, %0" : : "N" (IO_DELAY_PORT_STD));
22 static void alternate_io_delay(void)
24 asm volatile ("outb %%al, %0" : : "N" (IO_DELAY_PORT_ALT));
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
31 #define IO_DELAY_USECS 2
34 * High on a hill was a lonely goatherd
36 static void udelay_io_delay(void)
38 udelay(IO_DELAY_USECS);
41 #ifndef CONFIG_UDELAY_IO_DELAY
42 static void (*io_delay)(void) = standard_io_delay;
44 static void (*io_delay)(void) = udelay_io_delay;
48 * Paravirt wants native_io_delay to be a constant.
50 void native_io_delay(void)
54 EXPORT_SYMBOL(native_io_delay);
56 #ifndef CONFIG_UDELAY_IO_DELAY
57 static int __init dmi_alternate_io_delay_port(const struct dmi_system_id *id)
59 printk(KERN_NOTICE "%s: using alternate I/O delay port\n", id->ident);
60 io_delay = alternate_io_delay;
64 static struct dmi_system_id __initdata alternate_io_delay_port_dmi_table[] = {
66 .callback = dmi_alternate_io_delay_port,
67 .ident = "HP Pavilion dv9000z",
69 DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
70 DMI_MATCH(DMI_BOARD_NAME, "30B9")
77 static int __initdata io_delay_override;
79 void __init io_delay_init(void)
81 if (!io_delay_override)
82 dmi_check_system(alternate_io_delay_port_dmi_table);
86 static int __init io_delay_param(char *s)
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;
100 #ifndef CONFIG_UDELAY_IO_DELAY
101 io_delay_override = 1;
106 early_param("io_delay", io_delay_param);