lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Wed, 13 Jul 2022 12:22:59 +0530
From:   Viresh Kumar <viresh.kumar@...aro.org>
To:     Bjorn Andersson <bjorn.andersson@...aro.org>,
        Manivannan Sadhasivam <mani@...nel.org>,
        Andy Gross <agross@...nel.org>,
        "Rafael J. Wysocki" <rafael@...nel.org>,
        Viresh Kumar <viresh.kumar@...aro.org>
Cc:     Vincent Guittot <vincent.guittot@...aro.org>,
        Johan Hovold <johan@...nel.org>,
        Rob Herring <robh+dt@...nel.org>,
        Krzysztof Kozlowski <krzysztof.kozlowski+dt@...aro.org>,
        linux-arm-msm@...r.kernel.org, linux-pm@...r.kernel.org,
        linux-kernel@...r.kernel.org
Subject: [RFC PATCH 4/4] cpufreq: qcom-cpufreq-hw: Register config_clks helper

There is a corner case with Qcom, where we want to skip clk
configuration that happens via dev_pm_opp_set_opp(), but still want the
OPP core to read the "opp-hz" property so we can find the right OPP via
freq finding helpers.

The OPP core provides support for the platforms to provide config_clks
helpers now, lets use that to provide an empty callback to skip clock
configuration.

The "table" wasn't getting freed properly on error, fix it as well which
we are updating the code.

Signed-off-by: Viresh Kumar <viresh.kumar@...aro.org>
---
 drivers/cpufreq/qcom-cpufreq-hw.c | 32 ++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c
index 05fce4a559ca..8d055a5f6575 100644
--- a/drivers/cpufreq/qcom-cpufreq-hw.c
+++ b/drivers/cpufreq/qcom-cpufreq-hw.c
@@ -59,6 +59,7 @@ struct qcom_cpufreq_data {
 	bool per_core_dcvs;
 	unsigned long cpu_hw_rate;
 	unsigned long xo_rate;
+	int opp_token;
 };
 
 static bool icc_scaling_enabled;
@@ -162,6 +163,15 @@ static unsigned int qcom_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
 	return policy->freq_table[index].frequency;
 }
 
+static int qcom_cpufreq_hw_config_clks_nop(struct device *dev,
+					   struct opp_table *opp_table,
+					   struct dev_pm_opp *opp, void *data,
+					   bool scaling_down)
+{
+	/* We want to skip clk configuration via dev_pm_opp_set_opp() */
+	return 0;
+}
+
 static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
 				    struct cpufreq_policy *policy)
 {
@@ -173,11 +183,23 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
 	int ret;
 	struct qcom_cpufreq_data *drv_data = policy->driver_data;
 	const struct qcom_cpufreq_soc_data *soc_data = drv_data->soc_data;
+	const char * const clk_names[] = { "xo", NULL };
+	struct dev_pm_opp_config config = {
+		.clk_names = clk_names,
+		.config_clks = qcom_cpufreq_hw_config_clks_nop,
+	};
 
 	table = kcalloc(LUT_MAX_ENTRIES + 1, sizeof(*table), GFP_KERNEL);
 	if (!table)
 		return -ENOMEM;
 
+	ret = dev_pm_opp_set_config(cpu_dev, &config);
+	if (ret < 0) {
+		dev_err(cpu_dev, "Failed to set OPP config: %d\n", ret);
+		goto free_table;
+	}
+	drv_data->opp_token = ret;
+
 	ret = dev_pm_opp_of_add_table(cpu_dev);
 	if (!ret) {
 		/* Disable all opps and cross-validate against LUT later */
@@ -192,7 +214,7 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
 		}
 	} else if (ret != -ENODEV) {
 		dev_err(cpu_dev, "Invalid opp table in device tree\n");
-		return ret;
+		goto clear_config;
 	} else {
 		policy->fast_switch_possible = true;
 		icc_scaling_enabled = false;
@@ -260,6 +282,13 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
 	dev_pm_opp_set_sharing_cpus(cpu_dev, policy->cpus);
 
 	return 0;
+
+clear_config:
+	dev_pm_opp_clear_config(drv_data->opp_token);
+
+free_table:
+	kfree(table);
+	return ret;
 }
 
 static void qcom_get_related_cpus(int index, struct cpumask *m)
@@ -614,6 +643,7 @@ static int qcom_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy)
 	dev_pm_opp_remove_all_dynamic(cpu_dev);
 	dev_pm_opp_of_cpumask_remove_table(policy->related_cpus);
 	qcom_cpufreq_hw_lmh_exit(data);
+	dev_pm_opp_clear_config(data->opp_token);
 	kfree(policy->freq_table);
 	kfree(data);
 	iounmap(base);
-- 
2.31.1.272.g89b43f80a514

Powered by blists - more mailing lists