summaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/acpi-cpufreq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cpufreq/acpi-cpufreq.c')
-rw-r--r--drivers/cpufreq/acpi-cpufreq.c52
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
426static int acpi_cpufreq_target(struct cpufreq_policy *policy, 426static 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
519static 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
528static unsigned long 500static unsigned long
529acpi_cpufreq_guess_freq(struct acpi_cpufreq_data *data, unsigned int cpu) 501acpi_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
931static struct cpufreq_driver acpi_cpufreq_driver = { 905static 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,