aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-02 21:32:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-02 21:32:35 -0400
commit16642a2e7be23bbda013fc32d8f6c68982eab603 (patch)
tree346ae485f485f6901e5d8150f0d34d178a7dd448 /drivers/acpi
parent51562cba98939da0a1d10fe7c25359b77a069033 (diff)
parentb9142167a2bb979b58b98ffcd928a311b55cbd9f (diff)
Merge tag 'pm-for-3.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management updates from Rafael J Wysocki: - Improved system suspend/resume and runtime PM handling for the SH TMU, CMT and MTU2 clock event devices (also used by ARM/shmobile). - Generic PM domains framework extensions related to cpuidle support and domain objects lookup using names. - ARM/shmobile power management updates including improved support for the SH7372's A4S power domain containing the CPU core. - cpufreq changes related to AMD CPUs support from Matthew Garrett, Andre Przywara and Borislav Petkov. - cpu0 cpufreq driver from Shawn Guo. - cpufreq governor fixes related to the relaxing of limit from Michal Pecio. - OMAP cpufreq updates from Axel Lin and Richard Zhao. - cpuidle ladder governor fixes related to the disabling of states from Carsten Emde and me. - Runtime PM core updates related to the interactions with the system suspend core from Alan Stern and Kevin Hilman. - Wakeup sources modification allowing more helper functions to be called from interrupt context from John Stultz and additional diagnostic code from Todd Poynor. - System suspend error code path fix from Feng Hong. Fixed up conflicts in cpufreq/powernow-k8 that stemmed from the workqueue fixes conflicting fairly badly with the removal of support for hardware P-state chips. The changes were independent but somewhat intertwined. * tag 'pm-for-3.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (76 commits) Revert "PM QoS: Use spinlock in the per-device PM QoS constraints code" PM / Runtime: let rpm_resume() succeed if RPM_ACTIVE, even when disabled, v2 cpuidle: rename function name "__cpuidle_register_driver", v2 cpufreq: OMAP: Check IS_ERR() instead of NULL for omap_device_get_by_hwmod_name cpuidle: remove some empty lines PM: Prevent runtime suspend during system resume PM QoS: Use spinlock in the per-device PM QoS constraints code PM / Sleep: use resume event when call dpm_resume_early cpuidle / ACPI : move cpuidle_device field out of the acpi_processor_power structure ACPI / processor: remove pointless variable initialization ACPI / processor: remove unused function parameter cpufreq: OMAP: remove loops_per_jiffy recalculate for smp sections: fix section conflicts in drivers/cpufreq cpufreq: conservative: update frequency when limits are relaxed cpufreq / ondemand: update frequency when limits are relaxed properly __init-annotate pm_sysrq_init() cpufreq: Add a generic cpufreq-cpu0 driver PM / OPP: Initialize OPP table from device tree ARM: add cpufreq transiton notifier to adjust loops_per_jiffy for smp cpufreq: Remove support for hardware P-state chips from powernow-k8 ...
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/processor_driver.c8
-rw-r--r--drivers/acpi/processor_idle.c40
-rw-r--r--drivers/acpi/processor_perflib.c30
3 files changed, 59 insertions, 19 deletions
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index bfc31cb0dd3e..e78c2a52ea46 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -475,7 +475,7 @@ static __ref int acpi_processor_start(struct acpi_processor *pr)
475 acpi_processor_get_limit_info(pr); 475 acpi_processor_get_limit_info(pr);
476 476
477 if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver) 477 if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver)
478 acpi_processor_power_init(pr, device); 478 acpi_processor_power_init(pr);
479 479
480 pr->cdev = thermal_cooling_device_register("Processor", device, 480 pr->cdev = thermal_cooling_device_register("Processor", device,
481 &processor_cooling_ops); 481 &processor_cooling_ops);
@@ -509,7 +509,7 @@ err_remove_sysfs_thermal:
509err_thermal_unregister: 509err_thermal_unregister:
510 thermal_cooling_device_unregister(pr->cdev); 510 thermal_cooling_device_unregister(pr->cdev);
511err_power_exit: 511err_power_exit:
512 acpi_processor_power_exit(pr, device); 512 acpi_processor_power_exit(pr);
513 513
514 return result; 514 return result;
515} 515}
@@ -620,7 +620,7 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
620 return -EINVAL; 620 return -EINVAL;
621 } 621 }
622 622
623 acpi_processor_power_exit(pr, device); 623 acpi_processor_power_exit(pr);
624 624
625 sysfs_remove_link(&device->dev.kobj, "sysdev"); 625 sysfs_remove_link(&device->dev.kobj, "sysdev");
626 626
@@ -905,8 +905,6 @@ static int __init acpi_processor_init(void)
905 if (acpi_disabled) 905 if (acpi_disabled)
906 return 0; 906 return 0;
907 907
908 memset(&errata, 0, sizeof(errata));
909
910 result = acpi_bus_register_driver(&acpi_processor_driver); 908 result = acpi_bus_register_driver(&acpi_processor_driver);
911 if (result < 0) 909 if (result < 0)
912 return result; 910 return result;
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index ad3730b4038b..3655ab923812 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -79,6 +79,8 @@ module_param(bm_check_disable, uint, 0000);
79static unsigned int latency_factor __read_mostly = 2; 79static unsigned int latency_factor __read_mostly = 2;
80module_param(latency_factor, uint, 0644); 80module_param(latency_factor, uint, 0644);
81 81
82static DEFINE_PER_CPU(struct cpuidle_device *, acpi_cpuidle_device);
83
82static int disabled_by_idle_boot_param(void) 84static int disabled_by_idle_boot_param(void)
83{ 85{
84 return boot_option_idle_override == IDLE_POLL || 86 return boot_option_idle_override == IDLE_POLL ||
@@ -483,8 +485,6 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
483 if (obj->type != ACPI_TYPE_INTEGER) 485 if (obj->type != ACPI_TYPE_INTEGER)
484 continue; 486 continue;
485 487
486 cx.power = obj->integer.value;
487
488 current_count++; 488 current_count++;
489 memcpy(&(pr->power.states[current_count]), &cx, sizeof(cx)); 489 memcpy(&(pr->power.states[current_count]), &cx, sizeof(cx));
490 490
@@ -1000,7 +1000,7 @@ static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr)
1000 int i, count = CPUIDLE_DRIVER_STATE_START; 1000 int i, count = CPUIDLE_DRIVER_STATE_START;
1001 struct acpi_processor_cx *cx; 1001 struct acpi_processor_cx *cx;
1002 struct cpuidle_state_usage *state_usage; 1002 struct cpuidle_state_usage *state_usage;
1003 struct cpuidle_device *dev = &pr->power.dev; 1003 struct cpuidle_device *dev = per_cpu(acpi_cpuidle_device, pr->id);
1004 1004
1005 if (!pr->flags.power_setup_done) 1005 if (!pr->flags.power_setup_done)
1006 return -EINVAL; 1006 return -EINVAL;
@@ -1132,6 +1132,7 @@ static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr)
1132int acpi_processor_hotplug(struct acpi_processor *pr) 1132int acpi_processor_hotplug(struct acpi_processor *pr)
1133{ 1133{
1134 int ret = 0; 1134 int ret = 0;
1135 struct cpuidle_device *dev = per_cpu(acpi_cpuidle_device, pr->id);
1135 1136
1136 if (disabled_by_idle_boot_param()) 1137 if (disabled_by_idle_boot_param())
1137 return 0; 1138 return 0;
@@ -1147,11 +1148,11 @@ int acpi_processor_hotplug(struct acpi_processor *pr)
1147 return -ENODEV; 1148 return -ENODEV;
1148 1149
1149 cpuidle_pause_and_lock(); 1150 cpuidle_pause_and_lock();
1150 cpuidle_disable_device(&pr->power.dev); 1151 cpuidle_disable_device(dev);
1151 acpi_processor_get_power_info(pr); 1152 acpi_processor_get_power_info(pr);
1152 if (pr->flags.power) { 1153 if (pr->flags.power) {
1153 acpi_processor_setup_cpuidle_cx(pr); 1154 acpi_processor_setup_cpuidle_cx(pr);
1154 ret = cpuidle_enable_device(&pr->power.dev); 1155 ret = cpuidle_enable_device(dev);
1155 } 1156 }
1156 cpuidle_resume_and_unlock(); 1157 cpuidle_resume_and_unlock();
1157 1158
@@ -1162,6 +1163,7 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
1162{ 1163{
1163 int cpu; 1164 int cpu;
1164 struct acpi_processor *_pr; 1165 struct acpi_processor *_pr;
1166 struct cpuidle_device *dev;
1165 1167
1166 if (disabled_by_idle_boot_param()) 1168 if (disabled_by_idle_boot_param())
1167 return 0; 1169 return 0;
@@ -1192,7 +1194,8 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
1192 _pr = per_cpu(processors, cpu); 1194 _pr = per_cpu(processors, cpu);
1193 if (!_pr || !_pr->flags.power_setup_done) 1195 if (!_pr || !_pr->flags.power_setup_done)
1194 continue; 1196 continue;
1195 cpuidle_disable_device(&_pr->power.dev); 1197 dev = per_cpu(acpi_cpuidle_device, cpu);
1198 cpuidle_disable_device(dev);
1196 } 1199 }
1197 1200
1198 /* Populate Updated C-state information */ 1201 /* Populate Updated C-state information */
@@ -1206,7 +1209,8 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
1206 acpi_processor_get_power_info(_pr); 1209 acpi_processor_get_power_info(_pr);
1207 if (_pr->flags.power) { 1210 if (_pr->flags.power) {
1208 acpi_processor_setup_cpuidle_cx(_pr); 1211 acpi_processor_setup_cpuidle_cx(_pr);
1209 cpuidle_enable_device(&_pr->power.dev); 1212 dev = per_cpu(acpi_cpuidle_device, cpu);
1213 cpuidle_enable_device(dev);
1210 } 1214 }
1211 } 1215 }
1212 put_online_cpus(); 1216 put_online_cpus();
@@ -1218,11 +1222,11 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
1218 1222
1219static int acpi_processor_registered; 1223static int acpi_processor_registered;
1220 1224
1221int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, 1225int __cpuinit acpi_processor_power_init(struct acpi_processor *pr)
1222 struct acpi_device *device)
1223{ 1226{
1224 acpi_status status = 0; 1227 acpi_status status = 0;
1225 int retval; 1228 int retval;
1229 struct cpuidle_device *dev;
1226 static int first_run; 1230 static int first_run;
1227 1231
1228 if (disabled_by_idle_boot_param()) 1232 if (disabled_by_idle_boot_param())
@@ -1268,11 +1272,18 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
1268 printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", 1272 printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n",
1269 acpi_idle_driver.name); 1273 acpi_idle_driver.name);
1270 } 1274 }
1275
1276 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1277 if (!dev)
1278 return -ENOMEM;
1279 per_cpu(acpi_cpuidle_device, pr->id) = dev;
1280
1281 acpi_processor_setup_cpuidle_cx(pr);
1282
1271 /* Register per-cpu cpuidle_device. Cpuidle driver 1283 /* Register per-cpu cpuidle_device. Cpuidle driver
1272 * must already be registered before registering device 1284 * must already be registered before registering device
1273 */ 1285 */
1274 acpi_processor_setup_cpuidle_cx(pr); 1286 retval = cpuidle_register_device(dev);
1275 retval = cpuidle_register_device(&pr->power.dev);
1276 if (retval) { 1287 if (retval) {
1277 if (acpi_processor_registered == 0) 1288 if (acpi_processor_registered == 0)
1278 cpuidle_unregister_driver(&acpi_idle_driver); 1289 cpuidle_unregister_driver(&acpi_idle_driver);
@@ -1283,14 +1294,15 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
1283 return 0; 1294 return 0;
1284} 1295}
1285 1296
1286int acpi_processor_power_exit(struct acpi_processor *pr, 1297int acpi_processor_power_exit(struct acpi_processor *pr)
1287 struct acpi_device *device)
1288{ 1298{
1299 struct cpuidle_device *dev = per_cpu(acpi_cpuidle_device, pr->id);
1300
1289 if (disabled_by_idle_boot_param()) 1301 if (disabled_by_idle_boot_param())
1290 return 0; 1302 return 0;
1291 1303
1292 if (pr->flags.power) { 1304 if (pr->flags.power) {
1293 cpuidle_unregister_device(&pr->power.dev); 1305 cpuidle_unregister_device(dev);
1294 acpi_processor_registered--; 1306 acpi_processor_registered--;
1295 if (acpi_processor_registered == 0) 1307 if (acpi_processor_registered == 0)
1296 cpuidle_unregister_driver(&acpi_idle_driver); 1308 cpuidle_unregister_driver(&acpi_idle_driver);
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index a093dc163a42..836bfe069042 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -324,6 +324,34 @@ static int acpi_processor_get_performance_control(struct acpi_processor *pr)
324 return result; 324 return result;
325} 325}
326 326
327#ifdef CONFIG_X86
328/*
329 * Some AMDs have 50MHz frequency multiples, but only provide 100MHz rounding
330 * in their ACPI data. Calculate the real values and fix up the _PSS data.
331 */
332static void amd_fixup_frequency(struct acpi_processor_px *px, int i)
333{
334 u32 hi, lo, fid, did;
335 int index = px->control & 0x00000007;
336
337 if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
338 return;
339
340 if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10)
341 || boot_cpu_data.x86 == 0x11) {
342 rdmsr(MSR_AMD_PSTATE_DEF_BASE + index, lo, hi);
343 fid = lo & 0x3f;
344 did = (lo >> 6) & 7;
345 if (boot_cpu_data.x86 == 0x10)
346 px->core_frequency = (100 * (fid + 0x10)) >> did;
347 else
348 px->core_frequency = (100 * (fid + 8)) >> did;
349 }
350}
351#else
352static void amd_fixup_frequency(struct acpi_processor_px *px, int i) {};
353#endif
354
327static int acpi_processor_get_performance_states(struct acpi_processor *pr) 355static int acpi_processor_get_performance_states(struct acpi_processor *pr)
328{ 356{
329 int result = 0; 357 int result = 0;
@@ -379,6 +407,8 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr)
379 goto end; 407 goto end;
380 } 408 }
381 409
410 amd_fixup_frequency(px, i);
411
382 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 412 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
383 "State [%d]: core_frequency[%d] power[%d] transition_latency[%d] bus_master_latency[%d] control[0x%x] status[0x%x]\n", 413 "State [%d]: core_frequency[%d] power[%d] transition_latency[%d] bus_master_latency[%d] control[0x%x] status[0x%x]\n",
384 i, 414 i,