Commit 3537d161 authored by Dominik Brodowski's avatar Dominik Brodowski Committed by Linus Torvalds

[PATCH] cpufreq (2/5): x86 driver updates #2 (acpi, longhaul)

- update the VIA Longhaul driver to use frequency table helpers and
  the advanced cpufreq driver registration interface.
- cleanup of the ACPI P-States cpufreq driver
- very small update of the core -- set 24API values ahead of the setpolicy
  call.
parent 5787e471
...@@ -56,6 +56,16 @@ config X86_ACPI_CPUFREQ ...@@ -56,6 +56,16 @@ config X86_ACPI_CPUFREQ
If in doubt, say N. If in doubt, say N.
config X86_ACPI_CPUFREQ_PROC_INTF
bool "/proc/acpi/processor/../performance interface (deprecated)"
depends on X86_ACPI_CPUFREQ && PROC_FS
help
This enables the deprecated /proc/acpi/processor/../performance
interface. While it is helpful for debugging, the generic,
cross-architecture cpufreq interfaces should be used.
If in doubt, say N.
config ELAN_CPUFREQ config ELAN_CPUFREQ
tristate "AMD Elan" tristate "AMD Elan"
depends on CPU_FREQ_TABLE && MELAN depends on CPU_FREQ_TABLE && MELAN
...@@ -139,7 +149,7 @@ config X86_LONGRUN ...@@ -139,7 +149,7 @@ config X86_LONGRUN
config X86_LONGHAUL config X86_LONGHAUL
tristate "VIA Cyrix III Longhaul" tristate "VIA Cyrix III Longhaul"
depends on CPU_FREQ depends on CPU_FREQ_TABLE
help help
This adds the CPUFreq driver for VIA Samuel/CyrixIII, This adds the CPUFreq driver for VIA Samuel/CyrixIII,
VIA Cyrix Samuel/C3, VIA Cyrix Ezra and VIA Cyrix Ezra-T VIA Cyrix Samuel/C3, VIA Cyrix Ezra and VIA Cyrix Ezra-T
......
...@@ -50,23 +50,13 @@ MODULE_DESCRIPTION(ACPI_PROCESSOR_DRIVER_NAME); ...@@ -50,23 +50,13 @@ MODULE_DESCRIPTION(ACPI_PROCESSOR_DRIVER_NAME);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
/* Performance Management */
static struct acpi_processor_performance *performance; static struct acpi_processor_performance *performance;
static struct cpufreq_driver acpi_cpufreq_driver; static struct cpufreq_driver acpi_cpufreq_driver;
static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file);
static struct file_operations acpi_processor_perf_fops = {
.open = acpi_processor_perf_open_fs,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int static int
acpi_processor_get_performance_control ( acpi_processor_get_performance_control (
struct acpi_processor *pr) struct acpi_processor_performance *perf)
{ {
int result = 0; int result = 0;
acpi_status status = 0; acpi_status status = 0;
...@@ -77,7 +67,7 @@ acpi_processor_get_performance_control ( ...@@ -77,7 +67,7 @@ acpi_processor_get_performance_control (
ACPI_FUNCTION_TRACE("acpi_processor_get_performance_control"); ACPI_FUNCTION_TRACE("acpi_processor_get_performance_control");
status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer); status = acpi_evaluate_object(perf->pr->handle, "_PCT", NULL, &buffer);
if(ACPI_FAILURE(status)) { if(ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PCT\n")); ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PCT\n"));
return_VALUE(-ENODEV); return_VALUE(-ENODEV);
...@@ -116,7 +106,7 @@ acpi_processor_get_performance_control ( ...@@ -116,7 +106,7 @@ acpi_processor_get_performance_control (
goto end; goto end;
} }
pr->performance->control_register = (u16) reg->address; perf->control_register = (u16) reg->address;
/* /*
* status_register * status_register
...@@ -143,12 +133,12 @@ acpi_processor_get_performance_control ( ...@@ -143,12 +133,12 @@ acpi_processor_get_performance_control (
goto end; goto end;
} }
pr->performance->status_register = (u16) reg->address; perf->status_register = (u16) reg->address;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"control_register[0x%04x] status_register[0x%04x]\n", "control_register[0x%04x] status_register[0x%04x]\n",
pr->performance->control_register, perf->control_register,
pr->performance->status_register)); perf->status_register));
end: end:
acpi_os_free(buffer.pointer); acpi_os_free(buffer.pointer);
...@@ -159,7 +149,7 @@ acpi_processor_get_performance_control ( ...@@ -159,7 +149,7 @@ acpi_processor_get_performance_control (
static int static int
acpi_processor_get_performance_states ( acpi_processor_get_performance_states (
struct acpi_processor* pr) struct acpi_processor_performance * perf)
{ {
int result = 0; int result = 0;
acpi_status status = AE_OK; acpi_status status = AE_OK;
...@@ -171,7 +161,7 @@ acpi_processor_get_performance_states ( ...@@ -171,7 +161,7 @@ acpi_processor_get_performance_states (
ACPI_FUNCTION_TRACE("acpi_processor_get_performance_states"); ACPI_FUNCTION_TRACE("acpi_processor_get_performance_states");
status = acpi_evaluate_object(pr->handle, "_PSS", NULL, &buffer); status = acpi_evaluate_object(perf->pr->handle, "_PSS", NULL, &buffer);
if(ACPI_FAILURE(status)) { if(ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PSS\n")); ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PSS\n"));
return_VALUE(-ENODEV); return_VALUE(-ENODEV);
...@@ -188,20 +178,20 @@ acpi_processor_get_performance_states ( ...@@ -188,20 +178,20 @@ acpi_processor_get_performance_states (
pss->package.count)); pss->package.count));
if (pss->package.count > ACPI_PROCESSOR_MAX_PERFORMANCE) { if (pss->package.count > ACPI_PROCESSOR_MAX_PERFORMANCE) {
pr->performance->state_count = ACPI_PROCESSOR_MAX_PERFORMANCE; perf->state_count = ACPI_PROCESSOR_MAX_PERFORMANCE;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Limiting number of states to max (%d)\n", "Limiting number of states to max (%d)\n",
ACPI_PROCESSOR_MAX_PERFORMANCE)); ACPI_PROCESSOR_MAX_PERFORMANCE));
} }
else else
pr->performance->state_count = pss->package.count; perf->state_count = pss->package.count;
if (pr->performance->state_count > 1) if (perf->state_count > 1)
pr->flags.performance = 1; perf->pr->flags.performance = 1;
for (i = 0; i < pr->performance->state_count; i++) { for (i = 0; i < perf->state_count; i++) {
struct acpi_processor_px *px = &(pr->performance->states[i]); struct acpi_processor_px *px = &(perf->states[i]);
state.length = sizeof(struct acpi_processor_px); state.length = sizeof(struct acpi_processor_px);
state.pointer = px; state.pointer = px;
...@@ -236,7 +226,7 @@ acpi_processor_get_performance_states ( ...@@ -236,7 +226,7 @@ acpi_processor_get_performance_states (
static int static int
acpi_processor_set_performance ( acpi_processor_set_performance (
struct acpi_processor *pr, struct acpi_processor_performance *perf,
int state) int state)
{ {
u16 port = 0; u16 port = 0;
...@@ -246,38 +236,38 @@ acpi_processor_set_performance ( ...@@ -246,38 +236,38 @@ acpi_processor_set_performance (
ACPI_FUNCTION_TRACE("acpi_processor_set_performance"); ACPI_FUNCTION_TRACE("acpi_processor_set_performance");
if (!pr) if (!perf || !perf->pr)
return_VALUE(-EINVAL); return_VALUE(-EINVAL);
if (!pr->flags.performance) if (!perf->pr->flags.performance)
return_VALUE(-ENODEV); return_VALUE(-ENODEV);
if (state >= pr->performance->state_count) { if (state >= perf->state_count) {
ACPI_DEBUG_PRINT((ACPI_DB_WARN, ACPI_DEBUG_PRINT((ACPI_DB_WARN,
"Invalid target state (P%d)\n", state)); "Invalid target state (P%d)\n", state));
return_VALUE(-ENODEV); return_VALUE(-ENODEV);
} }
if (state < pr->performance_platform_limit) { if (state < perf->pr->performance_platform_limit) {
ACPI_DEBUG_PRINT((ACPI_DB_WARN, ACPI_DEBUG_PRINT((ACPI_DB_WARN,
"Platform limit (P%d) overrides target state (P%d)\n", "Platform limit (P%d) overrides target state (P%d)\n",
pr->performance->platform_limit, state)); perf->pr->performance_platform_limit, state));
return_VALUE(-ENODEV); return_VALUE(-ENODEV);
} }
if (state == pr->performance->state) { if (state == perf->state) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Already at target state (P%d)\n", state)); "Already at target state (P%d)\n", state));
return_VALUE(0); return_VALUE(0);
} }
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Transitioning from P%d to P%d\n", ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Transitioning from P%d to P%d\n",
pr->performance->state, state)); perf->state, state));
/* cpufreq frequency struct */ /* cpufreq frequency struct */
cpufreq_freqs.cpu = pr->id; cpufreq_freqs.cpu = perf->pr->id;
cpufreq_freqs.old = pr->performance->states[pr->performance->state].core_frequency; cpufreq_freqs.old = perf->states[perf->state].core_frequency;
cpufreq_freqs.new = pr->performance->states[state].core_frequency; cpufreq_freqs.new = perf->states[state].core_frequency;
/* notify cpufreq */ /* notify cpufreq */
cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_PRECHANGE); cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_PRECHANGE);
...@@ -287,8 +277,8 @@ acpi_processor_set_performance ( ...@@ -287,8 +277,8 @@ acpi_processor_set_performance (
* control_register. * control_register.
*/ */
port = pr->performance->control_register; port = perf->control_register;
value = (u16) pr->performance->states[state].control; value = (u16) perf->states[state].control;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Writing 0x%02x to port 0x%04x\n", value, port)); "Writing 0x%02x to port 0x%04x\n", value, port));
...@@ -302,15 +292,15 @@ acpi_processor_set_performance ( ...@@ -302,15 +292,15 @@ acpi_processor_set_performance (
* giving up. * giving up.
*/ */
port = pr->performance->status_register; port = perf->status_register;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Looking for 0x%02x from port 0x%04x\n", "Looking for 0x%02x from port 0x%04x\n",
(u8) pr->performance->states[state].status, port)); (u8) perf->states[state].status, port));
for (i=0; i<100; i++) { for (i=0; i<100; i++) {
value = inb(port); value = inb(port);
if (value == (u8) pr->performance->states[state].status) if (value == (u8) perf->states[state].status)
break; break;
udelay(10); udelay(10);
} }
...@@ -318,7 +308,7 @@ acpi_processor_set_performance ( ...@@ -318,7 +308,7 @@ acpi_processor_set_performance (
/* notify cpufreq */ /* notify cpufreq */
cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE); cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE);
if (value != pr->performance->states[state].status) { if (value != perf->states[state].status) {
unsigned int tmp = cpufreq_freqs.new; unsigned int tmp = cpufreq_freqs.new;
cpufreq_freqs.new = cpufreq_freqs.old; cpufreq_freqs.new = cpufreq_freqs.old;
cpufreq_freqs.old = tmp; cpufreq_freqs.old = tmp;
...@@ -332,11 +322,23 @@ acpi_processor_set_performance ( ...@@ -332,11 +322,23 @@ acpi_processor_set_performance (
"Transition successful after %d microseconds\n", "Transition successful after %d microseconds\n",
i * 10)); i * 10));
pr->performance->state = state; perf->state = state;
return_VALUE(0); return_VALUE(0);
} }
#ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF
/* /proc/acpi/processor/../performance interface (DEPRECATED) */
static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file);
static struct file_operations acpi_processor_perf_fops = {
.open = acpi_processor_perf_open_fs,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset) static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset)
{ {
struct acpi_processor *pr = (struct acpi_processor *)seq->private; struct acpi_processor *pr = (struct acpi_processor *)seq->private;
...@@ -347,7 +349,7 @@ static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset) ...@@ -347,7 +349,7 @@ static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset)
if (!pr) if (!pr)
goto end; goto end;
if (!pr->flags.performance) { if (!pr->flags.performance || !pr->performance) {
seq_puts(seq, "<not supported>\n"); seq_puts(seq, "<not supported>\n");
goto end; goto end;
} }
...@@ -379,8 +381,8 @@ static int ...@@ -379,8 +381,8 @@ static int
acpi_processor_write_performance ( acpi_processor_write_performance (
struct file *file, struct file *file,
const char *buffer, const char *buffer,
unsigned long count, size_t count,
void *data) loff_t *data)
{ {
int result = 0; int result = 0;
struct acpi_processor *pr = (struct acpi_processor *) data; struct acpi_processor *pr = (struct acpi_processor *) data;
...@@ -411,24 +413,78 @@ acpi_processor_write_performance ( ...@@ -411,24 +413,78 @@ acpi_processor_write_performance (
return_VALUE(count); return_VALUE(count);
} }
static void
acpi_cpufreq_add_file (
struct acpi_processor *pr)
{
struct proc_dir_entry *entry = NULL;
struct acpi_device *device = NULL;
ACPI_FUNCTION_TRACE("acpi_cpufreq_addfile");
if (acpi_bus_get_device(pr->handle, &device))
return_VOID;
/* add file 'performance' [R/W] */
entry = create_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
if (!entry)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Unable to create '%s' fs entry\n",
ACPI_PROCESSOR_FILE_PERFORMANCE));
else {
entry->proc_fops = &acpi_processor_perf_fops;
entry->proc_fops->write = acpi_processor_write_performance;
entry->data = acpi_driver_data(device);
}
return_VOID;
}
static void
acpi_cpufreq_remove_file (
struct acpi_processor *pr)
{
struct acpi_device *device = NULL;
ACPI_FUNCTION_TRACE("acpi_cpufreq_addfile");
if (acpi_bus_get_device(pr->handle, &device))
return_VOID;
/* remove file 'performance' */
remove_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
acpi_device_dir(device));
return_VOID;
}
#else
static void acpi_cpufreq_add_file (struct acpi_processor *pr) { return; }
static void acpi_cpufreq_remove_file (struct acpi_processor *pr) { return; }
#endif /* CONFIG_X86_ACPI_CPUFREQ_PROC_INTF */
static int static int
acpi_cpufreq_setpolicy ( acpi_cpufreq_target (
struct cpufreq_policy *policy) struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{ {
struct acpi_processor *pr = performance[policy->cpu].pr; struct acpi_processor_performance *perf = &performance[policy->cpu];
unsigned int next_state = 0; unsigned int next_state = 0;
unsigned int result = 0; unsigned int result = 0;
ACPI_FUNCTION_TRACE("acpi_cpufreq_setpolicy"); ACPI_FUNCTION_TRACE("acpi_cpufreq_setpolicy");
result = cpufreq_frequency_table_setpolicy(policy, result = cpufreq_frequency_table_target(policy,
&performance[policy->cpu].freq_table[pr->limit.state.px], &perf->freq_table[perf->pr->limit.state.px],
target_freq,
relation,
&next_state); &next_state);
if (result) if (result)
return_VALUE(result); return_VALUE(result);
result = acpi_processor_set_performance (pr, next_state); result = acpi_processor_set_performance (perf, next_state);
return_VALUE(result); return_VALUE(result);
} }
...@@ -439,18 +495,17 @@ acpi_cpufreq_verify ( ...@@ -439,18 +495,17 @@ acpi_cpufreq_verify (
struct cpufreq_policy *policy) struct cpufreq_policy *policy)
{ {
unsigned int result = 0; unsigned int result = 0;
unsigned int cpu = policy->cpu; struct acpi_processor_performance *perf = &performance[policy->cpu];
struct acpi_processor *pr = performance[policy->cpu].pr;
ACPI_FUNCTION_TRACE("acpi_cpufreq_verify"); ACPI_FUNCTION_TRACE("acpi_cpufreq_verify");
result = cpufreq_frequency_table_verify(policy, result = cpufreq_frequency_table_verify(policy,
&performance[cpu].freq_table[pr->limit.state.px]); &perf->freq_table[perf->pr->limit.state.px]);
cpufreq_verify_within_limits( cpufreq_verify_within_limits(
policy, policy,
performance[cpu].states[performance[cpu].state_count - 1].core_frequency * 1000, perf->states[perf->state_count - 1].core_frequency * 1000,
performance[cpu].states[pr->limit.state.px].core_frequency * 1000); perf->states[perf->pr->limit.state.px].core_frequency * 1000);
return_VALUE(result); return_VALUE(result);
} }
...@@ -458,7 +513,7 @@ acpi_cpufreq_verify ( ...@@ -458,7 +513,7 @@ acpi_cpufreq_verify (
static int static int
acpi_processor_get_performance_info ( acpi_processor_get_performance_info (
struct acpi_processor *pr) struct acpi_processor_performance *perf)
{ {
int result = 0; int result = 0;
acpi_status status = AE_OK; acpi_status status = AE_OK;
...@@ -466,31 +521,32 @@ acpi_processor_get_performance_info ( ...@@ -466,31 +521,32 @@ acpi_processor_get_performance_info (
ACPI_FUNCTION_TRACE("acpi_processor_get_performance_info"); ACPI_FUNCTION_TRACE("acpi_processor_get_performance_info");
if (!pr) if (!perf || !perf->pr || !perf->pr->handle)
return_VALUE(-EINVAL); return_VALUE(-EINVAL);
status = acpi_get_handle(pr->handle, "_PCT", &handle); status = acpi_get_handle(perf->pr->handle, "_PCT", &handle);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"ACPI-based processor performance control unavailable\n")); "ACPI-based processor performance control unavailable\n"));
return_VALUE(-ENODEV); return_VALUE(-ENODEV);
} }
result = acpi_processor_get_performance_control(pr); result = acpi_processor_get_performance_control(perf);
if (result) if (result)
return_VALUE(result); return_VALUE(result);
result = acpi_processor_get_performance_states(pr); result = acpi_processor_get_performance_states(perf);
if (result) if (result)
return_VALUE(result); return_VALUE(result);
result = acpi_processor_get_platform_limit(pr); result = acpi_processor_get_platform_limit(perf->pr);
if (result) if (result)
return_VALUE(result); return_VALUE(result);
return_VALUE(0); return_VALUE(0);
} }
static int static int
acpi_cpufreq_cpu_init ( acpi_cpufreq_cpu_init (
struct cpufreq_policy *policy) struct cpufreq_policy *policy)
...@@ -498,22 +554,18 @@ acpi_cpufreq_cpu_init ( ...@@ -498,22 +554,18 @@ acpi_cpufreq_cpu_init (
unsigned int i; unsigned int i;
unsigned int cpu = policy->cpu; unsigned int cpu = policy->cpu;
struct acpi_processor *pr = NULL; struct acpi_processor *pr = NULL;
struct acpi_processor_performance *perf = &performance[policy->cpu];
unsigned int result = 0; unsigned int result = 0;
struct proc_dir_entry *entry = NULL;
struct acpi_device *device = NULL;
ACPI_FUNCTION_TRACE("acpi_cpufreq_cpu_init"); ACPI_FUNCTION_TRACE("acpi_cpufreq_cpu_init");
acpi_processor_register_performance(&performance[cpu], &pr, cpu); acpi_processor_register_performance(perf, &pr, cpu);
pr = performance[cpu].pr; pr = performance[cpu].pr;
if (!pr) if (!pr)
return_VALUE(-ENODEV); return_VALUE(-ENODEV);
if (acpi_bus_get_device(pr->handle, &device)) result = acpi_processor_get_performance_info(perf);
return_VALUE(-ENODEV);
result = acpi_processor_get_performance_info(performance[cpu].pr);
if (result) if (result)
return_VALUE(-ENODEV); return_VALUE(-ENODEV);
...@@ -523,52 +575,64 @@ acpi_cpufreq_cpu_init ( ...@@ -523,52 +575,64 @@ acpi_cpufreq_cpu_init (
/* detect transition latency */ /* detect transition latency */
policy->cpuinfo.transition_latency = 0; policy->cpuinfo.transition_latency = 0;
for (i=0;i<performance[cpu].state_count;i++) { for (i=0;i<perf->state_count;i++) {
if (performance[cpu].states[i].transition_latency > policy->cpuinfo.transition_latency) if (perf->states[i].transition_latency > policy->cpuinfo.transition_latency)
policy->cpuinfo.transition_latency = performance[cpu].states[i].transition_latency; policy->cpuinfo.transition_latency = perf->states[i].transition_latency;
} }
policy->policy = CPUFREQ_POLICY_PERFORMANCE; policy->policy = CPUFREQ_POLICY_PERFORMANCE;
#ifdef CONFIG_CPU_FREQ_24_API
acpi_cpufreq_driver.cpu_cur_freq[policy->cpu] = perf->states[pr->limit.state.px].core_frequency * 1000;
#endif
/* table init */ /* table init */
for (i=0; i<=performance[cpu].state_count; i++) for (i=0; i<=perf->state_count; i++)
{ {
performance[cpu].freq_table[i].index = i; perf->freq_table[i].index = i;
if (i<performance[cpu].state_count) if (i<perf->state_count)
performance[cpu].freq_table[i].frequency = performance[cpu].states[i].core_frequency * 1000; perf->freq_table[i].frequency = perf->states[i].core_frequency * 1000;
else else
performance[cpu].freq_table[i].frequency = CPUFREQ_TABLE_END; perf->freq_table[i].frequency = CPUFREQ_TABLE_END;
} }
#ifdef CONFIG_CPU_FREQ_24_API result = cpufreq_frequency_table_cpuinfo(policy, &perf->freq_table[0]);
acpi_cpufreq_driver.cpu_cur_freq[policy->cpu] = performance[cpu].states[pr->limit.state.px].core_frequency * 1000;
#endif
result = cpufreq_frequency_table_cpuinfo(policy, &performance[cpu].freq_table[0]);
/* add file 'performance' [R/W] */ acpi_cpufreq_add_file(pr);
entry = create_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
if (!entry)
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Unable to create '%s' fs entry\n",
ACPI_PROCESSOR_FILE_PERFORMANCE));
else {
entry->proc_fops = &acpi_processor_perf_fops;
entry->write_proc = acpi_processor_write_performance;
entry->data = acpi_driver_data(device);
}
return_VALUE(result); return_VALUE(result);
} }
static int
acpi_cpufreq_cpu_exit (
struct cpufreq_policy *policy)
{
struct acpi_processor *pr = performance[policy->cpu].pr;
ACPI_FUNCTION_TRACE("acpi_cpufreq_cpu_exit");
acpi_cpufreq_remove_file(pr);
return_VALUE(0);
}
static struct cpufreq_driver acpi_cpufreq_driver = {
.verify = acpi_cpufreq_verify,
.target = acpi_cpufreq_target,
.init = acpi_cpufreq_cpu_init,
.exit = acpi_cpufreq_cpu_exit,
.name = "acpi-cpufreq",
};
static int __init static int __init
acpi_cpufreq_init (void) acpi_cpufreq_init (void)
{ {
int result = 0; int result = 0;
int current_state = 0; int current_state = 0;
int i = 0; int i = 0;
struct acpi_processor *pr; struct acpi_processor *pr = NULL;
struct acpi_processor_performance *perf = NULL;
ACPI_FUNCTION_TRACE("acpi_cpufreq_init"); ACPI_FUNCTION_TRACE("acpi_cpufreq_init");
...@@ -579,10 +643,9 @@ acpi_cpufreq_init (void) ...@@ -579,10 +643,9 @@ acpi_cpufreq_init (void)
performance = kmalloc(NR_CPUS * sizeof(struct acpi_processor_performance), GFP_KERNEL); performance = kmalloc(NR_CPUS * sizeof(struct acpi_processor_performance), GFP_KERNEL);
if (!performance) if (!performance)
return_VALUE(-ENOMEM); return_VALUE(-ENOMEM);
memset(performance, 0, NR_CPUS * sizeof(struct acpi_processor_performance)); memset(performance, 0, NR_CPUS * sizeof(struct acpi_processor_performance));
/* register struct acpi_performance performance */ /* register struct acpi_processor_performance performance */
for (i=0; i<NR_CPUS; i++) { for (i=0; i<NR_CPUS; i++) {
if (cpu_online(i)) if (cpu_online(i))
acpi_processor_register_performance(&performance[i], &pr, i); acpi_processor_register_performance(&performance[i], &pr, i);
...@@ -591,11 +654,13 @@ acpi_cpufreq_init (void) ...@@ -591,11 +654,13 @@ acpi_cpufreq_init (void)
/* initialize */ /* initialize */
for (i=0; i<NR_CPUS; i++) { for (i=0; i<NR_CPUS; i++) {
if (cpu_online(i) && performance[i].pr) if (cpu_online(i) && performance[i].pr)
result = acpi_processor_get_performance_info(performance[i].pr); result = acpi_processor_get_performance_info(&performance[i]);
} }
/* test it on one CPU */ /* test it on one CPU */
for (i=0; i<NR_CPUS; i++) { for (i=0; i<NR_CPUS; i++) {
if (cpu_online(i))
continue;
pr = performance[i].pr; pr = performance[i].pr;
if (pr && pr->flags.performance) if (pr && pr->flags.performance)
goto found_capable_cpu; goto found_capable_cpu;
...@@ -604,10 +669,11 @@ acpi_cpufreq_init (void) ...@@ -604,10 +669,11 @@ acpi_cpufreq_init (void)
goto err; goto err;
found_capable_cpu: found_capable_cpu:
current_state = pr->performance->state; perf = pr->performance;
current_state = perf->state;
if (current_state == pr->limit.state.px) { if (current_state == pr->limit.state.px) {
result = acpi_processor_set_performance(pr, (pr->performance->state_count - 1)); result = acpi_processor_set_performance(perf, (perf->state_count - 1));
if (result) { if (result) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Disabled P-States due to failure while switching.\n")); ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Disabled P-States due to failure while switching.\n"));
result = -ENODEV; result = -ENODEV;
...@@ -615,7 +681,7 @@ acpi_cpufreq_init (void) ...@@ -615,7 +681,7 @@ acpi_cpufreq_init (void)
} }
} }
result = acpi_processor_set_performance(pr, pr->limit.state.px); result = acpi_processor_set_performance(perf, pr->limit.state.px);
if (result) { if (result) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Disabled P-States due to failure while switching.\n")); ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Disabled P-States due to failure while switching.\n"));
result = -ENODEV; result = -ENODEV;
...@@ -623,7 +689,7 @@ acpi_cpufreq_init (void) ...@@ -623,7 +689,7 @@ acpi_cpufreq_init (void)
} }
if (current_state != 0) { if (current_state != 0) {
result = acpi_processor_set_performance(pr, current_state); result = acpi_processor_set_performance(perf, current_state);
if (result) { if (result) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Disabled P-States due to failure while switching.\n")); ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Disabled P-States due to failure while switching.\n"));
result = -ENODEV; result = -ENODEV;
...@@ -639,7 +705,7 @@ acpi_cpufreq_init (void) ...@@ -639,7 +705,7 @@ acpi_cpufreq_init (void)
/* error handling */ /* error handling */
err: err:
/* unregister struct acpi_performance performance */ /* unregister struct acpi_processor_performance performance */
for (i=0; i<NR_CPUS; i++) { for (i=0; i<NR_CPUS; i++) {
if (performance[i].pr) { if (performance[i].pr) {
performance[i].pr->flags.performance = 0; performance[i].pr->flags.performance = 0;
...@@ -647,9 +713,7 @@ acpi_cpufreq_init (void) ...@@ -647,9 +713,7 @@ acpi_cpufreq_init (void)
performance[i].pr = NULL; performance[i].pr = NULL;
} }
} }
kfree(performance); kfree(performance);
return_VALUE(result); return_VALUE(result);
} }
...@@ -668,7 +732,7 @@ acpi_cpufreq_exit (void) ...@@ -668,7 +732,7 @@ acpi_cpufreq_exit (void)
cpufreq_unregister_driver(&acpi_cpufreq_driver); cpufreq_unregister_driver(&acpi_cpufreq_driver);
/* unregister struct acpi_performance performance */ /* unregister struct acpi_processor_performance performance */
for (i=0; i<NR_CPUS; i++) { for (i=0; i<NR_CPUS; i++) {
if (performance[i].pr) { if (performance[i].pr) {
performance[i].pr->flags.performance = 0; performance[i].pr->flags.performance = 0;
...@@ -682,15 +746,6 @@ acpi_cpufreq_exit (void) ...@@ -682,15 +746,6 @@ acpi_cpufreq_exit (void)
return_VOID; return_VOID;
} }
static struct cpufreq_driver acpi_cpufreq_driver = {
.verify = acpi_cpufreq_verify,
.setpolicy = acpi_cpufreq_setpolicy,
.init = acpi_cpufreq_cpu_init,
.exit = NULL,
.policy = NULL,
.name = "acpi-cpufreq",
};
late_initcall(acpi_cpufreq_init); late_initcall(acpi_cpufreq_init);
module_exit(acpi_cpufreq_exit); module_exit(acpi_cpufreq_exit);
/* /*
* $Id: longhaul.c,v 1.77 2002/10/31 21:17:40 db Exp $ * $Id: longhaul.c,v 1.86 2003/02/12 13:59:11 davej Exp $
* *
* (C) 2001 Dave Jones. <davej@suse.de> * (C) 2001 Dave Jones. <davej@suse.de>
* (C) 2002 Padraig Brady. <padraig@antefacto.com> * (C) 2002 Padraig Brady. <padraig@antefacto.com>
...@@ -48,6 +48,7 @@ static int vrmrev; ...@@ -48,6 +48,7 @@ static int vrmrev;
/* Module parameters */ /* Module parameters */
static int prefer_slow_fsb;
static int dont_scale_voltage; static int dont_scale_voltage;
static int dont_scale_fsb; static int dont_scale_fsb;
static int current_fsb; static int current_fsb;
...@@ -237,7 +238,6 @@ static unsigned int power_fsb_table[] = { 66, 100, 133, -1 }; ...@@ -237,7 +238,6 @@ static unsigned int power_fsb_table[] = { 66, 100, 133, -1 };
/* fsb values to favour high fsb speed (for e.g. if lowering CPU /* fsb values to favour high fsb speed (for e.g. if lowering CPU
freq because of heat, but want to maintain highest performance possible) */ freq because of heat, but want to maintain highest performance possible) */
static unsigned int perf_fsb_table[] = { 133, 100, 66, -1 }; static unsigned int perf_fsb_table[] = { 133, 100, 66, -1 };
static unsigned int *fsb_search_table;
/* Voltage scales. Div by 1000 to get actual voltage. */ /* Voltage scales. Div by 1000 to get actual voltage. */
static int __initdata vrm85scales[32] = { static int __initdata vrm85scales[32] = {
...@@ -260,7 +260,7 @@ static int eblcr_table[32]; ...@@ -260,7 +260,7 @@ static int eblcr_table[32];
static int voltage_table[32]; static int voltage_table[32];
static int highest_speed, lowest_speed; /* kHz */ static int highest_speed, lowest_speed; /* kHz */
static int longhaul; /* version. */ static int longhaul; /* version. */
static struct cpufreq_driver *longhaul_driver; static struct cpufreq_frequency_table *longhaul_table;
static int longhaul_get_cpu_fsb (void) static int longhaul_get_cpu_fsb (void)
...@@ -428,7 +428,7 @@ static void longhaul_setstate (unsigned int clock_ratio_index, unsigned int newf ...@@ -428,7 +428,7 @@ static void longhaul_setstate (unsigned int clock_ratio_index, unsigned int newf
} }
static void __init longhaul_get_ranges (void) static int __init longhaul_get_ranges (void)
{ {
unsigned long lo, hi, invalue; unsigned long lo, hi, invalue;
unsigned int minmult=0, maxmult=0, minfsb=0, maxfsb=0; unsigned int minmult=0, maxmult=0, minfsb=0, maxfsb=0;
...@@ -436,6 +436,9 @@ static void __init longhaul_get_ranges (void) ...@@ -436,6 +436,9 @@ static void __init longhaul_get_ranges (void)
50,30,40,100,55,35,45,95,90,70,80,60,120,75,85,65, 50,30,40,100,55,35,45,95,90,70,80,60,120,75,85,65,
-1,110,120,-1,135,115,125,105,130,150,160,140,-1,155,-1,145 }; -1,110,120,-1,135,115,125,105,130,150,160,140,-1,155,-1,145 };
unsigned int fsb_table[4] = { 133, 100, -1, 66 }; unsigned int fsb_table[4] = { 133, 100, -1, 66 };
unsigned int fsbcount = 1;
unsigned int i, j, k = 0;
static unsigned int *fsb_search_table;
switch (longhaul) { switch (longhaul) {
case 1: case 1:
...@@ -472,6 +475,11 @@ static void __init longhaul_get_ranges (void) ...@@ -472,6 +475,11 @@ static void __init longhaul_get_ranges (void)
dprintk (KERN_INFO "longhaul: Min FSB=%d Max FSB=%d\n", dprintk (KERN_INFO "longhaul: Min FSB=%d Max FSB=%d\n",
minfsb, maxfsb); minfsb, maxfsb);
fsbcount = 0;
for (i=0;i<4;i++) {
if((fsb_table[i] >= minfsb) && (fsb_table[i] <= maxfsb))
fsbcount++;
}
} else { } else {
minfsb = maxfsb = current_fsb; minfsb = maxfsb = current_fsb;
} }
...@@ -480,11 +488,37 @@ static void __init longhaul_get_ranges (void) ...@@ -480,11 +488,37 @@ static void __init longhaul_get_ranges (void)
highest_speed = maxmult * maxfsb * 100; highest_speed = maxmult * maxfsb * 100;
lowest_speed = minmult * minfsb * 100; lowest_speed = minmult * minfsb * 100;
dprintk (KERN_INFO "longhaul: MinMult(x10)=%d MaxMult(x10)=%d\n", dprintk (KERN_INFO "longhaul: MinMult(x10)=%d MaxMult(x10)=%d\n",
minmult, maxmult); minmult, maxmult);
dprintk (KERN_INFO "longhaul: Lowestspeed=%d Highestspeed=%d\n", dprintk (KERN_INFO "longhaul: Lowestspeed=%d Highestspeed=%d\n",
lowest_speed, highest_speed); lowest_speed, highest_speed);
longhaul_table = kmalloc((numscales * fsbcount + 1) * sizeof(struct cpufreq_frequency_table), GFP_KERNEL);
if(!longhaul_table)
return -ENOMEM;
if (prefer_slow_fsb)
fsb_search_table = perf_fsb_table; // yep, this is right: the last entry is preferred by cpufreq_frequency_table_* ...
else
fsb_search_table = power_fsb_table;
for (i=0; (i<4); i++) {
if ((fsb_search_table[i] > maxfsb) || (fsb_search_table[i] < minfsb) || (fsb_search_table[i] == -1))
continue;
for (j=0; (j<numscales); j++) {
if ((clock_ratio[j] > maxmult) || (clock_ratio[j] < minmult) || (clock_ratio[j] == -1))
continue;
longhaul_table[k].frequency= clock_ratio[j] * fsb_search_table[i] * 100;
longhaul_table[k].index = (j << 8) | (i);
k++;
}
}
longhaul_table[k].frequency = CPUFREQ_TABLE_END;
if (!k)
return -EINVAL;
return 0;
} }
...@@ -523,182 +557,43 @@ static void __init longhaul_setup_voltagescaling (unsigned long lo, unsigned lon ...@@ -523,182 +557,43 @@ static void __init longhaul_setup_voltagescaling (unsigned long lo, unsigned lon
} }
static inline unsigned int longhaul_statecount_fsb(struct cpufreq_policy *policy, unsigned int fsb) {
unsigned int i, count = 0;
for(i=0; i<numscales; i++) {
if ((clock_ratio[i] != -1) &&
((clock_ratio[i] * fsb * 100) <= policy->max) &&
((clock_ratio[i] * fsb * 100) >= policy->min))
count++;
}
return count;
}
static int longhaul_verify(struct cpufreq_policy *policy) static int longhaul_verify(struct cpufreq_policy *policy)
{ {
unsigned int number_states = 0; return cpufreq_frequency_table_verify(policy, longhaul_table);
unsigned int i;
unsigned int fsb_index = 0;
unsigned int tmpfreq = 0;
unsigned int newmax = -1;
if (!policy || !longhaul_driver)
return -EINVAL;
policy->cpu = 0;
cpufreq_verify_within_limits(policy, lowest_speed, highest_speed);
if (can_scale_fsb==1) {
for (fsb_index=0; fsb_search_table[fsb_index]!=-1; fsb_index++)
number_states += longhaul_statecount_fsb(policy, fsb_search_table[fsb_index]);
} else
number_states = longhaul_statecount_fsb(policy, current_fsb);
if (number_states)
return 0;
/* get frequency closest above current policy->max */
if (can_scale_fsb==1) {
for (fsb_index=0; fsb_search_table[fsb_index] != -1; fsb_index++)
for(i=0; i<numscales; i++) {
if (clock_ratio[i] == -1)
continue;
tmpfreq = clock_ratio[i] * fsb_search_table[fsb_index];
if ((tmpfreq > policy->max) &&
(tmpfreq < newmax))
newmax = tmpfreq;
}
} else {
for(i=0; i<numscales; i++) {
if (clock_ratio[i] == -1)
continue;
tmpfreq = clock_ratio[i] * current_fsb;
if ((tmpfreq > policy->max) &&
(tmpfreq < newmax))
newmax = tmpfreq;
}
}
policy->max = newmax;
cpufreq_verify_within_limits(policy, lowest_speed, highest_speed);
return 0;
}
static int longhaul_get_best_freq_for_fsb(struct cpufreq_policy *policy,
unsigned int min_mult,
unsigned int max_mult,
unsigned int fsb,
unsigned int *new_mult)
{
unsigned int optimal = 0;
unsigned int found_optimal = 0;
unsigned int i;
switch(policy->policy) {
case CPUFREQ_POLICY_POWERSAVE:
optimal = max_mult;
break;
case CPUFREQ_POLICY_PERFORMANCE:
optimal = min_mult;
}
for(i=0; i<numscales; i++) {
unsigned int freq = fsb * clock_ratio[i] * 100;
if ((freq > policy->max) ||
(freq < policy->min))
continue;
switch(policy->policy) {
case CPUFREQ_POLICY_POWERSAVE:
if (clock_ratio[i] < clock_ratio[optimal]) {
found_optimal = 1;
optimal = i;
}
break;
case CPUFREQ_POLICY_PERFORMANCE:
if (clock_ratio[i] > clock_ratio[optimal]) {
found_optimal = 1;
optimal = i;
}
break;
}
}
if (found_optimal) {
*new_mult = optimal;
return 1;
}
return 0;
} }
static int longhaul_setpolicy (struct cpufreq_policy *policy) static int longhaul_target (struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{ {
unsigned int i; unsigned int table_index = 0;
unsigned int fsb_index = 0; unsigned int new_fsb = 0;
unsigned int new_fsb = 0; unsigned int new_clock_ratio = 0;
unsigned int new_clock_ratio = 0;
unsigned int min_mult = 0;
unsigned int max_mult = 0;
if (cpufreq_frequency_table_target(policy, longhaul_table, target_freq, relation, &table_index))
if (!longhaul_driver)
return -EINVAL; return -EINVAL;
if (policy->policy==CPUFREQ_POLICY_PERFORMANCE) new_clock_ratio = longhaul_table[table_index].index & 0xFF;
fsb_search_table = perf_fsb_table; new_fsb = power_fsb_table[(longhaul_table[table_index].index & 0xFF00) >> 8];
else
fsb_search_table = power_fsb_table;
for(i=0;i<numscales;i++) {
if (clock_ratio[max_mult] < clock_ratio[i])
max_mult = i;
else if (clock_ratio[min_mult] > clock_ratio[i])
min_mult = i;
}
if (can_scale_fsb==1) {
unsigned int found = 0;
for (fsb_index=0; fsb_search_table[fsb_index]!=-1; fsb_index++)
{
if (longhaul_get_best_freq_for_fsb(policy,
min_mult, max_mult,
fsb_search_table[fsb_index],
&new_clock_ratio)) {
new_fsb = fsb_search_table[fsb_index];
break;
}
}
if (!found)
return -EINVAL;
} else {
new_fsb = current_fsb;
if (!longhaul_get_best_freq_for_fsb(policy, min_mult,
max_mult, new_fsb, &new_clock_ratio))
return -EINVAL;
}
longhaul_setstate(new_clock_ratio, new_fsb); longhaul_setstate(new_clock_ratio, new_fsb);
return 0; return 0;
} }
static int longhaul_cpu_init (struct cpufreq_policy *policy);
static int __init longhaul_init (void) static struct cpufreq_driver longhaul_driver = {
.verify = longhaul_verify,
.target = longhaul_target,
.init = longhaul_cpu_init,
.name = "longhaul",
};
static int longhaul_cpu_init (struct cpufreq_policy *policy)
{ {
struct cpuinfo_x86 *c = cpu_data; struct cpuinfo_x86 *c = cpu_data;
unsigned int currentspeed;
static int currentmult;
unsigned long lo, hi;
int ret;
struct cpufreq_driver *driver;
if ((c->x86_vendor != X86_VENDOR_CENTAUR) || (c->x86 !=6) ) if ((c->x86_vendor != X86_VENDOR_CENTAUR) || (c->x86 !=6) )
return -ENODEV; return -ENODEV;
...@@ -733,21 +628,12 @@ static int __init longhaul_init (void) ...@@ -733,21 +628,12 @@ static int __init longhaul_init (void)
memcpy (eblcr_table, c5m_eblcr, sizeof(c5m_eblcr)); memcpy (eblcr_table, c5m_eblcr, sizeof(c5m_eblcr));
break; break;
default:
printk (KERN_INFO "longhaul: Unknown VIA CPU. Contact davej@suse.de\n");
return -ENODEV;
} }
printk (KERN_INFO "longhaul: VIA CPU detected. Longhaul version %d supported\n", longhaul); printk (KERN_INFO "longhaul: VIA CPU detected. Longhaul version %d supported\n", longhaul);
current_fsb = longhaul_get_cpu_fsb();
currentmult = longhaul_get_cpu_mult();
currentspeed = currentmult * current_fsb * 100;
dprintk (KERN_INFO "longhaul: CPU currently at %dMHz (%d x %d.%d)\n",
(currentspeed/1000), current_fsb, currentmult/10, currentmult%10);
if (longhaul==2 || longhaul==3) { if (longhaul==2 || longhaul==3) {
unsigned long lo, hi;
rdmsr (MSR_VIA_LONGHAUL, lo, hi); rdmsr (MSR_VIA_LONGHAUL, lo, hi);
if ((lo & (1<<0)) && (dont_scale_voltage==0)) if ((lo & (1<<0)) && (dont_scale_voltage==0))
longhaul_setup_voltagescaling (lo, hi); longhaul_setup_voltagescaling (lo, hi);
...@@ -756,57 +642,48 @@ static int __init longhaul_init (void) ...@@ -756,57 +642,48 @@ static int __init longhaul_init (void)
can_scale_fsb = 1; can_scale_fsb = 1;
} }
longhaul_get_ranges(); if (longhaul_get_ranges())
driver = kmalloc(sizeof(struct cpufreq_driver) +
NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL);
if (!driver)
return -ENOMEM; return -ENOMEM;
memset(driver, 0, sizeof(struct cpufreq_driver) +
NR_CPUS * sizeof(struct cpufreq_policy));
driver->policy = (struct cpufreq_policy *) (driver + 1); policy->policy = CPUFREQ_POLICY_PERFORMANCE;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
#ifdef CONFIG_CPU_FREQ_24_API #ifdef CONFIG_CPU_FREQ_24_API
driver->cpu_cur_freq[0] = currentspeed; longhaul_driver.cpu_cur_freq[0] = (unsigned int) (longhaul_get_cpu_fsb() * longhaul_get_cpu_mult() * 100);
#endif #endif
driver->verify = &longhaul_verify; return cpufreq_frequency_table_cpuinfo(policy, longhaul_table);
driver->setpolicy = &longhaul_setpolicy; }
strncpy(driver->name, "longhaul", CPUFREQ_NAME_LEN);
driver->policy[0].cpu = 0; static int __init longhaul_init (void)
driver->policy[0].min = (unsigned int) lowest_speed; {
driver->policy[0].max = (unsigned int) highest_speed; struct cpuinfo_x86 *c = cpu_data;
driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE;
driver->policy[0].cpuinfo.min_freq = (unsigned int) lowest_speed;
driver->policy[0].cpuinfo.max_freq = (unsigned int) highest_speed;
driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL;
longhaul_driver = driver; if ((c->x86_vendor != X86_VENDOR_CENTAUR) || (c->x86 !=6) )
return -ENODEV;
ret = cpufreq_register(driver); switch (c->x86_model) {
if (ret) { case 6 ... 7:
longhaul_driver = NULL; return cpufreq_register_driver(&longhaul_driver);
kfree(driver); case 8:
return -ENODEV;
default:
printk (KERN_INFO "longhaul: Unknown VIA CPU. Contact davej@suse.de\n");
} }
return ret; return -ENODEV;
} }
static void __exit longhaul_exit (void) static void __exit longhaul_exit (void)
{ {
if (longhaul_driver) { cpufreq_unregister_driver(&longhaul_driver);
cpufreq_unregister(); kfree(longhaul_table);
kfree(longhaul_driver);
}
} }
MODULE_PARM (dont_scale_fsb, "i"); MODULE_PARM (dont_scale_fsb, "i");
MODULE_PARM (dont_scale_voltage, "i"); MODULE_PARM (dont_scale_voltage, "i");
MODULE_PARM (current_fsb, "i"); MODULE_PARM (current_fsb, "i");
MODULE_PARM (prefer_slow_fsb, "i");
MODULE_AUTHOR ("Dave Jones <davej@suse.de>"); MODULE_AUTHOR ("Dave Jones <davej@suse.de>");
MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors."); MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors.");
......
...@@ -350,6 +350,13 @@ static int cpufreq_add_dev (struct device * dev) ...@@ -350,6 +350,13 @@ static int cpufreq_add_dev (struct device * dev)
&cpufreq_driver->policy[cpu], &cpufreq_driver->policy[cpu],
sizeof(struct cpufreq_policy)); sizeof(struct cpufreq_policy));
/* 2.4-API init for this CPU */
#ifdef CONFIG_CPU_FREQ_24_API
cpu_min_freq[cpu] = cpufreq_driver->policy[cpu].cpuinfo.min_freq;
cpu_max_freq[cpu] = cpufreq_driver->policy[cpu].cpuinfo.max_freq;
cpu_cur_freq[cpu] = cpufreq_driver->cpu_cur_freq[cpu];
#endif
if (cpufreq_driver->target) if (cpufreq_driver->target)
cpufreq_governor(cpu, CPUFREQ_GOV_START); cpufreq_governor(cpu, CPUFREQ_GOV_START);
...@@ -359,13 +366,6 @@ static int cpufreq_add_dev (struct device * dev) ...@@ -359,13 +366,6 @@ static int cpufreq_add_dev (struct device * dev)
return -EINVAL; return -EINVAL;
down(&cpufreq_driver_sem); down(&cpufreq_driver_sem);
/* 2.4-API init for this CPU */
#ifdef CONFIG_CPU_FREQ_24_API
cpu_min_freq[cpu] = cpufreq_driver->policy[cpu].cpuinfo.min_freq;
cpu_max_freq[cpu] = cpufreq_driver->policy[cpu].cpuinfo.max_freq;
cpu_cur_freq[cpu] = cpufreq_driver->cpu_cur_freq[cpu];
#endif
/* prepare interface data */ /* prepare interface data */
cpufreq_driver->policy[cpu].intf.dev = dev; cpufreq_driver->policy[cpu].intf.dev = dev;
cpufreq_driver->policy[cpu].intf.intf = &cpufreq_interface; cpufreq_driver->policy[cpu].intf.intf = &cpufreq_interface;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment