diff options
author | Deepthi Dharwar <deepthi@linux.vnet.ibm.com> | 2011-10-28 06:50:42 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2011-11-06 21:13:58 -0500 |
commit | 46bcfad7a819bd17ac4e831b04405152d59784ab (patch) | |
tree | 20041e788154d103edff2699f88d4a30320e3ee2 /drivers/acpi | |
parent | 4202735e8ab6ecfb0381631a0d0b58fefe0bd4e2 (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.c | 20 | ||||
-rw-r--r-- | drivers/acpi/processor_idle.c | 191 |
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 | |||
825 | out_cpuidle: | ||
826 | cpuidle_unregister_driver(&acpi_idle_driver); | ||
827 | |||
828 | return result; | ||
829 | } | 815 | } |
830 | 816 | ||
831 | static void __exit acpi_processor_exit(void) | 817 | static 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 | */ |
748 | static int acpi_idle_enter_c1(struct cpuidle_device *dev, int index) | 749 | static 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 | */ |
792 | static int acpi_idle_enter_simple(struct cpuidle_device *dev, int index) | 795 | static 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 | */ |
876 | static int acpi_idle_enter_bm(struct cpuidle_device *dev, int index) | 881 | static 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 | */ |
999 | static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) | 1007 | static 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 | */ | ||
1061 | static 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 | ||
1082 | int acpi_processor_cst_has_changed(struct acpi_processor *pr) | 1139 | int 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 | ||
1168 | int 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 | |||
1227 | static int acpi_processor_registered; | ||
1228 | |||
1111 | int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, | 1229 | int __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 | } |