Эх сурвалжийг харах

Merge cpufreq fixes going into v4.6.

* pm-cpufreq-fixes:
  intel_pstate: Fix intel_pstate_get()
  cpufreq: intel_pstate: Fix HWP on boot CPU after system resume
  cpufreq: st: enable selective initialization based on the platform
  cpufreq: intel_pstate: Fix processing for turbo activation ratio
Rafael J. Wysocki 9 жил өмнө
parent
commit
da43af961b

+ 15 - 11
drivers/cpufreq/cpufreq.c

@@ -1631,21 +1631,25 @@ void cpufreq_suspend(void)
 	if (!cpufreq_driver)
 	if (!cpufreq_driver)
 		return;
 		return;
 
 
-	if (!has_target())
+	if (!has_target() && !cpufreq_driver->suspend)
 		goto suspend;
 		goto suspend;
 
 
 	pr_debug("%s: Suspending Governors\n", __func__);
 	pr_debug("%s: Suspending Governors\n", __func__);
 
 
 	for_each_active_policy(policy) {
 	for_each_active_policy(policy) {
-		down_write(&policy->rwsem);
-		ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP);
-		up_write(&policy->rwsem);
+		if (has_target()) {
+			down_write(&policy->rwsem);
+			ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP);
+			up_write(&policy->rwsem);
 
 
-		if (ret)
-			pr_err("%s: Failed to stop governor for policy: %p\n",
-				__func__, policy);
-		else if (cpufreq_driver->suspend
-		    && cpufreq_driver->suspend(policy))
+			if (ret) {
+				pr_err("%s: Failed to stop governor for policy: %p\n",
+					__func__, policy);
+				continue;
+			}
+		}
+
+		if (cpufreq_driver->suspend && cpufreq_driver->suspend(policy))
 			pr_err("%s: Failed to suspend driver: %p\n", __func__,
 			pr_err("%s: Failed to suspend driver: %p\n", __func__,
 				policy);
 				policy);
 	}
 	}
@@ -1670,7 +1674,7 @@ void cpufreq_resume(void)
 
 
 	cpufreq_suspended = false;
 	cpufreq_suspended = false;
 
 
-	if (!has_target())
+	if (!has_target() && !cpufreq_driver->resume)
 		return;
 		return;
 
 
 	pr_debug("%s: Resuming Governors\n", __func__);
 	pr_debug("%s: Resuming Governors\n", __func__);
@@ -1679,7 +1683,7 @@ void cpufreq_resume(void)
 		if (cpufreq_driver->resume && cpufreq_driver->resume(policy)) {
 		if (cpufreq_driver->resume && cpufreq_driver->resume(policy)) {
 			pr_err("%s: Failed to resume driver: %p\n", __func__,
 			pr_err("%s: Failed to resume driver: %p\n", __func__,
 				policy);
 				policy);
-		} else {
+		} else if (has_target()) {
 			down_write(&policy->rwsem);
 			down_write(&policy->rwsem);
 			ret = cpufreq_start_governor(policy);
 			ret = cpufreq_start_governor(policy);
 			up_write(&policy->rwsem);
 			up_write(&policy->rwsem);

+ 23 - 8
drivers/cpufreq/intel_pstate.c

@@ -586,6 +586,14 @@ static void intel_pstate_hwp_set(const struct cpumask *cpumask)
 	}
 	}
 }
 }
 
 
