Message ID | 20241205-qcom-cpufreq-clk-fix-v1-2-de46c82e0fe5@linaro.org |
---|---|
State | New |
Headers | show |
Series | cpufreq: qcom: Clock provider fixes | expand |
Quoting Manivannan Sadhasivam via B4 Relay (2024-12-05 08:50:29) > From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> > > determine_rate() callback is used by the clk_set_rate() API to get the > closest rate of the target rate supported by the clock. If this callback > is not implemented (nor round_rate() callback), then the API will assume > that the clock cannot set the requested rate. And since there is no parent, > it will return -EINVAL. > > This is not an issue right now as clk_set_rate() mistakenly compares the > target rate with cached rate and bails out early. But once that is fixed > to compare the target rate with the actual rate of the clock (returned by > recalc_rate()), then clk_set_rate() for this clock will start to fail as > below: > > cpu cpu0: _opp_config_clk_single: failed to set clock rate: -22 > > So implement the determine_rate() callback that just returns the actual > rate at which the clock is passed to the CPUs in a domain. > > Fixes: 4370232c727b ("cpufreq: qcom-hw: Add CPU clock provider support") > Reported-by: Johan Hovold <johan+linaro@kernel.org> > Closes: https://lore.kernel.org/all/20241202100621.29209-1-johan+linaro@kernel.org > Suggested-by: Stephen Boyd <sboyd@kernel.org> > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> > --- Reviewed-by: Stephen Boyd <sboyd@kernel.org>
diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c index c145ab7b0bb2..b2e7e89feaac 100644 --- a/drivers/cpufreq/qcom-cpufreq-hw.c +++ b/drivers/cpufreq/qcom-cpufreq-hw.c @@ -626,8 +626,21 @@ static unsigned long qcom_cpufreq_hw_recalc_rate(struct clk_hw *hw, unsigned lon return __qcom_cpufreq_hw_get(data->policy) * HZ_PER_KHZ; } +/* + * Since we cannot determine the closest rate of the target rate, let's just + * return the actual rate at which the clock is running at. This is needed to + * make clk_set_rate() API work properly. + */ +static int qcom_cpufreq_hw_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) +{ + req->rate = qcom_cpufreq_hw_recalc_rate(hw, 0); + + return 0; +} + static const struct clk_ops qcom_cpufreq_hw_clk_ops = { .recalc_rate = qcom_cpufreq_hw_recalc_rate, + .determine_rate = qcom_cpufreq_hw_determine_rate, }; static int qcom_cpufreq_hw_driver_probe(struct platform_device *pdev)