|
@@ -44,6 +44,7 @@
|
|
|
|
|
|
#ifdef CONFIG_ACPI
|
|
|
#include <acpi/processor.h>
|
|
|
+#include <acpi/cppc_acpi.h>
|
|
|
#endif
|
|
|
|
|
|
#define FRAC_BITS 8
|
|
@@ -379,14 +380,67 @@ static bool intel_pstate_get_ppc_enable_status(void)
|
|
|
return acpi_ppc;
|
|
|
}
|
|
|
|
|
|
+#ifdef CONFIG_ACPI_CPPC_LIB
|
|
|
+
|
|
|
+/* The work item is needed to avoid CPU hotplug locking issues */
|
|
|
+static void intel_pstste_sched_itmt_work_fn(struct work_struct *work)
|
|
|
+{
|
|
|
+ sched_set_itmt_support();
|
|
|
+}
|
|
|
+
|
|
|
+static DECLARE_WORK(sched_itmt_work, intel_pstste_sched_itmt_work_fn);
|
|
|
+
|
|
|
+static void intel_pstate_set_itmt_prio(int cpu)
|
|
|
+{
|
|
|
+ struct cppc_perf_caps cppc_perf;
|
|
|
+ static u32 max_highest_perf = 0, min_highest_perf = U32_MAX;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ ret = cppc_get_perf_caps(cpu, &cppc_perf);
|
|
|
+ if (ret)
|
|
|
+ return;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * The priorities can be set regardless of whether or not
|
|
|
+ * sched_set_itmt_support(true) has been called and it is valid to
|
|
|
+ * update them at any time after it has been called.
|
|
|
+ */
|
|
|
+ sched_set_itmt_core_prio(cppc_perf.highest_perf, cpu);
|
|
|
+
|
|
|
+ if (max_highest_perf <= min_highest_perf) {
|
|
|
+ if (cppc_perf.highest_perf > max_highest_perf)
|
|
|
+ max_highest_perf = cppc_perf.highest_perf;
|
|
|
+
|
|
|
+ if (cppc_perf.highest_perf < min_highest_perf)
|
|
|
+ min_highest_perf = cppc_perf.highest_perf;
|
|
|
+
|
|
|
+ if (max_highest_perf > min_highest_perf) {
|
|
|
+ /*
|
|
|
+ * This code can be run during CPU online under the
|
|
|
+ * CPU hotplug locks, so sched_set_itmt_support()
|
|
|
+ * cannot be called from here. Queue up a work item
|
|
|
+ * to invoke it.
|
|
|
+ */
|
|
|
+ schedule_work(&sched_itmt_work);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+#else
|
|
|
+static void intel_pstate_set_itmt_prio(int cpu)
|
|
|
+{
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
static void intel_pstate_init_acpi_perf_limits(struct cpufreq_policy *policy)
|
|
|
{
|
|
|
struct cpudata *cpu;
|
|
|
int ret;
|
|
|
int i;
|
|
|
|
|
|
- if (hwp_active)
|
|
|
+ if (hwp_active) {
|
|
|
+ intel_pstate_set_itmt_prio(policy->cpu);
|
|
|
return;
|
|
|
+ }
|
|
|
|
|
|
if (!intel_pstate_get_ppc_enable_status())
|
|
|
return;
|