diff options
| -rw-r--r-- | drivers/acpi/apei/apei-base.c | 3 | ||||
| -rw-r--r-- | drivers/acpi/processor_idle.c | 4 | ||||
| -rw-r--r-- | drivers/acpi/processor_perflib.c | 7 | ||||
| -rw-r--r-- | drivers/cpufreq/Kconfig.x86 | 2 | ||||
| -rw-r--r-- | drivers/cpufreq/acpi-cpufreq.c | 7 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq-cpu0.c | 5 | ||||
| -rw-r--r-- | drivers/cpufreq/omap-cpufreq.c | 3 | ||||
| -rw-r--r-- | drivers/devfreq/devfreq.c | 5 | ||||
| -rw-r--r-- | drivers/devfreq/exynos4_bus.c | 94 | ||||
| -rw-r--r-- | drivers/idle/intel_idle.c | 3 |
10 files changed, 103 insertions, 30 deletions
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index 00a783661d0b..46f80e2c92f7 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c | |||
| @@ -590,6 +590,9 @@ static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr, | |||
| 590 | if (bit_width == 32 && bit_offset == 0 && (*paddr & 0x03) == 0 && | 590 | if (bit_width == 32 && bit_offset == 0 && (*paddr & 0x03) == 0 && |
| 591 | *access_bit_width < 32) | 591 | *access_bit_width < 32) |
| 592 | *access_bit_width = 32; | 592 | *access_bit_width = 32; |
| 593 | else if (bit_width == 64 && bit_offset == 0 && (*paddr & 0x07) == 0 && | ||
| 594 | *access_bit_width < 64) | ||
| 595 | *access_bit_width = 64; | ||
| 593 | 596 | ||
| 594 | if ((bit_width + bit_offset) > *access_bit_width) { | 597 | if ((bit_width + bit_offset) > *access_bit_width) { |
| 595 | pr_warning(FW_BUG APEI_PFX | 598 | pr_warning(FW_BUG APEI_PFX |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index f1a5da44591d..ed9a1cc690be 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
| @@ -958,6 +958,9 @@ static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr) | |||
| 958 | return -EINVAL; | 958 | return -EINVAL; |
| 959 | } | 959 | } |
| 960 | 960 | ||
| 961 | if (!dev) | ||
| 962 | return -EINVAL; | ||
| 963 | |||
| 961 | dev->cpu = pr->id; | 964 | dev->cpu = pr->id; |
| 962 | 965 | ||
| 963 | if (max_cstate == 0) | 966 | if (max_cstate == 0) |
| @@ -1149,6 +1152,7 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr) | |||
| 1149 | } | 1152 | } |
| 1150 | 1153 | ||
| 1151 | /* Populate Updated C-state information */ | 1154 | /* Populate Updated C-state information */ |
| 1155 | acpi_processor_get_power_info(pr); | ||
| 1152 | acpi_processor_setup_cpuidle_states(pr); | 1156 | acpi_processor_setup_cpuidle_states(pr); |
| 1153 | 1157 | ||
| 1154 | /* Enable all cpuidle devices */ | 1158 | /* Enable all cpuidle devices */ |
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 836bfe069042..53e7ac9403a7 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
| @@ -340,6 +340,13 @@ static void amd_fixup_frequency(struct acpi_processor_px *px, int i) | |||
| 340 | if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10) | 340 | if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10) |
| 341 | || boot_cpu_data.x86 == 0x11) { | 341 | || boot_cpu_data.x86 == 0x11) { |
| 342 | rdmsr(MSR_AMD_PSTATE_DEF_BASE + index, lo, hi); | 342 | rdmsr(MSR_AMD_PSTATE_DEF_BASE + index, lo, hi); |
| 343 | /* | ||
| 344 | * MSR C001_0064+: | ||
| 345 | * Bit 63: PstateEn. Read-write. If set, the P-state is valid. | ||
| 346 | */ | ||
| 347 | if (!(hi & BIT(31))) | ||
| 348 | return; | ||
| 349 | |||
| 343 | fid = lo & 0x3f; | 350 | fid = lo & 0x3f; |
| 344 | did = (lo >> 6) & 7; | 351 | did = (lo >> 6) & 7; |
| 345 | if (boot_cpu_data.x86 == 0x10) | 352 | if (boot_cpu_data.x86 == 0x10) |
diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86 index 934854ae5eb4..7227cd734042 100644 --- a/drivers/cpufreq/Kconfig.x86 +++ b/drivers/cpufreq/Kconfig.x86 | |||
| @@ -106,7 +106,7 @@ config X86_POWERNOW_K7_ACPI | |||
| 106 | config X86_POWERNOW_K8 | 106 | config X86_POWERNOW_K8 |
| 107 | tristate "AMD Opteron/Athlon64 PowerNow!" | 107 | tristate "AMD Opteron/Athlon64 PowerNow!" |
| 108 | select CPU_FREQ_TABLE | 108 | select CPU_FREQ_TABLE |
| 109 | depends on ACPI && ACPI_PROCESSOR | 109 | depends on ACPI && ACPI_PROCESSOR && X86_ACPI_CPUFREQ |
| 110 | help | 110 | help |
| 111 | This adds the CPUFreq driver for K8/early Opteron/Athlon64 processors. | 111 | This adds the CPUFreq driver for K8/early Opteron/Athlon64 processors. |
| 112 | Support for K10 and newer processors is now in acpi-cpufreq. | 112 | Support for K10 and newer processors is now in acpi-cpufreq. |
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 0d048f6a2b23..7b0d49d78c61 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c | |||
| @@ -1030,4 +1030,11 @@ MODULE_PARM_DESC(acpi_pstate_strict, | |||
| 1030 | late_initcall(acpi_cpufreq_init); | 1030 | late_initcall(acpi_cpufreq_init); |
| 1031 | module_exit(acpi_cpufreq_exit); | 1031 | module_exit(acpi_cpufreq_exit); |
| 1032 | 1032 | ||
| 1033 | static const struct x86_cpu_id acpi_cpufreq_ids[] = { | ||
| 1034 | X86_FEATURE_MATCH(X86_FEATURE_ACPI), | ||
| 1035 | X86_FEATURE_MATCH(X86_FEATURE_HW_PSTATE), | ||
| 1036 | {} | ||
| 1037 | }; | ||
| 1038 | MODULE_DEVICE_TABLE(x86cpu, acpi_cpufreq_ids); | ||
| 1039 | |||
| 1033 | MODULE_ALIAS("acpi"); | 1040 | MODULE_ALIAS("acpi"); |
diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c index 52bf36d599f5..debc5a7c8db6 100644 --- a/drivers/cpufreq/cpufreq-cpu0.c +++ b/drivers/cpufreq/cpufreq-cpu0.c | |||
| @@ -71,12 +71,15 @@ static int cpu0_set_target(struct cpufreq_policy *policy, | |||
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | if (cpu_reg) { | 73 | if (cpu_reg) { |
| 74 | rcu_read_lock(); | ||
| 74 | opp = opp_find_freq_ceil(cpu_dev, &freq_Hz); | 75 | opp = opp_find_freq_ceil(cpu_dev, &freq_Hz); |
| 75 | if (IS_ERR(opp)) { | 76 | if (IS_ERR(opp)) { |
| 77 | rcu_read_unlock(); | ||
| 76 | pr_err("failed to find OPP for %ld\n", freq_Hz); | 78 | pr_err("failed to find OPP for %ld\n", freq_Hz); |
| 77 | return PTR_ERR(opp); | 79 | return PTR_ERR(opp); |
| 78 | } | 80 | } |
| 79 | volt = opp_get_voltage(opp); | 81 | volt = opp_get_voltage(opp); |
| 82 | rcu_read_unlock(); | ||
| 80 | tol = volt * voltage_tolerance / 100; | 83 | tol = volt * voltage_tolerance / 100; |
| 81 | volt_old = regulator_get_voltage(cpu_reg); | 84 | volt_old = regulator_get_voltage(cpu_reg); |
| 82 | } | 85 | } |
| @@ -236,12 +239,14 @@ static int cpu0_cpufreq_driver_init(void) | |||
| 236 | */ | 239 | */ |
| 237 | for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) | 240 | for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) |
| 238 | ; | 241 | ; |
| 242 | rcu_read_lock(); | ||
| 239 | opp = opp_find_freq_exact(cpu_dev, | 243 | opp = opp_find_freq_exact(cpu_dev, |
| 240 | freq_table[0].frequency * 1000, true); | 244 | freq_table[0].frequency * 1000, true); |
| 241 | min_uV = opp_get_voltage(opp); | 245 | min_uV = opp_get_voltage(opp); |
| 242 | opp = opp_find_freq_exact(cpu_dev, | 246 | opp = opp_find_freq_exact(cpu_dev, |
| 243 | freq_table[i-1].frequency * 1000, true); | 247 | freq_table[i-1].frequency * 1000, true); |
| 244 | max_uV = opp_get_voltage(opp); | 248 | max_uV = opp_get_voltage(opp); |
| 249 | rcu_read_unlock(); | ||
| 245 | ret = regulator_set_voltage_time(cpu_reg, min_uV, max_uV); | 250 | ret = regulator_set_voltage_time(cpu_reg, min_uV, max_uV); |
| 246 | if (ret > 0) | 251 | if (ret > 0) |
| 247 | transition_latency += ret * 1000; | 252 | transition_latency += ret * 1000; |
diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c index 1f3417a8322d..97102b05843f 100644 --- a/drivers/cpufreq/omap-cpufreq.c +++ b/drivers/cpufreq/omap-cpufreq.c | |||
| @@ -110,13 +110,16 @@ static int omap_target(struct cpufreq_policy *policy, | |||
| 110 | freq = ret; | 110 | freq = ret; |
| 111 | 111 | ||
| 112 | if (mpu_reg) { | 112 | if (mpu_reg) { |
| 113 | rcu_read_lock(); | ||
| 113 | opp = opp_find_freq_ceil(mpu_dev, &freq); | 114 | opp = opp_find_freq_ceil(mpu_dev, &freq); |
| 114 | if (IS_ERR(opp)) { | 115 | if (IS_ERR(opp)) { |
| 116 | rcu_read_unlock(); | ||
| 115 | dev_err(mpu_dev, "%s: unable to find MPU OPP for %d\n", | 117 | dev_err(mpu_dev, "%s: unable to find MPU OPP for %d\n", |
| 116 | __func__, freqs.new); | 118 | __func__, freqs.new); |
| 117 | return -EINVAL; | 119 | return -EINVAL; |
| 118 | } | 120 | } |
| 119 | volt = opp_get_voltage(opp); | 121 | volt = opp_get_voltage(opp); |
| 122 | rcu_read_unlock(); | ||
| 120 | tol = volt * OPP_TOLERANCE / 100; | 123 | tol = volt * OPP_TOLERANCE / 100; |
| 121 | volt_old = regulator_get_voltage(mpu_reg); | 124 | volt_old = regulator_get_voltage(mpu_reg); |
| 122 | } | 125 | } |
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 53766f39aadd..3b367973a802 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c | |||
| @@ -994,6 +994,11 @@ module_exit(devfreq_exit); | |||
| 994 | * @freq: The frequency given to target function | 994 | * @freq: The frequency given to target function |
| 995 | * @flags: Flags handed from devfreq framework. | 995 | * @flags: Flags handed from devfreq framework. |
| 996 | * | 996 | * |
| 997 | * Locking: This function must be called under rcu_read_lock(). opp is a rcu | ||
| 998 | * protected pointer. The reason for the same is that the opp pointer which is | ||
| 999 | * returned will remain valid for use with opp_get_{voltage, freq} only while | ||
| 1000 | * under the locked area. The pointer returned must be used prior to unlocking | ||
| 1001 | * with rcu_read_unlock() to maintain the integrity of the pointer. | ||
| 997 | */ | 1002 | */ |
| 998 | struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq, | 1003 | struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq, |
| 999 | u32 flags) | 1004 | u32 flags) |
diff --git a/drivers/devfreq/exynos4_bus.c b/drivers/devfreq/exynos4_bus.c index 80c745e83082..46d94e9e95b5 100644 --- a/drivers/devfreq/exynos4_bus.c +++ b/drivers/devfreq/exynos4_bus.c | |||
| @@ -73,6 +73,16 @@ enum busclk_level_idx { | |||
| 73 | #define EX4210_LV_NUM (LV_2 + 1) | 73 | #define EX4210_LV_NUM (LV_2 + 1) |
| 74 | #define EX4x12_LV_NUM (LV_4 + 1) | 74 | #define EX4x12_LV_NUM (LV_4 + 1) |
| 75 | 75 | ||
| 76 | /** | ||
| 77 | * struct busfreq_opp_info - opp information for bus | ||
| 78 | * @rate: Frequency in hertz | ||
| 79 | * @volt: Voltage in microvolts corresponding to this OPP | ||
| 80 | */ | ||
| 81 | struct busfreq_opp_info { | ||
| 82 | unsigned long rate; | ||
| 83 | unsigned long volt; | ||
| 84 | }; | ||
| 85 | |||
| 76 | struct busfreq_data { | 86 | struct busfreq_data { |
| 77 | enum exynos4_busf_type type; | 87 | enum exynos4_busf_type type; |
| 78 | struct device *dev; | 88 | struct device *dev; |
| @@ -80,7 +90,7 @@ struct busfreq_data { | |||
| 80 | bool disabled; | 90 | bool disabled; |
| 81 | struct regulator *vdd_int; | 91 | struct regulator *vdd_int; |
| 82 | struct regulator *vdd_mif; /* Exynos4412/4212 only */ | 92 | struct regulator *vdd_mif; /* Exynos4412/4212 only */ |
| 83 | struct opp *curr_opp; | 93 | struct busfreq_opp_info curr_oppinfo; |
| 84 | struct exynos4_ppmu dmc[2]; | 94 | struct exynos4_ppmu dmc[2]; |
| 85 | 95 | ||
| 86 | struct notifier_block pm_notifier; | 96 | struct notifier_block pm_notifier; |
| @@ -296,13 +306,14 @@ static unsigned int exynos4x12_clkdiv_sclkip[][3] = { | |||
| 296 | }; | 306 | }; |
| 297 | 307 | ||
| 298 | 308 | ||
| 299 | static int exynos4210_set_busclk(struct busfreq_data *data, struct opp *opp) | 309 | static int exynos4210_set_busclk(struct busfreq_data *data, |
| 310 | struct busfreq_opp_info *oppi) | ||
| 300 | { | 311 | { |
| 301 | unsigned int index; | 312 | unsigned int index; |
| 302 | unsigned int tmp; | 313 | unsigned int tmp; |
| 303 | 314 | ||
| 304 | for (index = LV_0; index < EX4210_LV_NUM; index++) | 315 | for (index = LV_0; index < EX4210_LV_NUM; index++) |
| 305 | if (opp_get_freq(opp) == exynos4210_busclk_table[index].clk) | 316 | if (oppi->rate == exynos4210_busclk_table[index].clk) |
| 306 | break; | 317 | break; |
| 307 | 318 | ||
| 308 | if (index == EX4210_LV_NUM) | 319 | if (index == EX4210_LV_NUM) |
| @@ -361,13 +372,14 @@ static int exynos4210_set_busclk(struct busfreq_data *data, struct opp *opp) | |||
| 361 | return 0; | 372 | return 0; |
| 362 | } | 373 | } |
| 363 | 374 | ||
| 364 | static int exynos4x12_set_busclk(struct busfreq_data *data, struct opp *opp) | 375 | static int exynos4x12_set_busclk(struct busfreq_data *data, |
| 376 | struct busfreq_opp_info *oppi) | ||
| 365 | { | 377 | { |
| 366 | unsigned int index; | 378 | unsigned int index; |
| 367 | unsigned int tmp; | 379 | unsigned int tmp; |
| 368 | 380 | ||
| 369 | for (index = LV_0; index < EX4x12_LV_NUM; index++) | 381 | for (index = LV_0; index < EX4x12_LV_NUM; index++) |
| 370 | if (opp_get_freq(opp) == exynos4x12_mifclk_table[index].clk) | 382 | if (oppi->rate == exynos4x12_mifclk_table[index].clk) |
| 371 | break; | 383 | break; |
| 372 | 384 | ||
| 373 | if (index == EX4x12_LV_NUM) | 385 | if (index == EX4x12_LV_NUM) |
| @@ -576,11 +588,12 @@ static int exynos4x12_get_intspec(unsigned long mifclk) | |||
| 576 | return -EINVAL; | 588 | return -EINVAL; |
| 577 | } | 589 | } |
| 578 | 590 | ||
| 579 | static int exynos4_bus_setvolt(struct busfreq_data *data, struct opp *opp, | 591 | static int exynos4_bus_setvolt(struct busfreq_data *data, |
| 580 | struct opp *oldopp) | 592 | struct busfreq_opp_info *oppi, |
| 593 | struct busfreq_opp_info *oldoppi) | ||
| 581 | { | 594 | { |
| 582 | int err = 0, tmp; | 595 | int err = 0, tmp; |
| 583 | unsigned long volt = opp_get_voltage(opp); | 596 | unsigned long volt = oppi->volt; |
| 584 | 597 | ||
| 585 | switch (data->type) { | 598 | switch (data->type) { |
| 586 | case TYPE_BUSF_EXYNOS4210: | 599 | case TYPE_BUSF_EXYNOS4210: |
| @@ -595,11 +608,11 @@ static int exynos4_bus_setvolt(struct busfreq_data *data, struct opp *opp, | |||
| 595 | if (err) | 608 | if (err) |
| 596 | break; | 609 | break; |
| 597 | 610 | ||
| 598 | tmp = exynos4x12_get_intspec(opp_get_freq(opp)); | 611 | tmp = exynos4x12_get_intspec(oppi->rate); |
| 599 | if (tmp < 0) { | 612 | if (tmp < 0) { |
| 600 | err = tmp; | 613 | err = tmp; |
| 601 | regulator_set_voltage(data->vdd_mif, | 614 | regulator_set_voltage(data->vdd_mif, |
| 602 | opp_get_voltage(oldopp), | 615 | oldoppi->volt, |
| 603 | MAX_SAFEVOLT); | 616 | MAX_SAFEVOLT); |
| 604 | break; | 617 | break; |
| 605 | } | 618 | } |
| @@ -609,7 +622,7 @@ static int exynos4_bus_setvolt(struct busfreq_data *data, struct opp *opp, | |||
| 609 | /* Try to recover */ | 622 | /* Try to recover */ |
| 610 | if (err) | 623 | if (err) |
| 611 | regulator_set_voltage(data->vdd_mif, | 624 | regulator_set_voltage(data->vdd_mif, |
| 612 | opp_get_voltage(oldopp), | 625 | oldoppi->volt, |
| 613 | MAX_SAFEVOLT); | 626 | MAX_SAFEVOLT); |
| 614 | break; | 627 | break; |
| 615 | default: | 628 | default: |
| @@ -626,17 +639,26 @@ static int exynos4_bus_target(struct device *dev, unsigned long *_freq, | |||
| 626 | struct platform_device *pdev = container_of(dev, struct platform_device, | 639 | struct platform_device *pdev = container_of(dev, struct platform_device, |
| 627 | dev); | 640 | dev); |
| 628 | struct busfreq_data *data = platform_get_drvdata(pdev); | 641 | struct busfreq_data *data = platform_get_drvdata(pdev); |
| 629 | struct opp *opp = devfreq_recommended_opp(dev, _freq, flags); | 642 | struct opp *opp; |
| 630 | unsigned long freq = opp_get_freq(opp); | 643 | unsigned long freq; |
| 631 | unsigned long old_freq = opp_get_freq(data->curr_opp); | 644 | unsigned long old_freq = data->curr_oppinfo.rate; |
| 645 | struct busfreq_opp_info new_oppinfo; | ||
| 632 | 646 | ||
| 633 | if (IS_ERR(opp)) | 647 | rcu_read_lock(); |
| 648 | opp = devfreq_recommended_opp(dev, _freq, flags); | ||
| 649 | if (IS_ERR(opp)) { | ||
| 650 | rcu_read_unlock(); | ||
| 634 | return PTR_ERR(opp); | 651 | return PTR_ERR(opp); |
| 652 | } | ||
| 653 | new_oppinfo.rate = opp_get_freq(opp); | ||
| 654 | new_oppinfo.volt = opp_get_voltage(opp); | ||
| 655 | rcu_read_unlock(); | ||
| 656 | freq = new_oppinfo.rate; | ||
| 635 | 657 | ||
| 636 | if (old_freq == freq) | 658 | if (old_freq == freq) |
| 637 | return 0; | 659 | return 0; |
| 638 | 660 | ||
| 639 | dev_dbg(dev, "targetting %lukHz %luuV\n", freq, opp_get_voltage(opp)); | 661 | dev_dbg(dev, "targetting %lukHz %luuV\n", freq, new_oppinfo.volt); |
| 640 | 662 | ||
| 641 | mutex_lock(&data->lock); | 663 | mutex_lock(&data->lock); |
| 642 | 664 | ||
| @@ -644,17 +666,18 @@ static int exynos4_bus_target(struct device *dev, unsigned long *_freq, | |||
| 644 | goto out; | 666 | goto out; |
| 645 | 667 | ||
| 646 | if (old_freq < freq) | 668 | if (old_freq < freq) |
| 647 | err = exynos4_bus_setvolt(data, opp, data->curr_opp); | 669 | err = exynos4_bus_setvolt(data, &new_oppinfo, |
| 670 | &data->curr_oppinfo); | ||
| 648 | if (err) | 671 | if (err) |
| 649 | goto out; | 672 | goto out; |
| 650 | 673 | ||
| 651 | if (old_freq != freq) { | 674 | if (old_freq != freq) { |
| 652 | switch (data->type) { | 675 | switch (data->type) { |
| 653 | case TYPE_BUSF_EXYNOS4210: | 676 | case TYPE_BUSF_EXYNOS4210: |
| 654 | err = exynos4210_set_busclk(data, opp); | 677 | err = exynos4210_set_busclk(data, &new_oppinfo); |
| 655 | break; | 678 | break; |
| 656 | case TYPE_BUSF_EXYNOS4x12: | 679 | case TYPE_BUSF_EXYNOS4x12: |
| 657 | err = exynos4x12_set_busclk(data, opp); | 680 | err = exynos4x12_set_busclk(data, &new_oppinfo); |
| 658 | break; | 681 | break; |
| 659 | default: | 682 | default: |
| 660 | err = -EINVAL; | 683 | err = -EINVAL; |
| @@ -664,11 +687,12 @@ static int exynos4_bus_target(struct device *dev, unsigned long *_freq, | |||
| 664 | goto out; | 687 | goto out; |
| 665 | 688 | ||
| 666 | if (old_freq > freq) | 689 | if (old_freq > freq) |
| 667 | err = exynos4_bus_setvolt(data, opp, data->curr_opp); | 690 | err = exynos4_bus_setvolt(data, &new_oppinfo, |
| 691 | &data->curr_oppinfo); | ||
| 668 | if (err) | 692 | if (err) |
| 669 | goto out; | 693 | goto out; |
| 670 | 694 | ||
| 671 | data->curr_opp = opp; | 695 | data->curr_oppinfo = new_oppinfo; |
| 672 | out: | 696 | out: |
| 673 | mutex_unlock(&data->lock); | 697 | mutex_unlock(&data->lock); |
| 674 | return err; | 698 | return err; |
| @@ -702,7 +726,7 @@ static int exynos4_bus_get_dev_status(struct device *dev, | |||
| 702 | 726 | ||
| 703 | exynos4_read_ppmu(data); | 727 | exynos4_read_ppmu(data); |
| 704 | busier_dmc = exynos4_get_busier_dmc(data); | 728 | busier_dmc = exynos4_get_busier_dmc(data); |
| 705 | stat->current_frequency = opp_get_freq(data->curr_opp); | 729 | stat->current_frequency = data->curr_oppinfo.rate; |
| 706 | 730 | ||
| 707 | if (busier_dmc) | 731 | if (busier_dmc) |
| 708 | addr = S5P_VA_DMC1; | 732 | addr = S5P_VA_DMC1; |
| @@ -933,6 +957,7 @@ static int exynos4_busfreq_pm_notifier_event(struct notifier_block *this, | |||
| 933 | struct busfreq_data *data = container_of(this, struct busfreq_data, | 957 | struct busfreq_data *data = container_of(this, struct busfreq_data, |
| 934 | pm_notifier); | 958 | pm_notifier); |
| 935 | struct opp *opp; | 959 | struct opp *opp; |
| 960 | struct busfreq_opp_info new_oppinfo; | ||
| 936 | unsigned long maxfreq = ULONG_MAX; | 961 | unsigned long maxfreq = ULONG_MAX; |
| 937 | int err = 0; | 962 | int err = 0; |
| 938 | 963 | ||
| @@ -943,18 +968,29 @@ static int exynos4_busfreq_pm_notifier_event(struct notifier_block *this, | |||
| 943 | 968 | ||
| 944 | data->disabled = true; | 969 | data->disabled = true; |
| 945 | 970 | ||
| 971 | rcu_read_lock(); | ||
| 946 | opp = opp_find_freq_floor(data->dev, &maxfreq); | 972 | opp = opp_find_freq_floor(data->dev, &maxfreq); |
| 973 | if (IS_ERR(opp)) { | ||
| 974 | rcu_read_unlock(); | ||
| 975 | dev_err(data->dev, "%s: unable to find a min freq\n", | ||
| 976 | __func__); | ||
| 977 | return PTR_ERR(opp); | ||
| 978 | } | ||
| 979 | new_oppinfo.rate = opp_get_freq(opp); | ||
| 980 | new_oppinfo.volt = opp_get_voltage(opp); | ||
| 981 | rcu_read_unlock(); | ||
| 947 | 982 | ||
| 948 | err = exynos4_bus_setvolt(data, opp, data->curr_opp); | 983 | err = exynos4_bus_setvolt(data, &new_oppinfo, |
| 984 | &data->curr_oppinfo); | ||
| 949 | if (err) | 985 | if (err) |
| 950 | goto unlock; | 986 | goto unlock; |
| 951 | 987 | ||
| 952 | switch (data->type) { | 988 | switch (data->type) { |
| 953 | case TYPE_BUSF_EXYNOS4210: | 989 | case TYPE_BUSF_EXYNOS4210: |
| 954 | err = exynos4210_set_busclk(data, opp); | 990 | err = exynos4210_set_busclk(data, &new_oppinfo); |
| 955 | break; | 991 | break; |
| 956 | case TYPE_BUSF_EXYNOS4x12: | 992 | case TYPE_BUSF_EXYNOS4x12: |
| 957 | err = exynos4x12_set_busclk(data, opp); | 993 | err = exynos4x12_set_busclk(data, &new_oppinfo); |
| 958 | break; | 994 | break; |
| 959 | default: | 995 | default: |
| 960 | err = -EINVAL; | 996 | err = -EINVAL; |
| @@ -962,7 +998,7 @@ static int exynos4_busfreq_pm_notifier_event(struct notifier_block *this, | |||
| 962 | if (err) | 998 | if (err) |
| 963 | goto unlock; | 999 | goto unlock; |
| 964 | 1000 | ||
| 965 | data->curr_opp = opp; | 1001 | data->curr_oppinfo = new_oppinfo; |
| 966 | unlock: | 1002 | unlock: |
| 967 | mutex_unlock(&data->lock); | 1003 | mutex_unlock(&data->lock); |
| 968 | if (err) | 1004 | if (err) |
| @@ -1027,13 +1063,17 @@ static int exynos4_busfreq_probe(struct platform_device *pdev) | |||
| 1027 | } | 1063 | } |
| 1028 | } | 1064 | } |
| 1029 | 1065 | ||
| 1066 | rcu_read_lock(); | ||
| 1030 | opp = opp_find_freq_floor(dev, &exynos4_devfreq_profile.initial_freq); | 1067 | opp = opp_find_freq_floor(dev, &exynos4_devfreq_profile.initial_freq); |
| 1031 | if (IS_ERR(opp)) { | 1068 | if (IS_ERR(opp)) { |
| 1069 | rcu_read_unlock(); | ||
| 1032 | dev_err(dev, "Invalid initial frequency %lu kHz.\n", | 1070 | dev_err(dev, "Invalid initial frequency %lu kHz.\n", |
| 1033 | exynos4_devfreq_profile.initial_freq); | 1071 | exynos4_devfreq_profile.initial_freq); |
| 1034 | return PTR_ERR(opp); | 1072 | return PTR_ERR(opp); |
| 1035 | } | 1073 | } |
| 1036 | data->curr_opp = opp; | 1074 | data->curr_oppinfo.rate = opp_get_freq(opp); |
| 1075 | data->curr_oppinfo.volt = opp_get_voltage(opp); | ||
| 1076 | rcu_read_unlock(); | ||
| 1037 | 1077 | ||
| 1038 | platform_set_drvdata(pdev, data); | 1078 | platform_set_drvdata(pdev, data); |
| 1039 | 1079 | ||
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 4ba384f1ab54..2df9414a72f7 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c | |||
| @@ -448,8 +448,6 @@ static int intel_idle_probe(void) | |||
| 448 | else | 448 | else |
| 449 | on_each_cpu(__setup_broadcast_timer, (void *)true, 1); | 449 | on_each_cpu(__setup_broadcast_timer, (void *)true, 1); |
| 450 | 450 | ||
| 451 | register_cpu_notifier(&cpu_hotplug_notifier); | ||
| 452 | |||
| 453 | pr_debug(PREFIX "v" INTEL_IDLE_VERSION | 451 | pr_debug(PREFIX "v" INTEL_IDLE_VERSION |
| 454 | " model 0x%X\n", boot_cpu_data.x86_model); | 452 | " model 0x%X\n", boot_cpu_data.x86_model); |
| 455 | 453 | ||
| @@ -612,6 +610,7 @@ static int __init intel_idle_init(void) | |||
| 612 | return retval; | 610 | return retval; |
| 613 | } | 611 | } |
| 614 | } | 612 | } |
| 613 | register_cpu_notifier(&cpu_hotplug_notifier); | ||
| 615 | 614 | ||
| 616 | return 0; | 615 | return 0; |
| 617 | } | 616 | } |
