# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.1156 -> 1.1157 # drivers/acpi/processor.c 1.13 -> 1.14 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 03/12/10 len.brown@intel.com 1.1157 # [ACPI] change hard-coded IO width to programmable width (Shaohua David Li) # http://bugzilla.kernel.org/show_bug.cgi?id=1349 # -------------------------------------------- # diff -Nru a/drivers/acpi/processor.c b/drivers/acpi/processor.c --- a/drivers/acpi/processor.c Wed Dec 10 23:43:10 2003 +++ b/drivers/acpi/processor.c Wed Dec 10 23:43:10 2003 @@ -144,6 +144,8 @@ int platform_limit; u16 control_register; u16 status_register; + u8 control_register_bit_width; + u8 status_register_bit_width; int state_count; struct acpi_processor_px states[ACPI_PROCESSOR_MAX_PERFORMANCE]; }; @@ -902,7 +904,7 @@ } pr->performance.control_register = (u16) reg->address; - + pr->performance.control_register_bit_width = reg->bit_width; /* * status_register */ @@ -929,6 +931,7 @@ } pr->performance.status_register = (u16) reg->address; + pr->performance.status_register_bit_width = reg->bit_width; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "control_register[0x%04x] status_register[0x%04x]\n", @@ -1018,6 +1021,42 @@ return_VALUE(result); } +static int +acpi_processor_write_port( + u16 port, + u8 bit_width, + u32 value) +{ + if (bit_width <= 8) { + outb(value, port); + } else if (bit_width <= 16) { + outw(value, port); + } else if (bit_width <= 32) { + outl(value, port); + } else { + return -ENODEV; + } + return 0; +} + +static int +acpi_processor_read_port( + u16 port, + u8 bit_width, + u32 *ret) +{ + *ret = 0; + if (bit_width <= 8) { + *ret = inb(port); + } else if (bit_width <= 16) { + *ret = inw(port); + } else if (bit_width <= 32) { + *ret = inl(port); + } else { + return -ENODEV; + } + return 0; +} static int acpi_processor_set_performance ( @@ -1025,7 +1064,9 @@ int state) { u16 port = 0; - u8 value = 0; + u8 bit_width = 0; + int ret = 0; + u32 value = 0; int i = 0; ACPI_FUNCTION_TRACE("acpi_processor_set_performance"); @@ -1064,12 +1105,18 @@ */ port = pr->performance.control_register; - value = (u16) pr->performance.states[state].control; + value = (u32) pr->performance.states[state].control; + bit_width = pr->performance.control_register_bit_width; ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Writing 0x%02x to port 0x%04x\n", value, port)); + "Writing 0x%08x to port 0x%04x\n", value, port)); - outb(value, port); + ret = acpi_processor_write_port(port, bit_width, value); + if (ret) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, + "Invalid port width 0x%04x\n", bit_width)); + return_VALUE(ret); + } /* * Then we read the 'status_register' and compare the value with the @@ -1079,19 +1126,25 @@ */ port = pr->performance.status_register; + bit_width = pr->performance.status_register_bit_width; ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Looking for 0x%02x from port 0x%04x\n", - (u8) pr->performance.states[state].status, port)); + "Looking for 0x%08x from port 0x%04x\n", + (u32) pr->performance.states[state].status, port)); for (i=0; i<100; i++) { - value = inb(port); - if (value == (u8) pr->performance.states[state].status) + ret = acpi_processor_read_port(port, bit_width, &value); + if (ret) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, + "Invalid port width 0x%04x\n", bit_width)); + return_VALUE(ret); + } + if (value == (u32) pr->performance.states[state].status) break; udelay(10); } - if (value != pr->performance.states[state].status) { + if (value != (u32) pr->performance.states[state].status) { ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Transition failed\n")); return_VALUE(-ENODEV); }