diff options
| -rw-r--r-- | arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c | 41 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/cpufreq/powernow-k8.c | 11 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq.c | 12 |
3 files changed, 27 insertions, 37 deletions
diff --git a/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c index ce7cde713e71..a36de5bbb622 100644 --- a/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c | |||
| @@ -368,22 +368,16 @@ static int __init pcc_cpufreq_do_osc(acpi_handle *handle) | |||
| 368 | return -ENODEV; | 368 | return -ENODEV; |
| 369 | 369 | ||
| 370 | out_obj = output.pointer; | 370 | out_obj = output.pointer; |
| 371 | if (out_obj->type != ACPI_TYPE_BUFFER) { | 371 | if (out_obj->type != ACPI_TYPE_BUFFER) |
| 372 | ret = -ENODEV; | 372 | return -ENODEV; |
| 373 | goto out_free; | ||
| 374 | } | ||
| 375 | 373 | ||
| 376 | errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0); | 374 | errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0); |
| 377 | if (errors) { | 375 | if (errors) |
| 378 | ret = -ENODEV; | 376 | return -ENODEV; |
| 379 | goto out_free; | ||
| 380 | } | ||
| 381 | 377 | ||
| 382 | supported = *((u32 *)(out_obj->buffer.pointer + 4)); | 378 | supported = *((u32 *)(out_obj->buffer.pointer + 4)); |
| 383 | if (!(supported & 0x1)) { | 379 | if (!(supported & 0x1)) |
| 384 | ret = -ENODEV; | 380 | return -ENODEV; |
| 385 | goto out_free; | ||
| 386 | } | ||
| 387 | 381 | ||
| 388 | out_free: | 382 | out_free: |
| 389 | kfree(output.pointer); | 383 | kfree(output.pointer); |
| @@ -397,13 +391,17 @@ static int __init pcc_cpufreq_probe(void) | |||
| 397 | struct pcc_memory_resource *mem_resource; | 391 | struct pcc_memory_resource *mem_resource; |
| 398 | struct pcc_register_resource *reg_resource; | 392 | struct pcc_register_resource *reg_resource; |
| 399 | union acpi_object *out_obj, *member; | 393 | union acpi_object *out_obj, *member; |
| 400 | acpi_handle handle, osc_handle; | 394 | acpi_handle handle, osc_handle, pcch_handle; |
| 401 | int ret = 0; | 395 | int ret = 0; |
| 402 | 396 | ||
| 403 | status = acpi_get_handle(NULL, "\\_SB", &handle); | 397 | status = acpi_get_handle(NULL, "\\_SB", &handle); |
| 404 | if (ACPI_FAILURE(status)) | 398 | if (ACPI_FAILURE(status)) |
| 405 | return -ENODEV; | 399 | return -ENODEV; |
| 406 | 400 | ||
| 401 | status = acpi_get_handle(handle, "PCCH", &pcch_handle); | ||
| 402 | if (ACPI_FAILURE(status)) | ||
| 403 | return -ENODEV; | ||
| 404 | |||
| 407 | status = acpi_get_handle(handle, "_OSC", &osc_handle); | 405 | status = acpi_get_handle(handle, "_OSC", &osc_handle); |
| 408 | if (ACPI_SUCCESS(status)) { | 406 | if (ACPI_SUCCESS(status)) { |
| 409 | ret = pcc_cpufreq_do_osc(&osc_handle); | 407 | ret = pcc_cpufreq_do_osc(&osc_handle); |
| @@ -543,13 +541,13 @@ static int pcc_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
| 543 | 541 | ||
| 544 | if (!pcch_virt_addr) { | 542 | if (!pcch_virt_addr) { |
| 545 | result = -1; | 543 | result = -1; |
| 546 | goto pcch_null; | 544 | goto out; |
| 547 | } | 545 | } |
| 548 | 546 | ||
| 549 | result = pcc_get_offset(cpu); | 547 | result = pcc_get_offset(cpu); |
| 550 | if (result) { | 548 | if (result) { |
| 551 | dprintk("init: PCCP evaluation failed\n"); | 549 | dprintk("init: PCCP evaluation failed\n"); |
| 552 | goto free; | 550 | goto out; |
| 553 | } | 551 | } |
| 554 | 552 | ||
| 555 | policy->max = policy->cpuinfo.max_freq = | 553 | policy->max = policy->cpuinfo.max_freq = |
| @@ -558,14 +556,15 @@ static int pcc_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
| 558 | ioread32(&pcch_hdr->minimum_frequency) * 1000; | 556 | ioread32(&pcch_hdr->minimum_frequency) * 1000; |
| 559 | policy->cur = pcc_get_freq(cpu); | 557 | policy->cur = pcc_get_freq(cpu); |
| 560 | 558 | ||
| 559 | if (!policy->cur) { | ||
| 560 | dprintk("init: Unable to get current CPU frequency\n"); | ||
| 561 | result = -EINVAL; | ||
| 562 | goto out; | ||
| 563 | } | ||
| 564 | |||
| 561 | dprintk("init: policy->max is %d, policy->min is %d\n", | 565 | dprintk("init: policy->max is %d, policy->min is %d\n", |
| 562 | policy->max, policy->min); | 566 | policy->max, policy->min); |
| 563 | 567 | out: | |
| 564 | return 0; | ||
| 565 | free: | ||
| 566 | pcc_clear_mapping(); | ||
| 567 | free_percpu(pcc_cpu_info); | ||
| 568 | pcch_null: | ||
| 569 | return result; | 568 | return result; |
| 570 | } | 569 | } |
| 571 | 570 | ||
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index 7ec2123838e6..3e90cce3dc8b 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c | |||
| @@ -1023,13 +1023,12 @@ static int get_transition_latency(struct powernow_k8_data *data) | |||
| 1023 | } | 1023 | } |
| 1024 | if (max_latency == 0) { | 1024 | if (max_latency == 0) { |
| 1025 | /* | 1025 | /* |
| 1026 | * Fam 11h always returns 0 as transition latency. | 1026 | * Fam 11h and later may return 0 as transition latency. This |
| 1027 | * This is intended and means "very fast". While cpufreq core | 1027 | * is intended and means "very fast". While cpufreq core and |
| 1028 | * and governors currently can handle that gracefully, better | 1028 | * governors currently can handle that gracefully, better set it |
| 1029 | * set it to 1 to avoid problems in the future. | 1029 | * to 1 to avoid problems in the future. |
| 1030 | * For all others it's a BIOS bug. | ||
| 1031 | */ | 1030 | */ |
| 1032 | if (boot_cpu_data.x86 != 0x11) | 1031 | if (boot_cpu_data.x86 < 0x11) |
| 1033 | printk(KERN_ERR FW_WARN PFX "Invalid zero transition " | 1032 | printk(KERN_ERR FW_WARN PFX "Invalid zero transition " |
| 1034 | "latency\n"); | 1033 | "latency\n"); |
| 1035 | max_latency = 1; | 1034 | max_latency = 1; |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 063b2184caf5..938b74ea9ffb 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
| @@ -1077,6 +1077,7 @@ err_out_unregister: | |||
| 1077 | 1077 | ||
| 1078 | err_unlock_policy: | 1078 | err_unlock_policy: |
| 1079 | unlock_policy_rwsem_write(cpu); | 1079 | unlock_policy_rwsem_write(cpu); |
| 1080 | free_cpumask_var(policy->related_cpus); | ||
| 1080 | err_free_cpumask: | 1081 | err_free_cpumask: |
| 1081 | free_cpumask_var(policy->cpus); | 1082 | free_cpumask_var(policy->cpus); |
| 1082 | err_free_policy: | 1083 | err_free_policy: |
| @@ -1762,17 +1763,8 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, | |||
| 1762 | dprintk("governor switch\n"); | 1763 | dprintk("governor switch\n"); |
| 1763 | 1764 | ||
| 1764 | /* end old governor */ | 1765 | /* end old governor */ |
| 1765 | if (data->governor) { | 1766 | if (data->governor) |
| 1766 | /* | ||
| 1767 | * Need to release the rwsem around governor | ||
| 1768 | * stop due to lock dependency between | ||
| 1769 | * cancel_delayed_work_sync and the read lock | ||
| 1770 | * taken in the delayed work handler. | ||
| 1771 | */ | ||
| 1772 | unlock_policy_rwsem_write(data->cpu); | ||
| 1773 | __cpufreq_governor(data, CPUFREQ_GOV_STOP); | 1767 | __cpufreq_governor(data, CPUFREQ_GOV_STOP); |
| 1774 | lock_policy_rwsem_write(data->cpu); | ||
| 1775 | } | ||
| 1776 | 1768 | ||
| 1777 | /* start new governor */ | 1769 | /* start new governor */ |
| 1778 | data->governor = policy->governor; | 1770 | data->governor = policy->governor; |
