diff options
| -rw-r--r-- | arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 23 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/cpufreq/longhaul.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/cpufreq/powernow-k8.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/cpufreq/speedstep-ich.c | 19 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq.c | 48 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq_conservative.c | 4 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq_ondemand.c | 4 |
7 files changed, 70 insertions, 32 deletions
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index 7d5c3b0ea8da..8b581d3905cb 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | |||
| @@ -526,15 +526,21 @@ static const struct dmi_system_id sw_any_bug_dmi_table[] = { | |||
| 526 | 526 | ||
| 527 | static int acpi_cpufreq_blacklist(struct cpuinfo_x86 *c) | 527 | static int acpi_cpufreq_blacklist(struct cpuinfo_x86 *c) |
| 528 | { | 528 | { |
| 529 | /* http://www.intel.com/Assets/PDF/specupdate/314554.pdf | 529 | /* Intel Xeon Processor 7100 Series Specification Update |
| 530 | * http://www.intel.com/Assets/PDF/specupdate/314554.pdf | ||
| 530 | * AL30: A Machine Check Exception (MCE) Occurring during an | 531 | * AL30: A Machine Check Exception (MCE) Occurring during an |
| 531 | * Enhanced Intel SpeedStep Technology Ratio Change May Cause | 532 | * Enhanced Intel SpeedStep Technology Ratio Change May Cause |
| 532 | * Both Processor Cores to Lock Up when HT is enabled*/ | 533 | * Both Processor Cores to Lock Up. */ |
| 533 | if (c->x86_vendor == X86_VENDOR_INTEL) { | 534 | if (c->x86_vendor == X86_VENDOR_INTEL) { |
| 534 | if ((c->x86 == 15) && | 535 | if ((c->x86 == 15) && |
| 535 | (c->x86_model == 6) && | 536 | (c->x86_model == 6) && |
| 536 | (c->x86_mask == 8) && smt_capable()) | 537 | (c->x86_mask == 8)) { |
| 538 | printk(KERN_INFO "acpi-cpufreq: Intel(R) " | ||
| 539 | "Xeon(R) 7100 Errata AL30, processors may " | ||
| 540 | "lock up on frequency changes: disabling " | ||
| 541 | "acpi-cpufreq.\n"); | ||
| 537 | return -ENODEV; | 542 | return -ENODEV; |
| 543 | } | ||
| 538 | } | 544 | } |
| 539 | return 0; | 545 | return 0; |
| 540 | } | 546 | } |
| @@ -549,13 +555,18 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
| 549 | unsigned int result = 0; | 555 | unsigned int result = 0; |
| 550 | struct cpuinfo_x86 *c = &cpu_data(policy->cpu); | 556 | struct cpuinfo_x86 *c = &cpu_data(policy->cpu); |
| 551 | struct acpi_processor_performance *perf; | 557 | struct acpi_processor_performance *perf; |
| 558 | #ifdef CONFIG_SMP | ||
| 559 | static int blacklisted; | ||
| 560 | #endif | ||
| 552 | 561 | ||
| 553 | dprintk("acpi_cpufreq_cpu_init\n"); | 562 | dprintk("acpi_cpufreq_cpu_init\n"); |
| 554 | 563 | ||
| 555 | #ifdef CONFIG_SMP | 564 | #ifdef CONFIG_SMP |
| 556 | result = acpi_cpufreq_blacklist(c); | 565 | if (blacklisted) |
| 557 | if (result) | 566 | return blacklisted; |
| 558 | return result; | 567 | blacklisted = acpi_cpufreq_blacklist(c); |
| 568 | if (blacklisted) | ||
| 569 | return blacklisted; | ||
| 559 | #endif | 570 | #endif |
| 560 | 571 | ||
| 561 | data = kzalloc(sizeof(struct acpi_cpufreq_data), GFP_KERNEL); | 572 | data = kzalloc(sizeof(struct acpi_cpufreq_data), GFP_KERNEL); |
diff --git a/arch/x86/kernel/cpu/cpufreq/longhaul.c b/arch/x86/kernel/cpu/cpufreq/longhaul.c index ce2ed3e4aad9..cabd2fa3fc93 100644 --- a/arch/x86/kernel/cpu/cpufreq/longhaul.c +++ b/arch/x86/kernel/cpu/cpufreq/longhaul.c | |||
| @@ -813,7 +813,7 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy) | |||
| 813 | memcpy(eblcr, samuel2_eblcr, sizeof(samuel2_eblcr)); | 813 | memcpy(eblcr, samuel2_eblcr, sizeof(samuel2_eblcr)); |
| 814 | break; | 814 | break; |
| 815 | case 1 ... 15: | 815 | case 1 ... 15: |
| 816 | longhaul_version = TYPE_LONGHAUL_V1; | 816 | longhaul_version = TYPE_LONGHAUL_V2; |
| 817 | if (c->x86_mask < 8) { | 817 | if (c->x86_mask < 8) { |
| 818 | cpu_model = CPU_SAMUEL2; | 818 | cpu_model = CPU_SAMUEL2; |
| 819 | cpuname = "C3 'Samuel 2' [C5B]"; | 819 | cpuname = "C3 'Samuel 2' [C5B]"; |
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index 6394aa5c7985..3f12dabeab52 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c | |||
| @@ -1022,7 +1022,7 @@ static int get_transition_latency(struct powernow_k8_data *data) | |||
| 1022 | * set it to 1 to avoid problems in the future. | 1022 | * set it to 1 to avoid problems in the future. |
| 1023 | * For all others it's a BIOS bug. | 1023 | * For all others it's a BIOS bug. |
| 1024 | */ | 1024 | */ |
| 1025 | if (!boot_cpu_data.x86 == 0x11) | 1025 | if (boot_cpu_data.x86 != 0x11) |
| 1026 | printk(KERN_ERR FW_WARN PFX "Invalid zero transition " | 1026 | printk(KERN_ERR FW_WARN PFX "Invalid zero transition " |
| 1027 | "latency\n"); | 1027 | "latency\n"); |
| 1028 | max_latency = 1; | 1028 | max_latency = 1; |
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c index 6911e91fb4f6..3ae5a7a3a500 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c | |||
| @@ -232,28 +232,23 @@ static unsigned int speedstep_detect_chipset(void) | |||
| 232 | return 0; | 232 | return 0; |
| 233 | } | 233 | } |
| 234 | 234 | ||
| 235 | struct get_freq_data { | 235 | static void get_freq_data(void *_speed) |
| 236 | unsigned int speed; | ||
| 237 | unsigned int processor; | ||
| 238 | }; | ||
| 239 | |||
| 240 | static void get_freq_data(void *_data) | ||
| 241 | { | 236 | { |
| 242 | struct get_freq_data *data = _data; | 237 | unsigned int *speed = _speed; |
| 243 | 238 | ||
| 244 | data->speed = speedstep_get_frequency(data->processor); | 239 | *speed = speedstep_get_frequency(speedstep_processor); |
| 245 | } | 240 | } |
| 246 | 241 | ||
| 247 | static unsigned int speedstep_get(unsigned int cpu) | 242 | static unsigned int speedstep_get(unsigned int cpu) |
| 248 | { | 243 | { |
| 249 | struct get_freq_data data = { .processor = cpu }; | 244 | unsigned int speed; |
| 250 | 245 | ||
| 251 | /* You're supposed to ensure CPU is online. */ | 246 | /* You're supposed to ensure CPU is online. */ |
| 252 | if (smp_call_function_single(cpu, get_freq_data, &data, 1) != 0) | 247 | if (smp_call_function_single(cpu, get_freq_data, &speed, 1) != 0) |
| 253 | BUG(); | 248 | BUG(); |
| 254 | 249 | ||
| 255 | dprintk("detected %u kHz as current frequency\n", data.speed); | 250 | dprintk("detected %u kHz as current frequency\n", speed); |
| 256 | return data.speed; | 251 | return speed; |
| 257 | } | 252 | } |
| 258 | 253 | ||
| 259 | /** | 254 | /** |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 3938c7817095..ff57c40e9b8b 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
| @@ -41,7 +41,7 @@ static struct cpufreq_driver *cpufreq_driver; | |||
| 41 | static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); | 41 | static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); |
| 42 | #ifdef CONFIG_HOTPLUG_CPU | 42 | #ifdef CONFIG_HOTPLUG_CPU |
| 43 | /* This one keeps track of the previously set governor of a removed CPU */ | 43 | /* This one keeps track of the previously set governor of a removed CPU */ |
| 44 | static DEFINE_PER_CPU(struct cpufreq_governor *, cpufreq_cpu_governor); | 44 | static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor); |
| 45 | #endif | 45 | #endif |
| 46 | static DEFINE_SPINLOCK(cpufreq_driver_lock); | 46 | static DEFINE_SPINLOCK(cpufreq_driver_lock); |
| 47 | 47 | ||
| @@ -774,10 +774,12 @@ int cpufreq_add_dev_policy(unsigned int cpu, struct cpufreq_policy *policy, | |||
| 774 | #ifdef CONFIG_SMP | 774 | #ifdef CONFIG_SMP |
| 775 | unsigned long flags; | 775 | unsigned long flags; |
| 776 | unsigned int j; | 776 | unsigned int j; |
| 777 | |||
| 778 | #ifdef CONFIG_HOTPLUG_CPU | 777 | #ifdef CONFIG_HOTPLUG_CPU |
| 779 | if (per_cpu(cpufreq_cpu_governor, cpu)) { | 778 | struct cpufreq_governor *gov; |
| 780 | policy->governor = per_cpu(cpufreq_cpu_governor, cpu); | 779 | |
| 780 | gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu)); | ||
| 781 | if (gov) { | ||
| 782 | policy->governor = gov; | ||
| 781 | dprintk("Restoring governor %s for cpu %d\n", | 783 | dprintk("Restoring governor %s for cpu %d\n", |
| 782 | policy->governor->name, cpu); | 784 | policy->governor->name, cpu); |
| 783 | } | 785 | } |
| @@ -949,10 +951,13 @@ err_out_kobj_put: | |||
| 949 | static int cpufreq_add_dev(struct sys_device *sys_dev) | 951 | static int cpufreq_add_dev(struct sys_device *sys_dev) |
| 950 | { | 952 | { |
| 951 | unsigned int cpu = sys_dev->id; | 953 | unsigned int cpu = sys_dev->id; |
| 952 | int ret = 0; | 954 | int ret = 0, found = 0; |
| 953 | struct cpufreq_policy *policy; | 955 | struct cpufreq_policy *policy; |
| 954 | unsigned long flags; | 956 | unsigned long flags; |
| 955 | unsigned int j; | 957 | unsigned int j; |
| 958 | #ifdef CONFIG_HOTPLUG_CPU | ||
| 959 | int sibling; | ||
| 960 | #endif | ||
| 956 | 961 | ||
| 957 | if (cpu_is_offline(cpu)) | 962 | if (cpu_is_offline(cpu)) |
| 958 | return 0; | 963 | return 0; |
| @@ -999,7 +1004,19 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) | |||
| 999 | INIT_WORK(&policy->update, handle_update); | 1004 | INIT_WORK(&policy->update, handle_update); |
| 1000 | 1005 | ||
| 1001 | /* Set governor before ->init, so that driver could check it */ | 1006 | /* Set governor before ->init, so that driver could check it */ |
| 1002 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; | 1007 | #ifdef CONFIG_HOTPLUG_CPU |
| 1008 | for_each_online_cpu(sibling) { | ||
| 1009 | struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling); | ||
| 1010 | if (cp && cp->governor && | ||
| 1011 | (cpumask_test_cpu(cpu, cp->related_cpus))) { | ||
| 1012 | policy->governor = cp->governor; | ||
| 1013 | found = 1; | ||
| 1014 | break; | ||
| 1015 | } | ||
| 1016 | } | ||
| 1017 | #endif | ||
| 1018 | if (!found) | ||
| 1019 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; | ||
| 1003 | /* call driver. From then on the cpufreq must be able | 1020 | /* call driver. From then on the cpufreq must be able |
| 1004 | * to accept all calls to ->verify and ->setpolicy for this CPU | 1021 | * to accept all calls to ->verify and ->setpolicy for this CPU |
| 1005 | */ | 1022 | */ |
| @@ -1111,7 +1128,8 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev) | |||
| 1111 | #ifdef CONFIG_SMP | 1128 | #ifdef CONFIG_SMP |
| 1112 | 1129 | ||
| 1113 | #ifdef CONFIG_HOTPLUG_CPU | 1130 | #ifdef CONFIG_HOTPLUG_CPU |
| 1114 | per_cpu(cpufreq_cpu_governor, cpu) = data->governor; | 1131 | strncpy(per_cpu(cpufreq_cpu_governor, cpu), data->governor->name, |
| 1132 | CPUFREQ_NAME_LEN); | ||
| 1115 | #endif | 1133 | #endif |
| 1116 | 1134 | ||
| 1117 | /* if we have other CPUs still registered, we need to unlink them, | 1135 | /* if we have other CPUs still registered, we need to unlink them, |
| @@ -1135,7 +1153,8 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev) | |||
| 1135 | continue; | 1153 | continue; |
| 1136 | dprintk("removing link for cpu %u\n", j); | 1154 | dprintk("removing link for cpu %u\n", j); |
| 1137 | #ifdef CONFIG_HOTPLUG_CPU | 1155 | #ifdef CONFIG_HOTPLUG_CPU |
| 1138 | per_cpu(cpufreq_cpu_governor, j) = data->governor; | 1156 | strncpy(per_cpu(cpufreq_cpu_governor, j), |
| 1157 | data->governor->name, CPUFREQ_NAME_LEN); | ||
| 1139 | #endif | 1158 | #endif |
| 1140 | cpu_sys_dev = get_cpu_sysdev(j); | 1159 | cpu_sys_dev = get_cpu_sysdev(j); |
| 1141 | sysfs_remove_link(&cpu_sys_dev->kobj, "cpufreq"); | 1160 | sysfs_remove_link(&cpu_sys_dev->kobj, "cpufreq"); |
| @@ -1606,9 +1625,22 @@ EXPORT_SYMBOL_GPL(cpufreq_register_governor); | |||
| 1606 | 1625 | ||
| 1607 | void cpufreq_unregister_governor(struct cpufreq_governor *governor) | 1626 | void cpufreq_unregister_governor(struct cpufreq_governor *governor) |
| 1608 | { | 1627 | { |
| 1628 | #ifdef CONFIG_HOTPLUG_CPU | ||
| 1629 | int cpu; | ||
| 1630 | #endif | ||
| 1631 | |||
| 1609 | if (!governor) | 1632 | if (!governor) |
| 1610 | return; | 1633 | return; |
| 1611 | 1634 | ||
| 1635 | #ifdef CONFIG_HOTPLUG_CPU | ||
| 1636 | for_each_present_cpu(cpu) { | ||
| 1637 | if (cpu_online(cpu)) | ||
| 1638 | continue; | ||
| 1639 | if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name)) | ||
| 1640 | strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0"); | ||
| 1641 | } | ||
| 1642 | #endif | ||
| 1643 | |||
| 1612 | mutex_lock(&cpufreq_governor_mutex); | 1644 | mutex_lock(&cpufreq_governor_mutex); |
| 1613 | list_del(&governor->governor_list); | 1645 | list_del(&governor->governor_list); |
| 1614 | mutex_unlock(&cpufreq_governor_mutex); | 1646 | mutex_unlock(&cpufreq_governor_mutex); |
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index bc33ddc9c97c..c7b081b839ff 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c | |||
| @@ -116,9 +116,9 @@ static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu, | |||
| 116 | 116 | ||
| 117 | idle_time = cputime64_sub(cur_wall_time, busy_time); | 117 | idle_time = cputime64_sub(cur_wall_time, busy_time); |
| 118 | if (wall) | 118 | if (wall) |
| 119 | *wall = cur_wall_time; | 119 | *wall = (cputime64_t)jiffies_to_usecs(cur_wall_time); |
| 120 | 120 | ||
| 121 | return idle_time; | 121 | return (cputime64_t)jiffies_to_usecs(idle_time);; |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall) | 124 | static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall) |
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 071699de50ee..4b34ade2332b 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c | |||
| @@ -133,9 +133,9 @@ static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu, | |||
| 133 | 133 | ||
| 134 | idle_time = cputime64_sub(cur_wall_time, busy_time); | 134 | idle_time = cputime64_sub(cur_wall_time, busy_time); |
| 135 | if (wall) | 135 | if (wall) |
| 136 | *wall = cur_wall_time; | 136 | *wall = (cputime64_t)jiffies_to_usecs(cur_wall_time); |
| 137 | 137 | ||
| 138 | return idle_time; | 138 | return (cputime64_t)jiffies_to_usecs(idle_time); |
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall) | 141 | static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall) |
