summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-05-06 16:08:46 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-05-06 16:08:46 -0400
commitfd7c3c29f9abab50a84fd4fd6811129641c53b2f (patch)
tree907eb7ac29bdd4ab44f0e09bda8d54517cb4ebdb
parent625fe4f8ffc1b915248558481bb94249f6bd411c (diff)
parente93e59ce5b85e6c2b444f09fd1f707274ec066dc (diff)
Merge back new cpuidle material for v4.7.
-rw-r--r--arch/arm/include/asm/cpuidle.h2
-rw-r--r--arch/arm/kernel/cpuidle.c6
-rw-r--r--drivers/cpuidle/cpuidle.c14
-rw-r--r--drivers/firmware/psci.c2
-rw-r--r--drivers/idle/intel_idle.c137
-rw-r--r--drivers/soc/qcom/spm.c2
6 files changed, 153 insertions, 10 deletions
diff --git a/arch/arm/include/asm/cpuidle.h b/arch/arm/include/asm/cpuidle.h
index 3848259bebf8..baefe1d51517 100644
--- a/arch/arm/include/asm/cpuidle.h
+++ b/arch/arm/include/asm/cpuidle.h
@@ -36,7 +36,7 @@ struct cpuidle_ops {
36 36
37struct of_cpuidle_method { 37struct of_cpuidle_method {
38 const char *method; 38 const char *method;
39 struct cpuidle_ops *ops; 39 const struct cpuidle_ops *ops;
40}; 40};
41 41
42#define CPUIDLE_METHOD_OF_DECLARE(name, _method, _ops) \ 42#define CPUIDLE_METHOD_OF_DECLARE(name, _method, _ops) \
diff --git a/arch/arm/kernel/cpuidle.c b/arch/arm/kernel/cpuidle.c
index 703926e7007b..a44b268e12e1 100644
--- a/arch/arm/kernel/cpuidle.c
+++ b/arch/arm/kernel/cpuidle.c
@@ -70,7 +70,7 @@ int arm_cpuidle_suspend(int index)
70 * 70 *
71 * Returns a struct cpuidle_ops pointer, NULL if not found. 71 * Returns a struct cpuidle_ops pointer, NULL if not found.
72 */ 72 */
73static struct cpuidle_ops *__init arm_cpuidle_get_ops(const char *method) 73static const struct cpuidle_ops *__init arm_cpuidle_get_ops(const char *method)
74{ 74{
75 struct of_cpuidle_method *m = __cpuidle_method_of_table; 75 struct of_cpuidle_method *m = __cpuidle_method_of_table;
76 76
@@ -88,7 +88,7 @@ static struct cpuidle_ops *__init arm_cpuidle_get_ops(const char *method)
88 * 88 *
89 * Get the method name defined in the 'enable-method' property, retrieve the 89 * Get the method name defined in the 'enable-method' property, retrieve the
90 * associated cpuidle_ops and do a struct copy. This copy is needed because all 90 * associated cpuidle_ops and do a struct copy. This copy is needed because all
91 * cpuidle_ops are tagged __initdata and will be unloaded after the init 91 * cpuidle_ops are tagged __initconst and will be unloaded after the init
92 * process. 92 * process.
93 * 93 *
94 * Return 0 on sucess, -ENOENT if no 'enable-method' is defined, -EOPNOTSUPP if 94 * Return 0 on sucess, -ENOENT if no 'enable-method' is defined, -EOPNOTSUPP if
@@ -97,7 +97,7 @@ static struct cpuidle_ops *__init arm_cpuidle_get_ops(const char *method)
97static int __init arm_cpuidle_read_ops(struct device_node *dn, int cpu) 97static int __init arm_cpuidle_read_ops(struct device_node *dn, int cpu)
98{ 98{
99 const char *enable_method; 99 const char *enable_method;
100 struct cpuidle_ops *ops; 100 const struct cpuidle_ops *ops;
101 101
102 enable_method = of_get_property(dn, "enable-method", NULL); 102 enable_method = of_get_property(dn, "enable-method", NULL);
103 if (!enable_method) 103 if (!enable_method)
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index f996efc56605..2b8e6ce62e81 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -173,7 +173,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
173 173
174 struct cpuidle_state *target_state = &drv->states[index]; 174 struct cpuidle_state *target_state = &drv->states[index];
175 bool broadcast = !!(target_state->flags & CPUIDLE_FLAG_TIMER_STOP); 175 bool broadcast = !!(target_state->flags & CPUIDLE_FLAG_TIMER_STOP);
176 ktime_t time_start, time_end; 176 u64 time_start, time_end;
177 s64 diff; 177 s64 diff;
178 178
179 /* 179 /*
@@ -195,13 +195,13 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
195 sched_idle_set_state(target_state); 195 sched_idle_set_state(target_state);
196 196
197 trace_cpu_idle_rcuidle(index, dev->cpu); 197 trace_cpu_idle_rcuidle(index, dev->cpu);
198 time_start = ktime_get(); 198 time_start = local_clock();
199 199
200 stop_critical_timings(); 200 stop_critical_timings();
201 entered_state = target_state->enter(dev, drv, index); 201 entered_state = target_state->enter(dev, drv, index);
202 start_critical_timings(); 202 start_critical_timings();
203 203
204 time_end = ktime_get(); 204 time_end = local_clock();
205 trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu); 205 trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);
206 206
207 /* The cpu is no longer idle or about to enter idle. */ 207 /* The cpu is no longer idle or about to enter idle. */
@@ -217,7 +217,11 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
217 if (!cpuidle_state_is_coupled(drv, entered_state)) 217 if (!cpuidle_state_is_coupled(drv, entered_state))
218 local_irq_enable(); 218 local_irq_enable();
219 219
220 diff = ktime_to_us(ktime_sub(time_end, time_start)); 220 /*
221 * local_clock() returns the time in nanosecond, let's shift
222 * by 10 (divide by 1024) to have microsecond based time.
223 */
224 diff = (time_end - time_start) >> 10;
221 if (diff > INT_MAX) 225 if (diff > INT_MAX)
222 diff = INT_MAX; 226 diff = INT_MAX;
223 227
@@ -433,6 +437,8 @@ static void __cpuidle_unregister_device(struct cpuidle_device *dev)
433 list_del(&dev->device_list); 437 list_del(&dev->device_list);
434 per_cpu(cpuidle_devices, dev->cpu) = NULL; 438 per_cpu(cpuidle_devices, dev->cpu) = NULL;
435 module_put(drv->owner); 439 module_put(drv->owner);
440
441 dev->registered = 0;
436} 442}
437 443
438static void __cpuidle_device_init(struct cpuidle_device *dev) 444static void __cpuidle_device_init(struct cpuidle_device *dev)
diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
index 11bfee8b79a9..eb8134a148c0 100644
--- a/drivers/firmware/psci.c
+++ b/drivers/firmware/psci.c
@@ -355,7 +355,7 @@ int psci_cpu_suspend_enter(unsigned long index)
355 355
356/* ARM specific CPU idle operations */ 356/* ARM specific CPU idle operations */
357#ifdef CONFIG_ARM 357#ifdef CONFIG_ARM
358static struct cpuidle_ops psci_cpuidle_ops __initdata = { 358static const struct cpuidle_ops psci_cpuidle_ops __initconst = {
359 .suspend = psci_cpu_suspend_enter, 359 .suspend = psci_cpu_suspend_enter,
360 .init = psci_dt_cpu_init_idle, 360 .init = psci_dt_cpu_init_idle,
361}; 361};
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index c6935de425fa..c96649292b55 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -766,6 +766,67 @@ static struct cpuidle_state knl_cstates[] = {
766 .enter = NULL } 766 .enter = NULL }
767}; 767};
768 768
769static struct cpuidle_state bxt_cstates[] = {
770 {
771 .name = "C1-BXT",
772 .desc = "MWAIT 0x00",
773 .flags = MWAIT2flg(0x00),
774 .exit_latency = 2,
775 .target_residency = 2,
776 .enter = &intel_idle,
777 .enter_freeze = intel_idle_freeze, },
778 {
779 .name = "C1E-BXT",
780 .desc = "MWAIT 0x01",
781 .flags = MWAIT2flg(0x01),
782 .exit_latency = 10,
783 .target_residency = 20,
784 .enter = &intel_idle,
785 .enter_freeze = intel_idle_freeze, },
786 {
787 .name = "C6-BXT",
788 .desc = "MWAIT 0x20",
789 .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
790 .exit_latency = 133,
791 .target_residency = 133,
792 .enter = &intel_idle,
793 .enter_freeze = intel_idle_freeze, },
794 {
795 .name = "C7s-BXT",
796 .desc = "MWAIT 0x31",
797 .flags = MWAIT2flg(0x31) | CPUIDLE_FLAG_TLB_FLUSHED,
798 .exit_latency = 155,
799 .target_residency = 155,
800 .enter = &intel_idle,
801 .enter_freeze = intel_idle_freeze, },
802 {
803 .name = "C8-BXT",
804 .desc = "MWAIT 0x40",
805 .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED,
806 .exit_latency = 1000,
807 .target_residency = 1000,
808 .enter = &intel_idle,
809 .enter_freeze = intel_idle_freeze, },
810 {
811 .name = "C9-BXT",
812 .desc = "MWAIT 0x50",
813 .flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED,
814 .exit_latency = 2000,
815 .target_residency = 2000,
816 .enter = &intel_idle,
817 .enter_freeze = intel_idle_freeze, },
818 {
819 .name = "C10-BXT",
820 .desc = "MWAIT 0x60",
821 .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED,
822 .exit_latency = 10000,
823 .target_residency = 10000,
824 .enter = &intel_idle,
825 .enter_freeze = intel_idle_freeze, },
826 {
827 .enter = NULL }
828};
829
769/** 830/**
770 * intel_idle 831 * intel_idle
771 * @dev: cpuidle_device 832 * @dev: cpuidle_device
@@ -950,6 +1011,11 @@ static const struct idle_cpu idle_cpu_knl = {
950 .state_table = knl_cstates, 1011 .state_table = knl_cstates,
951}; 1012};
952 1013
1014static const struct idle_cpu idle_cpu_bxt = {
1015 .state_table = bxt_cstates,
1016 .disable_promotion_to_c1e = true,
1017};
1018
953#define ICPU(model, cpu) \ 1019#define ICPU(model, cpu) \
954 { X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (unsigned long)&cpu } 1020 { X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (unsigned long)&cpu }
955 1021
@@ -985,6 +1051,7 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = {
985 ICPU(0x9e, idle_cpu_skl), 1051 ICPU(0x9e, idle_cpu_skl),
986 ICPU(0x55, idle_cpu_skx), 1052 ICPU(0x55, idle_cpu_skx),
987 ICPU(0x57, idle_cpu_knl), 1053 ICPU(0x57, idle_cpu_knl),
1054 ICPU(0x5c, idle_cpu_bxt),
988 {} 1055 {}
989}; 1056};
990MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids); 1057MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids);
@@ -1075,6 +1142,73 @@ static void ivt_idle_state_table_update(void)
1075 1142
1076 /* else, 1 and 2 socket systems use default ivt_cstates */ 1143 /* else, 1 and 2 socket systems use default ivt_cstates */
1077} 1144}
1145
1146/*
1147 * Translate IRTL (Interrupt Response Time Limit) MSR to usec
1148 */
1149
1150static unsigned int irtl_ns_units[] = {
1151 1, 32, 1024, 32768, 1048576, 33554432, 0, 0 };
1152
1153static unsigned long long irtl_2_usec(unsigned long long irtl)
1154{
1155 unsigned long long ns;
1156
1157 ns = irtl_ns_units[(irtl >> 10) & 0x3];
1158
1159 return div64_u64((irtl & 0x3FF) * ns, 1000);
1160}
1161/*
1162 * bxt_idle_state_table_update(void)
1163 *
1164 * On BXT, we trust the IRTL to show the definitive maximum latency
1165 * We use the same value for target_residency.
1166 */
1167static void bxt_idle_state_table_update(void)
1168{
1169 unsigned long long msr;
1170
1171 rdmsrl(MSR_PKGC6_IRTL, msr);
1172 if (msr) {
1173 unsigned int usec = irtl_2_usec(msr);
1174
1175 bxt_cstates[2].exit_latency = usec;
1176 bxt_cstates[2].target_residency = usec;
1177 }
1178
1179 rdmsrl(MSR_PKGC7_IRTL, msr);
1180 if (msr) {
1181 unsigned int usec = irtl_2_usec(msr);
1182
1183 bxt_cstates[3].exit_latency = usec;
1184 bxt_cstates[3].target_residency = usec;
1185 }
1186
1187 rdmsrl(MSR_PKGC8_IRTL, msr);
1188 if (msr) {
1189 unsigned int usec = irtl_2_usec(msr);
1190
1191 bxt_cstates[4].exit_latency = usec;
1192 bxt_cstates[4].target_residency = usec;
1193 }
1194
1195 rdmsrl(MSR_PKGC9_IRTL, msr);
1196 if (msr) {
1197 unsigned int usec = irtl_2_usec(msr);
1198
1199 bxt_cstates[5].exit_latency = usec;
1200 bxt_cstates[5].target_residency = usec;
1201 }
1202
1203 rdmsrl(MSR_PKGC10_IRTL, msr);
1204 if (msr) {
1205 unsigned int usec = irtl_2_usec(msr);
1206
1207 bxt_cstates[6].exit_latency = usec;
1208 bxt_cstates[6].target_residency = usec;
1209 }
1210
1211}
1078/* 1212/*
1079 * sklh_idle_state_table_update(void) 1213 * sklh_idle_state_table_update(void)
1080 * 1214 *
@@ -1130,6 +1264,9 @@ static void intel_idle_state_table_update(void)
1130 case 0x3e: /* IVT */ 1264 case 0x3e: /* IVT */
1131 ivt_idle_state_table_update(); 1265 ivt_idle_state_table_update();
1132 break; 1266 break;
1267 case 0x5c: /* BXT */
1268 bxt_idle_state_table_update();
1269 break;
1133 case 0x5e: /* SKL-H */ 1270 case 0x5e: /* SKL-H */
1134 sklh_idle_state_table_update(); 1271 sklh_idle_state_table_update();
1135 break; 1272 break;
diff --git a/drivers/soc/qcom/spm.c b/drivers/soc/qcom/spm.c
index 5548a31e1a39..1fcbb22a4a1c 100644
--- a/drivers/soc/qcom/spm.c
+++ b/drivers/soc/qcom/spm.c
@@ -274,7 +274,7 @@ check_spm:
274 return per_cpu(cpu_spm_drv, cpu) ? 0 : -ENXIO; 274 return per_cpu(cpu_spm_drv, cpu) ? 0 : -ENXIO;
275} 275}
276 276
277static struct cpuidle_ops qcom_cpuidle_ops __initdata = { 277static const struct cpuidle_ops qcom_cpuidle_ops __initconst = {
278 .suspend = qcom_idle_enter, 278 .suspend = qcom_idle_enter,
279 .init = qcom_cpuidle_init, 279 .init = qcom_cpuidle_init,
280}; 280};