diff options
Diffstat (limited to 'drivers/cpufreq/acpi-cpufreq.c')
-rw-r--r-- | drivers/cpufreq/acpi-cpufreq.c | 52 |
1 files changed, 13 insertions, 39 deletions
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 506fd23c7550..caf41ebea184 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c | |||
@@ -424,34 +424,21 @@ static unsigned int check_freqs(const struct cpumask *mask, unsigned int freq, | |||
424 | } | 424 | } |
425 | 425 | ||
426 | static int acpi_cpufreq_target(struct cpufreq_policy *policy, | 426 | static int acpi_cpufreq_target(struct cpufreq_policy *policy, |
427 | unsigned int target_freq, unsigned int relation) | 427 | unsigned int index) |
428 | { | 428 | { |
429 | struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu); | 429 | struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu); |
430 | struct acpi_processor_performance *perf; | 430 | struct acpi_processor_performance *perf; |
431 | struct cpufreq_freqs freqs; | ||
432 | struct drv_cmd cmd; | 431 | struct drv_cmd cmd; |
433 | unsigned int next_state = 0; /* Index into freq_table */ | ||
434 | unsigned int next_perf_state = 0; /* Index into perf table */ | 432 | unsigned int next_perf_state = 0; /* Index into perf table */ |
435 | int result = 0; | 433 | int result = 0; |
436 | 434 | ||
437 | pr_debug("acpi_cpufreq_target %d (%d)\n", target_freq, policy->cpu); | ||
438 | |||
439 | if (unlikely(data == NULL || | 435 | if (unlikely(data == NULL || |
440 | data->acpi_data == NULL || data->freq_table == NULL)) { | 436 | data->acpi_data == NULL || data->freq_table == NULL)) { |
441 | return -ENODEV; | 437 | return -ENODEV; |
442 | } | 438 | } |
443 | 439 | ||
444 | perf = data->acpi_data; | 440 | perf = data->acpi_data; |
445 | result = cpufreq_frequency_table_target(policy, | 441 | next_perf_state = data->freq_table[index].driver_data; |
446 | data->freq_table, | ||
447 | target_freq, | ||
448 | relation, &next_state); | ||
449 | if (unlikely(result)) { | ||
450 | result = -ENODEV; | ||
451 | goto out; | ||
452 | } | ||
453 | |||
454 | next_perf_state = data->freq_table[next_state].driver_data; | ||
455 | if (perf->state == next_perf_state) { | 442 | if (perf->state == next_perf_state) { |
456 | if (unlikely(data->resume)) { | 443 | if (unlikely(data->resume)) { |
457 | pr_debug("Called after resume, resetting to P%d\n", | 444 | pr_debug("Called after resume, resetting to P%d\n", |
@@ -492,23 +479,17 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, | |||
492 | else | 479 | else |
493 | cmd.mask = cpumask_of(policy->cpu); | 480 | cmd.mask = cpumask_of(policy->cpu); |
494 | 481 | ||
495 | freqs.old = perf->states[perf->state].core_frequency * 1000; | ||
496 | freqs.new = data->freq_table[next_state].frequency; | ||
497 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
498 | |||
499 | drv_write(&cmd); | 482 | drv_write(&cmd); |
500 | 483 | ||
501 | if (acpi_pstate_strict) { | 484 | if (acpi_pstate_strict) { |
502 | if (!check_freqs(cmd.mask, freqs.new, data)) { | 485 | if (!check_freqs(cmd.mask, data->freq_table[index].frequency, |
486 | data)) { | ||
503 | pr_debug("acpi_cpufreq_target failed (%d)\n", | 487 | pr_debug("acpi_cpufreq_target failed (%d)\n", |
504 | policy->cpu); | 488 | policy->cpu); |
505 | result = -EAGAIN; | 489 | result = -EAGAIN; |
506 | freqs.new = freqs.old; | ||
507 | } | 490 | } |
508 | } | 491 | } |
509 | 492 | ||
510 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
511 | |||
512 | if (!result) | 493 | if (!result) |
513 | perf->state = next_perf_state; | 494 | perf->state = next_perf_state; |
514 | 495 | ||
@@ -516,15 +497,6 @@ out: | |||
516 | return result; | 497 | return result; |
517 | } | 498 | } |
518 | 499 | ||
519 | static int acpi_cpufreq_verify(struct cpufreq_policy *policy) | ||
520 | { | ||
521 | struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu); | ||
522 | |||
523 | pr_debug("acpi_cpufreq_verify\n"); | ||
524 | |||
525 | return cpufreq_frequency_table_verify(policy, data->freq_table); | ||
526 | } | ||
527 | |||
528 | static unsigned long | 500 | static unsigned long |
529 | acpi_cpufreq_guess_freq(struct acpi_cpufreq_data *data, unsigned int cpu) | 501 | acpi_cpufreq_guess_freq(struct acpi_cpufreq_data *data, unsigned int cpu) |
530 | { | 502 | { |
@@ -837,7 +809,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
837 | data->freq_table[valid_states].frequency = CPUFREQ_TABLE_END; | 809 | data->freq_table[valid_states].frequency = CPUFREQ_TABLE_END; |
838 | perf->state = 0; | 810 | perf->state = 0; |
839 | 811 | ||
840 | result = cpufreq_frequency_table_cpuinfo(policy, data->freq_table); | 812 | result = cpufreq_table_validate_and_show(policy, data->freq_table); |
841 | if (result) | 813 | if (result) |
842 | goto err_freqfree; | 814 | goto err_freqfree; |
843 | 815 | ||
@@ -846,12 +818,16 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
846 | 818 | ||
847 | switch (perf->control_register.space_id) { | 819 | switch (perf->control_register.space_id) { |
848 | case ACPI_ADR_SPACE_SYSTEM_IO: | 820 | case ACPI_ADR_SPACE_SYSTEM_IO: |
849 | /* Current speed is unknown and not detectable by IO port */ | 821 | /* |
822 | * The core will not set policy->cur, because | ||
823 | * cpufreq_driver->get is NULL, so we need to set it here. | ||
824 | * However, we have to guess it, because the current speed is | ||
825 | * unknown and not detectable via IO ports. | ||
826 | */ | ||
850 | policy->cur = acpi_cpufreq_guess_freq(data, policy->cpu); | 827 | policy->cur = acpi_cpufreq_guess_freq(data, policy->cpu); |
851 | break; | 828 | break; |
852 | case ACPI_ADR_SPACE_FIXED_HARDWARE: | 829 | case ACPI_ADR_SPACE_FIXED_HARDWARE: |
853 | acpi_cpufreq_driver.get = get_cur_freq_on_cpu; | 830 | acpi_cpufreq_driver.get = get_cur_freq_on_cpu; |
854 | policy->cur = get_cur_freq_on_cpu(cpu); | ||
855 | break; | 831 | break; |
856 | default: | 832 | default: |
857 | break; | 833 | break; |
@@ -868,8 +844,6 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
868 | (u32) perf->states[i].power, | 844 | (u32) perf->states[i].power, |
869 | (u32) perf->states[i].transition_latency); | 845 | (u32) perf->states[i].transition_latency); |
870 | 846 | ||
871 | cpufreq_frequency_table_get_attr(data->freq_table, policy->cpu); | ||
872 | |||
873 | /* | 847 | /* |
874 | * the first call to ->target() should result in us actually | 848 | * the first call to ->target() should result in us actually |
875 | * writing something to the appropriate registers. | 849 | * writing something to the appropriate registers. |
@@ -929,8 +903,8 @@ static struct freq_attr *acpi_cpufreq_attr[] = { | |||
929 | }; | 903 | }; |
930 | 904 | ||
931 | static struct cpufreq_driver acpi_cpufreq_driver = { | 905 | static struct cpufreq_driver acpi_cpufreq_driver = { |
932 | .verify = acpi_cpufreq_verify, | 906 | .verify = cpufreq_generic_frequency_table_verify, |
933 | .target = acpi_cpufreq_target, | 907 | .target_index = acpi_cpufreq_target, |
934 | .bios_limit = acpi_processor_get_bios_limit, | 908 | .bios_limit = acpi_processor_get_bios_limit, |
935 | .init = acpi_cpufreq_cpu_init, | 909 | .init = acpi_cpufreq_cpu_init, |
936 | .exit = acpi_cpufreq_cpu_exit, | 910 | .exit = acpi_cpufreq_cpu_exit, |