Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'pm+acpi-for-3.8-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull ACPI and power management fixes from Rafael Wysocki:

- Two cpuidle initialization fixes from Konrad Rzeszutek Wilk.

- cpufreq regression fixes for AMD processors from Borislav Petkov,
Stefan Bader, and Matthew Garrett.

- ACPI cpufreq fix from Thomas Schlichter.

- cpufreq and devfreq fixes related to incorrect usage of operating
performance points (OPP) framework and RCU from Nishanth Menon.

- APEI workaround for incorrect BIOS information from Lans Zhang.

* tag 'pm+acpi-for-3.8-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
cpufreq: Add module aliases for acpi-cpufreq
ACPI: Check MSR valid bit before using P-state frequencies
PM / devfreq: exynos4_bus: honor RCU lock usage
PM / devfreq: add locking documentation for recommended_opp
cpufreq: cpufreq-cpu0: use RCU locks around usage of OPP
cpufreq: OMAP: use RCU locks around usage of OPP
ACPI, APEI: Fixup incorrect 64-bit access width firmware bug
ACPI / processor: Get power info before updating the C-states
powernow-k8: Add a kconfig dependency on acpi-cpufreq
ACPI / cpuidle: Fix NULL pointer issues when cpuidle is disabled
intel_idle: Don't register CPU notifier if we are not running.

