aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorDeepthi Dharwar <deepthi@linux.vnet.ibm.com>2011-10-28 06:50:42 -0400
committerLen Brown <len.brown@intel.com>2011-11-06 21:13:58 -0500
commit46bcfad7a819bd17ac4e831b04405152d59784ab (patch)
tree20041e788154d103edff2699f88d4a30320e3ee2 /drivers/acpi
parent4202735e8ab6ecfb0381631a0d0b58fefe0bd4e2 (diff)
cpuidle: Single/Global registration of idle states
This patch makes the cpuidle_states structure global (single copy) instead of per-cpu. The statistics needed on per-cpu basis by the governor are kept per-cpu. This simplifies the cpuidle subsystem as state registration is done by single cpu only. Having single copy of cpuidle_states saves memory. Rare case of asymmetric C-states can be handled within the cpuidle driver and architectures such as POWER do not have asymmetric C-states. Having single/global registration of all the idle states, dynamic C-state transitions on x86 are handled by the boot cpu. Here, the boot cpu would disable all the devices, re-populate the states and later enable all the devices, irrespective of the cpu that would receive the notification first. Reference: https://lkml.org/lkml/2011/4/25/83 Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com> Signed-off-by: Trinabh Gupta <g.trinabh@gmail.com> Tested-by: Jean Pihet <j-pihet@ti.com> Reviewed-by: Kevin Hilman <khilman@ti.com> Acked-by: Arjan van de Ven <arjan@linux.intel.com> Acked-by: Kevin Hilman <khilman@ti.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/processor_driver.c20
-rw-r--r--drivers/acpi/processor_idle.c191
2 files changed, 169 insertions, 42 deletions
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index a4e0f1ba6040..9d7bc9f6b6cc 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -426,7 +426,7 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb,
426 426
427 if (action == CPU_ONLINE && pr) { 427 if (action == CPU_ONLINE && pr) {
428 acpi_processor_ppc_has_changed(pr, 0); 428 acpi_processor_ppc_has_changed(pr, 0);
429 acpi_processor_cst_has_changed(pr); 429 acpi_processor_hotplug(pr);
430 acpi_processor_reevaluate_tstate(pr, action); 430 acpi_processor_reevaluate_tstate(pr, action);
431 acpi_processor_tstate_has_changed(pr); 431 acpi_processor_tstate_has_changed(pr);
432 } 432 }
@@ -503,8 +503,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
503 acpi_processor_get_throttling_info(pr); 503 acpi_processor_get_throttling_info(pr);
504 acpi_processor_get_limit_info(pr); 504 acpi_processor_get_limit_info(pr);
505 505
506 506 if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver)
507 if (cpuidle_get_driver() == &acpi_idle_driver)
508 acpi_processor_power_init(pr, device); 507 acpi_processor_power_init(pr, device);
509 508
510 pr->cdev = thermal_cooling_device_register("Processor", device, 509 pr->cdev = thermal_cooling_device_register("Processor", device,
@@ -800,17 +799,9 @@ static int __init acpi_processor_init(void)
800 799
801 memset(&errata, 0, sizeof(errata)); 800 memset(&errata, 0, sizeof(errata));
802 801
803 if (!cpuidle_register_driver(&acpi_idle_driver)) {
804 printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n",
805 acpi_idle_driver.name);
806 } else {
807 printk(KERN_DEBUG "ACPI: acpi_idle yielding to %s\n",
808 cpuidle_get_driver()->name);
809 }
810
811 result = acpi_bus_register_driver(&acpi_processor_driver); 802 result = acpi_bus_register_driver(&acpi_processor_driver);
812 if (result < 0) 803 if (result < 0)
813 goto out_cpuidle; 804 return result;
814 805
815 acpi_processor_install_hotplug_notify(); 806 acpi_processor_install_hotplug_notify();
816 807
@@ -821,11 +812,6 @@ static int __init acpi_processor_init(void)
821 acpi_processor_throttling_init(); 812 acpi_processor_throttling_init();
822 813
823 return 0; 814 return 0;
824
825out_cpuidle:
826 cpuidle_unregister_driver(&acpi_idle_driver);
827
828 return result;
829} 815}
830 816
831static void __exit acpi_processor_exit(void) 817static void __exit acpi_processor_exit(void)
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index b98c75285690..24fe3afa7119 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -741,11 +741,13 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx)
741/** 741/**
742 * acpi_idle_enter_c1 - enters an ACPI C1 state-type 742 * acpi_idle_enter_c1 - enters an ACPI C1 state-type
743 * @dev: the target CPU 743 * @dev: the target CPU
744 * @drv: cpuidle driver containing cpuidle state info
744 * @index: index of target state 745 * @index: index of target state
745 * 746 *
746 * This is equivalent to the HALT instruction. 747 * This is equivalent to the HALT instruction.
747 */ 748 */
748static int acpi_idle_enter_c1(struct cpuidle_device *dev, int index) 749static int acpi_idle_enter_c1(struct cpuidle_device *dev,
750 struct cpuidle_driver *drv, int index)
749{ 751{
750 ktime_t kt1, kt2; 752 ktime_t kt1, kt2;
751 s64 idle_time; 753 s64 idle_time;
@@ -787,9 +789,11 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, int index)
787/** 789/**
788 * acpi_idle_enter_simple - enters an ACPI state without BM handling 790 * acpi_idle_enter_simple - enters an ACPI state without BM handling
789 * @dev: the target CPU 791 * @dev: the target CPU
792 * @drv: cpuidle driver with cpuidle state information
790 * @index: the index of suggested state 793 * @index: the index of suggested state
791 */ 794 */
792static int acpi_idle_enter_simple(struct cpuidle_device *dev, int index) 795static int acpi_idle_enter_simple(struct cpuidle_device *dev,
796 struct cpuidle_driver *drv, int index)
793{ 797{
794 struct acpi_processor *pr; 798 struct acpi_processor *pr;
795 struct cpuidle_state_usage *state_usage = &dev->states_usage[index]; 799 struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
@@ -869,11 +873,13 @@ static DEFINE_SPINLOCK(c3_lock);
869/** 873/**
870 * acpi_idle_enter_bm - enters C3 with proper BM handling 874 * acpi_idle_enter_bm - enters C3 with proper BM handling
871 * @dev: the target CPU 875 * @dev: the target CPU
876 * @drv: cpuidle driver containing state data
872 * @index: the index of suggested state 877 * @index: the index of suggested state
873 * 878 *
874 * If BM is detected, the deepest non-C3 idle state is entered instead. 879 * If BM is detected, the deepest non-C3 idle state is entered instead.
875 */ 880 */
876static int acpi_idle_enter_bm(struct cpuidle_device *dev, int index) 881static int acpi_idle_enter_bm(struct cpuidle_device *dev,
882 struct cpuidle_driver *drv, int index)
877{ 883{
878 struct acpi_processor *pr; 884 struct acpi_processor *pr;
879 struct cpuidle_state_usage *state_usage = &dev->states_usage[index]; 885 struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
@@ -896,9 +902,9 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, int index)
896 } 902 }
897 903
898 if (!cx->bm_sts_skip && acpi_idle_bm_check()) { 904 if (!cx->bm_sts_skip && acpi_idle_bm_check()) {
899 if (dev->safe_state_index >= 0) { 905 if (drv->safe_state_index >= 0) {
900 return dev->states[dev->safe_state_index].enter(dev, 906 return drv->states[drv->safe_state_index].enter(dev,
901 dev->safe_state_index); 907 drv, drv->safe_state_index);
902 } else { 908 } else {
903 local_irq_disable(); 909 local_irq_disable();
904 acpi_safe_halt(); 910 acpi_safe_halt();
@@ -993,14 +999,15 @@ struct cpuidle_driver acpi_idle_driver = {
993}; 999};
994 1000
995/** 1001/**
996 * acpi_processor_setup_cpuidle - prepares and configures CPUIDLE 1002 * acpi_processor_setup_cpuidle_cx - prepares and configures CPUIDLE
1003 * device i.e. per-cpu data
1004 *
997 * @pr: the ACPI processor 1005 * @pr: the ACPI processor
998 */ 1006 */
999static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) 1007static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr)
1000{ 1008{
1001 int i, count = CPUIDLE_DRIVER_STATE_START; 1009 int i, count = CPUIDLE_DRIVER_STATE_START;
1002 struct acpi_processor_cx *cx; 1010 struct acpi_processor_cx *cx;
1003 struct cpuidle_state *state;
1004 struct cpuidle_state_usage *state_usage; 1011 struct cpuidle_state_usage *state_usage;
1005 struct cpuidle_device *dev = &pr->power.dev; 1012 struct cpuidle_device *dev = &pr->power.dev;
1006 1013
@@ -1012,18 +1019,12 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
1012 } 1019 }
1013 1020
1014 dev->cpu = pr->id; 1021 dev->cpu = pr->id;
1015 dev->safe_state_index = -1;
1016 for (i = 0; i < CPUIDLE_STATE_MAX; i++) {
1017 dev->states[i].name[0] = '\0';
1018 dev->states[i].desc[0] = '\0';
1019 }
1020 1022
1021 if (max_cstate == 0) 1023 if (max_cstate == 0)
1022 max_cstate = 1; 1024 max_cstate = 1;
1023 1025
1024 for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) { 1026 for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) {
1025 cx = &pr->power.states[i]; 1027 cx = &pr->power.states[i];
1026 state = &dev->states[count];
1027 state_usage = &dev->states_usage[count]; 1028 state_usage = &dev->states_usage[count];
1028 1029
1029 if (!cx->valid) 1030 if (!cx->valid)
@@ -1035,8 +1036,64 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
1035 !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) 1036 !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
1036 continue; 1037 continue;
1037#endif 1038#endif
1039
1038 cpuidle_set_statedata(state_usage, cx); 1040 cpuidle_set_statedata(state_usage, cx);
1039 1041
1042 count++;
1043 if (count == CPUIDLE_STATE_MAX)
1044 break;
1045 }
1046
1047 dev->state_count = count;
1048
1049 if (!count)
1050 return -EINVAL;
1051
1052 return 0;
1053}
1054
1055/**
1056 * acpi_processor_setup_cpuidle states- prepares and configures cpuidle
1057 * global state data i.e. idle routines
1058 *
1059 * @pr: the ACPI processor
1060 */
1061static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr)
1062{
1063 int i, count = CPUIDLE_DRIVER_STATE_START;
1064 struct acpi_processor_cx *cx;
1065 struct cpuidle_state *state;
1066 struct cpuidle_driver *drv = &acpi_idle_driver;
1067
1068 if (!pr->flags.power_setup_done)
1069 return -EINVAL;
1070
1071 if (pr->flags.power == 0)
1072 return -EINVAL;
1073
1074 drv->safe_state_index = -1;
1075 for (i = 0; i < CPUIDLE_STATE_MAX; i++) {
1076 drv->states[i].name[0] = '\0';
1077 drv->states[i].desc[0] = '\0';
1078 }
1079
1080 if (max_cstate == 0)
1081 max_cstate = 1;
1082
1083 for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) {
1084 cx = &pr->power.states[i];
1085
1086 if (!cx->valid)
1087 continue;
1088
1089#ifdef CONFIG_HOTPLUG_CPU
1090 if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) &&
1091 !pr->flags.has_cst &&
1092 !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
1093 continue;
1094#endif
1095
1096 state = &drv->states[count];
1040 snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", i); 1097 snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", i);
1041 strncpy(state->desc, cx->desc, CPUIDLE_DESC_LEN); 1098 strncpy(state->desc, cx->desc, CPUIDLE_DESC_LEN);
1042 state->exit_latency = cx->latency; 1099 state->exit_latency = cx->latency;
@@ -1049,13 +1106,13 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
1049 state->flags |= CPUIDLE_FLAG_TIME_VALID; 1106 state->flags |= CPUIDLE_FLAG_TIME_VALID;
1050 1107
1051 state->enter = acpi_idle_enter_c1; 1108 state->enter = acpi_idle_enter_c1;
1052 dev->safe_state_index = count; 1109 drv->safe_state_index = count;
1053 break; 1110 break;
1054 1111
1055 case ACPI_STATE_C2: 1112 case ACPI_STATE_C2:
1056 state->flags |= CPUIDLE_FLAG_TIME_VALID; 1113 state->flags |= CPUIDLE_FLAG_TIME_VALID;
1057 state->enter = acpi_idle_enter_simple; 1114 state->enter = acpi_idle_enter_simple;
1058 dev->safe_state_index = count; 1115 drv->safe_state_index = count;
1059 break; 1116 break;
1060 1117
1061 case ACPI_STATE_C3: 1118 case ACPI_STATE_C3:
@@ -1071,7 +1128,7 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
1071 break; 1128 break;
1072 } 1129 }
1073 1130
1074 dev->state_count = count; 1131 drv->state_count = count;
1075 1132
1076 if (!count) 1133 if (!count)
1077 return -EINVAL; 1134 return -EINVAL;
@@ -1079,7 +1136,7 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
1079 return 0; 1136 return 0;
1080} 1137}
1081 1138
1082int acpi_processor_cst_has_changed(struct acpi_processor *pr) 1139int acpi_processor_hotplug(struct acpi_processor *pr)
1083{ 1140{
1084 int ret = 0; 1141 int ret = 0;
1085 1142
@@ -1100,7 +1157,7 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
1100 cpuidle_disable_device(&pr->power.dev); 1157 cpuidle_disable_device(&pr->power.dev);
1101 acpi_processor_get_power_info(pr); 1158 acpi_processor_get_power_info(pr);
1102 if (pr->flags.power) { 1159 if (pr->flags.power) {
1103 acpi_processor_setup_cpuidle(pr); 1160 acpi_processor_setup_cpuidle_cx(pr);
1104 ret = cpuidle_enable_device(&pr->power.dev); 1161 ret = cpuidle_enable_device(&pr->power.dev);
1105 } 1162 }
1106 cpuidle_resume_and_unlock(); 1163 cpuidle_resume_and_unlock();
@@ -1108,10 +1165,72 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
1108 return ret; 1165 return ret;
1109} 1166}
1110 1167
1168int acpi_processor_cst_has_changed(struct acpi_processor *pr)
1169{
1170 int cpu;
1171 struct acpi_processor *_pr;
1172
1173 if (disabled_by_idle_boot_param())
1174 return 0;
1175
1176 if (!pr)
1177 return -EINVAL;
1178
1179 if (nocst)
1180 return -ENODEV;
1181
1182 if (!pr->flags.power_setup_done)
1183 return -ENODEV;
1184
1185 /*
1186 * FIXME: Design the ACPI notification to make it once per
1187 * system instead of once per-cpu. This condition is a hack
1188 * to make the code that updates C-States be called once.
1189 */
1190
1191 if (smp_processor_id() == 0 &&
1192 cpuidle_get_driver() == &acpi_idle_driver) {
1193
1194 cpuidle_pause_and_lock();
1195 /* Protect against cpu-hotplug */
1196 get_online_cpus();
1197
1198 /* Disable all cpuidle devices */
1199 for_each_online_cpu(cpu) {
1200 _pr = per_cpu(processors, cpu);
1201 if (!_pr || !_pr->flags.power_setup_done)
1202 continue;
1203 cpuidle_disable_device(&_pr->power.dev);
1204 }
1205
1206 /* Populate Updated C-state information */
1207 acpi_processor_setup_cpuidle_states(pr);
1208
1209 /* Enable all cpuidle devices */
1210 for_each_online_cpu(cpu) {
1211 _pr = per_cpu(processors, cpu);
1212 if (!_pr || !_pr->flags.power_setup_done)
1213 continue;
1214 acpi_processor_get_power_info(_pr);
1215 if (_pr->flags.power) {
1216 acpi_processor_setup_cpuidle_cx(_pr);
1217 cpuidle_enable_device(&_pr->power.dev);
1218 }
1219 }
1220 put_online_cpus();
1221 cpuidle_resume_and_unlock();
1222 }
1223
1224 return 0;
1225}
1226
1227static int acpi_processor_registered;
1228
1111int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, 1229int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
1112 struct acpi_device *device) 1230 struct acpi_device *device)
1113{ 1231{
1114 acpi_status status = 0; 1232 acpi_status status = 0;
1233 int retval;
1115 static int first_run; 1234 static int first_run;
1116 1235
1117 if (disabled_by_idle_boot_param()) 1236 if (disabled_by_idle_boot_param())
@@ -1148,9 +1267,26 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
1148 * platforms that only support C1. 1267 * platforms that only support C1.
1149 */ 1268 */
1150 if (pr->flags.power) { 1269 if (pr->flags.power) {
1151 acpi_processor_setup_cpuidle(pr); 1270 /* Register acpi_idle_driver if not already registered */
1152 if (cpuidle_register_device(&pr->power.dev)) 1271 if (!acpi_processor_registered) {
1153 return -EIO; 1272 acpi_processor_setup_cpuidle_states(pr);
1273 retval = cpuidle_register_driver(&acpi_idle_driver);
1274 if (retval)
1275 return retval;
1276 printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n",
1277 acpi_idle_driver.name);
1278 }
1279 /* Register per-cpu cpuidle_device. Cpuidle driver
1280 * must already be registered before registering device
1281 */
1282 acpi_processor_setup_cpuidle_cx(pr);
1283 retval = cpuidle_register_device(&pr->power.dev);
1284 if (retval) {
1285 if (acpi_processor_registered == 0)
1286 cpuidle_unregister_driver(&acpi_idle_driver);
1287 return retval;
1288 }
1289 acpi_processor_registered++;
1154 } 1290 }
1155 return 0; 1291 return 0;
1156} 1292}
@@ -1161,8 +1297,13 @@ int acpi_processor_power_exit(struct acpi_processor *pr,
1161 if (disabled_by_idle_boot_param()) 1297 if (disabled_by_idle_boot_param())
1162 return 0; 1298 return 0;
1163 1299
1164 cpuidle_unregister_device(&pr->power.dev); 1300 if (pr->flags.power) {
1165 pr->flags.power_setup_done = 0; 1301 cpuidle_unregister_device(&pr->power.dev);
1302 acpi_processor_registered--;
1303 if (acpi_processor_registered == 0)
1304 cpuidle_unregister_driver(&acpi_idle_driver);
1305 }
1166 1306
1307 pr->flags.power_setup_done = 0;
1167 return 0; 1308 return 0;
1168} 1309}