diff options
| author | Len Brown <len.brown@intel.com> | 2004-01-15 07:04:28 -0500 |
|---|---|---|
| committer | Len Brown <len.brown@intel.com> | 2004-01-15 07:04:28 -0500 |
| commit | 3136d3401b03ceea1984336d03644924aeecab56 (patch) | |
| tree | d8a8c858867461ee3e51c8fed9f3d00e14ed0ca1 | |
| parent | 11afe463de78e8231ef20c1774f8d41defcab683 (diff) | |
[ACPI] change hard-coded IO width to programmable width
http://bugzilla.kernel.org/show_bug.cgi?id=1349
from David Shaohua Li and Venatesh Pallipadi
| -rw-r--r-- | arch/i386/kernel/cpu/cpufreq/acpi.c | 71 | ||||
| -rw-r--r-- | include/acpi/processor.h | 2 |
2 files changed, 63 insertions, 10 deletions
diff --git a/arch/i386/kernel/cpu/cpufreq/acpi.c b/arch/i386/kernel/cpu/cpufreq/acpi.c index 1da77a79043e..d493f49b527f 100644 --- a/arch/i386/kernel/cpu/cpufreq/acpi.c +++ b/arch/i386/kernel/cpu/cpufreq/acpi.c @@ -108,7 +108,7 @@ acpi_processor_get_performance_control ( } perf->control_register = (u16) reg->address; - + perf->control_register_bit_width = reg->bit_width; /* * status_register */ @@ -135,6 +135,7 @@ acpi_processor_get_performance_control ( } perf->status_register = (u16) reg->address; + perf->status_register_bit_width = reg->bit_width; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "control_register[0x%04x] status_register[0x%04x]\n", @@ -224,6 +225,42 @@ end: 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 ( @@ -231,7 +268,9 @@ acpi_processor_set_performance ( int state) { u16 port = 0; - u16 value = 0; + u8 bit_width = 0; + int ret = 0; + u32 value = 0; int i = 0; struct cpufreq_freqs cpufreq_freqs; @@ -279,12 +318,18 @@ acpi_processor_set_performance ( */ port = perf->control_register; - value = (u16) perf->states[state].control; + bit_width = perf->control_register_bit_width; + value = (u32) perf->states[state].control; ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Writing 0x%04x to port 0x%04x\n", value, port)); + "Writing 0x%08x to port 0x%04x\n", value, port)); - outw(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 @@ -294,14 +339,20 @@ acpi_processor_set_performance ( */ port = perf->status_register; + bit_width = perf->status_register_bit_width; ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Looking for 0x%04x from port 0x%04x\n", - (u16) perf->states[state].status, port)); + "Looking for 0x%08x from port 0x%04x\n", + (u32) perf->states[state].status, port)); for (i=0; i<100; i++) { - value = inw(port); - if (value == (u16) perf->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) perf->states[state].status) break; udelay(10); } @@ -309,7 +360,7 @@ acpi_processor_set_performance ( /* notify cpufreq */ cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE); - if (value != (u16) perf->states[state].status) { + if (value != (u32) perf->states[state].status) { unsigned int tmp = cpufreq_freqs.new; cpufreq_freqs.new = cpufreq_freqs.old; cpufreq_freqs.old = tmp; diff --git a/include/acpi/processor.h b/include/acpi/processor.h index bbae343f2bd8..985cc0616dd1 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -72,6 +72,8 @@ struct acpi_processor_performance { 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]; struct cpufreq_frequency_table freq_table[ACPI_PROCESSOR_MAX_PERFORMANCE]; |