+103 -30
+3
drivers/acpi/apei/apei-base.c
··· 590 590 if (bit_width == 32 && bit_offset == 0 && (*paddr & 0x03) == 0 && 591 591 *access_bit_width < 32) 592 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 597 if ((bit_width + bit_offset) > *access_bit_width) { 595 598 pr_warning(FW_BUG APEI_PFX
+4
drivers/acpi/processor_idle.c
··· 958 958 return -EINVAL; 959 959 } 960 960 961 + if (!dev) 962 + return -EINVAL; 963 + 961 964 dev->cpu = pr->id; 962 965 963 966 if (max_cstate == 0) ··· 1152 1149 } 1153 1150 1154 1151 /* Populate Updated C-state information */ 1152 + acpi_processor_get_power_info(pr); 1155 1153 acpi_processor_setup_cpuidle_states(pr); 1156 1154 1157 1155 /* Enable all cpuidle devices */
+7
drivers/acpi/processor_perflib.c
··· 340 340 if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10) 341 341 || boot_cpu_data.x86 == 0x11) { 342 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 350 fid = lo & 0x3f; 344 351 did = (lo >> 6) & 7; 345 352 if (boot_cpu_data.x86 == 0x10)
+1 -1
drivers/cpufreq/Kconfig.x86
··· 106 106 config X86_POWERNOW_K8 107 107 tristate "AMD Opteron/Athlon64 PowerNow!" 108 108 select CPU_FREQ_TABLE 109 - depends on ACPI && ACPI_PROCESSOR 109 + depends on ACPI && ACPI_PROCESSOR && X86_ACPI_CPUFREQ 110 110 help 111 111 This adds the CPUFreq driver for K8/early Opteron/Athlon64 processors. 112 112 Support for K10 and newer processors is now in acpi-cpufreq.
+7
drivers/cpufreq/acpi-cpufreq.c
··· 1030 1030 late_initcall(acpi_cpufreq_init); 1031 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 1040 MODULE_ALIAS("acpi");
+5
drivers/cpufreq/cpufreq-cpu0.c
··· 71 71 } 72 72 73 73 if (cpu_reg) { 74 + rcu_read_lock(); 74 75 opp = opp_find_freq_ceil(cpu_dev, &freq_Hz); 75 76 if (IS_ERR(opp)) { 77 + rcu_read_unlock(); 76 78 pr_err("failed to find OPP for %ld\n", freq_Hz); 77 79 return PTR_ERR(opp); 78 80 } 79 81 volt = opp_get_voltage(opp); 82 + rcu_read_unlock(); 80 83 tol = volt * voltage_tolerance / 100; 81 84 volt_old = regulator_get_voltage(cpu_reg); 82 85 } ··· 239 236 */ 240 237 for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) 241 238 ; 239 + rcu_read_lock(); 242 240 opp = opp_find_freq_exact(cpu_dev, 243 241 freq_table[0].frequency * 1000, true); 244 242 min_uV = opp_get_voltage(opp); 245 243 opp = opp_find_freq_exact(cpu_dev, 246 244 freq_table[i-1].frequency * 1000, true); 247 245 max_uV = opp_get_voltage(opp); 246 + rcu_read_unlock(); 248 247 ret = regulator_set_voltage_time(cpu_reg, min_uV, max_uV); 249 248 if (ret > 0) 250 249 transition_latency += ret * 1000;
+3
drivers/cpufreq/omap-cpufreq.c
··· 110 110 freq = ret; 111 111 112 112 if (mpu_reg) { 113 + rcu_read_lock(); 113 114 opp = opp_find_freq_ceil(mpu_dev, &freq); 114 115 if (IS_ERR(opp)) { 116 + rcu_read_unlock(); 115 117 dev_err(mpu_dev, "%s: unable to find MPU OPP for %d\n", 116 118 __func__, freqs.new); 117 119 return -EINVAL; 118 120 } 119 121 volt = opp_get_voltage(opp); 122 + rcu_read_unlock(); 120 123 tol = volt * OPP_TOLERANCE / 100; 121 124 volt_old = regulator_get_voltage(mpu_reg); 122 125 }
+5
drivers/devfreq/devfreq.c
··· 994 994 * @freq: The frequency given to target function 995 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 1003 struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq, 999 1004 u32 flags)
+67 -27
drivers/devfreq/exynos4_bus.c
··· 73 73 #define EX4210_LV_NUM (LV_2 + 1) 74 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 86 struct busfreq_data { 77 87 enum exynos4_busf_type type; 78 88 struct device *dev; ··· 90 80 bool disabled; 91 81 struct regulator *vdd_int; 92 82 struct regulator *vdd_mif; /* Exynos4412/4212 only */ 93 - struct opp *curr_opp; 83 + struct busfreq_opp_info curr_oppinfo; 94 84 struct exynos4_ppmu dmc[2]; 95 85 96 86 struct notifier_block pm_notifier; ··· 306 296 }; 307 297 308 298 309 - static int exynos4210_set_busclk(struct busfreq_data *data, struct opp *opp) 299 + static int exynos4210_set_busclk(struct busfreq_data *data, 300 + struct busfreq_opp_info *oppi) 310 301 { 311 302 unsigned int index; 312 303 unsigned int tmp; 313 304 314 305 for (index = LV_0; index < EX4210_LV_NUM; index++) 315 - if (opp_get_freq(opp) == exynos4210_busclk_table[index].clk) 306 + if (oppi->rate == exynos4210_busclk_table[index].clk) 316 307 break; 317 308 318 309 if (index == EX4210_LV_NUM) ··· 372 361 return 0; 373 362 } 374 363 375 - static int exynos4x12_set_busclk(struct busfreq_data *data, struct opp *opp) 364 + static int exynos4x12_set_busclk(struct busfreq_data *data, 365 + struct busfreq_opp_info *oppi) 376 366 { 377 367 unsigned int index; 378 368 unsigned int tmp; 379 369 380 370 for (index = LV_0; index < EX4x12_LV_NUM; index++) 381 - if (opp_get_freq(opp) == exynos4x12_mifclk_table[index].clk) 371 + if (oppi->rate == exynos4x12_mifclk_table[index].clk) 382 372 break; 383 373 384 374 if (index == EX4x12_LV_NUM) ··· 588 576 return -EINVAL; 589 577 } 590 578 591 - static int exynos4_bus_setvolt(struct busfreq_data *data, struct opp *opp, 592 - struct opp *oldopp) 579 + static int exynos4_bus_setvolt(struct busfreq_data *data, 580 + struct busfreq_opp_info *oppi, 581 + struct busfreq_opp_info *oldoppi) 593 582 { 594 583 int err = 0, tmp; 595 - unsigned long volt = opp_get_voltage(opp); 584 + unsigned long volt = oppi->volt; 596 585 597 586 switch (data->type) { 598 587 case TYPE_BUSF_EXYNOS4210: ··· 608 595 if (err) 609 596 break; 610 597 611 - tmp = exynos4x12_get_intspec(opp_get_freq(opp)); 598 + tmp = exynos4x12_get_intspec(oppi->rate); 612 599 if (tmp < 0) { 613 600 err = tmp; 614 601 regulator_set_voltage(data->vdd_mif, 615 - opp_get_voltage(oldopp), 602 + oldoppi->volt, 616 603 MAX_SAFEVOLT); 617 604 break; 618 605 } ··· 622 609 /* Try to recover */ 623 610 if (err) 624 611 regulator_set_voltage(data->vdd_mif, 625 - opp_get_voltage(oldopp), 612 + oldoppi->volt, 626 613 MAX_SAFEVOLT); 627 614 break; 628 615 default: ··· 639 626 struct platform_device *pdev = container_of(dev, struct platform_device, 640 627 dev); 641 628 struct busfreq_data *data = platform_get_drvdata(pdev); 642 - struct opp *opp = devfreq_recommended_opp(dev, _freq, flags); 643 - unsigned long freq = opp_get_freq(opp); 644 - unsigned long old_freq = opp_get_freq(data->curr_opp); 629 + struct opp *opp; 630 + unsigned long freq; 631 + unsigned long old_freq = data->curr_oppinfo.rate; 632 + struct busfreq_opp_info new_oppinfo; 645 633 646 - if (IS_ERR(opp)) 634 + rcu_read_lock(); 635 + opp = devfreq_recommended_opp(dev, _freq, flags); 636 + if (IS_ERR(opp)) { 637 + rcu_read_unlock(); 647 638 return PTR_ERR(opp); 639 + } 640 + new_oppinfo.rate = opp_get_freq(opp); 641 + new_oppinfo.volt = opp_get_voltage(opp); 642 + rcu_read_unlock(); 643 + freq = new_oppinfo.rate; 648 644 649 645 if (old_freq == freq) 650 646 return 0; 651 647 652 - dev_dbg(dev, "targetting %lukHz %luuV\n", freq, opp_get_voltage(opp)); 648 + dev_dbg(dev, "targetting %lukHz %luuV\n", freq, new_oppinfo.volt); 653 649 654 650 mutex_lock(&data->lock); 655 651 ··· 666 644 goto out; 667 645 668 646 if (old_freq < freq) 669 - err = exynos4_bus_setvolt(data, opp, data->curr_opp); 647 + err = exynos4_bus_setvolt(data, &new_oppinfo, 648 + &data->curr_oppinfo); 670 649 if (err) 671 650 goto out; 672 651 673 652 if (old_freq != freq) { 674 653 switch (data->type) { 675 654 case TYPE_BUSF_EXYNOS4210: 676 - err = exynos4210_set_busclk(data, opp); 655 + err = exynos4210_set_busclk(data, &new_oppinfo); 677 656 break; 678 657 case TYPE_BUSF_EXYNOS4x12: 679 - err = exynos4x12_set_busclk(data, opp); 658 + err = exynos4x12_set_busclk(data, &new_oppinfo); 680 659 break; 681 660 default: 682 661 err = -EINVAL; ··· 687 664 goto out; 688 665 689 666 if (old_freq > freq) 690 - err = exynos4_bus_setvolt(data, opp, data->curr_opp); 667 + err = exynos4_bus_setvolt(data, &new_oppinfo, 668 + &data->curr_oppinfo); 691 669 if (err) 692 670 goto out; 693 671 694 - data->curr_opp = opp; 672 + data->curr_oppinfo = new_oppinfo; 695 673 out: 696 674 mutex_unlock(&data->lock); 697 675 return err; ··· 726 702 727 703 exynos4_read_ppmu(data); 728 704 busier_dmc = exynos4_get_busier_dmc(data); 729 - stat->current_frequency = opp_get_freq(data->curr_opp); 705 + stat->current_frequency = data->curr_oppinfo.rate; 730 706 731 707 if (busier_dmc) 732 708 addr = S5P_VA_DMC1; ··· 957 933 struct busfreq_data *data = container_of(this, struct busfreq_data, 958 934 pm_notifier); 959 935 struct opp *opp; 936 + struct busfreq_opp_info new_oppinfo; 960 937 unsigned long maxfreq = ULONG_MAX; 961 938 int err = 0; 962 939 ··· 968 943 969 944 data->disabled = true; 970 945 946 + rcu_read_lock(); 971 947 opp = opp_find_freq_floor(data->dev, &maxfreq); 948 + if (IS_ERR(opp)) { 949 + rcu_read_unlock(); 950 + dev_err(data->dev, "%s: unable to find a min freq\n", 951 + __func__); 952 + return PTR_ERR(opp); 953 + } 954 + new_oppinfo.rate = opp_get_freq(opp); 955 + new_oppinfo.volt = opp_get_voltage(opp); 956 + rcu_read_unlock(); 972 957 973 - err = exynos4_bus_setvolt(data, opp, data->curr_opp); 958 + err = exynos4_bus_setvolt(data, &new_oppinfo, 959 + &data->curr_oppinfo); 974 960 if (err) 975 961 goto unlock; 976 962 977 963 switch (data->type) { 978 964 case TYPE_BUSF_EXYNOS4210: 979 - err = exynos4210_set_busclk(data, opp); 965 + err = exynos4210_set_busclk(data, &new_oppinfo); 980 966 break; 981 967 case TYPE_BUSF_EXYNOS4x12: 982 - err = exynos4x12_set_busclk(data, opp); 968 + err = exynos4x12_set_busclk(data, &new_oppinfo); 983 969 break; 984 970 default: 985 971 err = -EINVAL; ··· 998 962 if (err) 999 963 goto unlock; 1000 964 1001 - data->curr_opp = opp; 965 + data->curr_oppinfo = new_oppinfo; 1002 966 unlock: 1003 967 mutex_unlock(&data->lock); 1004 968 if (err) ··· 1063 1027 } 1064 1028 } 1065 1029 1030 + rcu_read_lock(); 1066 1031 opp = opp_find_freq_floor(dev, &exynos4_devfreq_profile.initial_freq); 1067 1032 if (IS_ERR(opp)) { 1033 + rcu_read_unlock(); 1068 1034 dev_err(dev, "Invalid initial frequency %lu kHz.\n", 1069 1035 exynos4_devfreq_profile.initial_freq); 1070 1036 return PTR_ERR(opp); 1071 1037 } 1072 - data->curr_opp = opp; 1038 + data->curr_oppinfo.rate = opp_get_freq(opp); 1039 + data->curr_oppinfo.volt = opp_get_voltage(opp); 1040 + rcu_read_unlock(); 1073 1041 1074 1042 platform_set_drvdata(pdev, data); 1075 1043
+1 -2
drivers/idle/intel_idle.c
··· 448 448 else 449 449 on_each_cpu(__setup_broadcast_timer, (void *)true, 1); 450 450 451 - register_cpu_notifier(&cpu_hotplug_notifier); 452 - 453 451 pr_debug(PREFIX "v" INTEL_IDLE_VERSION 454 452 " model 0x%X\n", boot_cpu_data.x86_model); 455 453 ··· 610 612 return retval; 611 613 } 612 614 } 615 + register_cpu_notifier(&cpu_hotplug_notifier); 613 616 614 617 return 0; 615 618 }