+static int intel_pstate_hwp_set_policy(struct cpufreq_policy *policy)
+{
+	if (hwp_active)
+		intel_pstate_hwp_set(policy->cpus);
+
+	return 0;
+}
+
 static void intel_pstate_hwp_set_online_cpus(void)
 static void intel_pstate_hwp_set_online_cpus(void)
 {
 {
 	get_online_cpus();
 	get_online_cpus();
@@ -944,6 +952,11 @@ static int core_get_max_pstate(void)
 			if (err)
 			if (err)
 				goto skip_tar;
 				goto skip_tar;
 
 
+			/* For level 1 and 2, bits[23:16] contain the ratio */
+			if (tdp_ctrl)
+				tdp_ratio >>= 16;
+
+			tdp_ratio &= 0xff; /* ratios are only 8 bits long */
 			if (tdp_ratio - 1 == tar) {
 			if (tdp_ratio - 1 == tar) {
 				max_pstate = tar;
 				max_pstate = tar;
 				pr_debug("max_pstate=TAC %x\n", max_pstate);
 				pr_debug("max_pstate=TAC %x\n", max_pstate);
@@ -1188,8 +1201,9 @@ static inline bool intel_pstate_sample(struct cpudata *cpu, u64 time)
 
 
 static inline int32_t get_avg_frequency(struct cpudata *cpu)
 static inline int32_t get_avg_frequency(struct cpudata *cpu)
 {
 {
-	return div64_u64(cpu->pstate.max_pstate_physical * cpu->sample.aperf *
-		cpu->pstate.scaling, cpu->sample.mperf);
+	return fp_toint(mul_fp(cpu->sample.core_pct_busy,
+			       int_tofp(cpu->pstate.max_pstate_physical *
+						cpu->pstate.scaling / 100)));
 }
 }
 
 
 static inline int32_t get_avg_pstate(struct cpudata *cpu)
 static inline int32_t get_avg_pstate(struct cpudata *cpu)
@@ -1238,8 +1252,6 @@ static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu)
 	int32_t core_busy, max_pstate, current_pstate, sample_ratio;
 	int32_t core_busy, max_pstate, current_pstate, sample_ratio;
 	u64 duration_ns;
 	u64 duration_ns;
 
 
-	intel_pstate_calc_busy(cpu);
-
 	/*
 	/*
 	 * core_busy is the ratio of actual performance to max
 	 * core_busy is the ratio of actual performance to max
 	 * max_pstate is the max non turbo pstate available
 	 * max_pstate is the max non turbo pstate available
@@ -1322,8 +1334,11 @@ static void intel_pstate_update_util(struct update_util_data *data, u64 time,
 	if ((s64)delta_ns >= pid_params.sample_rate_ns) {
 	if ((s64)delta_ns >= pid_params.sample_rate_ns) {
 		bool sample_taken = intel_pstate_sample(cpu, time);
 		bool sample_taken = intel_pstate_sample(cpu, time);
 
 
-		if (sample_taken && !hwp_active)
-			intel_pstate_adjust_busy_pstate(cpu);
+		if (sample_taken) {
+			intel_pstate_calc_busy(cpu);
+			if (!hwp_active)
+				intel_pstate_adjust_busy_pstate(cpu);
+		}
 	}
 	}
 }
 }
 
 
@@ -1485,8 +1500,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
  out:
  out:
 	intel_pstate_set_update_util_hook(policy->cpu);
 	intel_pstate_set_update_util_hook(policy->cpu);
 
 
-	if (hwp_active)
-		intel_pstate_hwp_set(policy->cpus);
+	intel_pstate_hwp_set_policy(policy);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -1558,6 +1572,7 @@ static struct cpufreq_driver intel_pstate_driver = {
 	.flags		= CPUFREQ_CONST_LOOPS,
 	.flags		= CPUFREQ_CONST_LOOPS,
 	.verify		= intel_pstate_verify_policy,
 	.verify		= intel_pstate_verify_policy,
 	.setpolicy	= intel_pstate_set_policy,
 	.setpolicy	= intel_pstate_set_policy,
+	.resume		= intel_pstate_hwp_set_policy,
 	.get		= intel_pstate_get,
 	.get		= intel_pstate_get,
 	.init		= intel_pstate_cpu_init,
 	.init		= intel_pstate_cpu_init,
 	.exit		= intel_pstate_cpu_exit,
 	.exit		= intel_pstate_cpu_exit,

+ 4 - 0
drivers/cpufreq/sti-cpufreq.c

@@ -259,6 +259,10 @@ static int sti_cpufreq_init(void)
 {
 {
 	int ret;
 	int ret;
 
 
+	if ((!of_machine_is_compatible("st,stih407")) &&
+		(!of_machine_is_compatible("st,stih410")))
+		return -ENODEV;
+
 	ddata.cpu = get_cpu_device(0);
 	ddata.cpu = get_cpu_device(0);
 	if (!ddata.cpu) {
 	if (!ddata.cpu) {
 		dev_err(ddata.cpu, "Failed to get device for CPU0\n");
 		dev_err(ddata.cpu, "Failed to get device for CPU0\n");