Commit ceac2f27 authored by Manivannan Sadhasivam's avatar Manivannan Sadhasivam Committed by Wentao Guan
Browse files

cpufreq: qcom: Fix qcom_cpufreq_hw_recalc_rate() to query LUT if LMh IRQ is not available

stable inclusion
from stable-v6.6.76
commit f757327c4ce69f9d654aa43889c8c14035090d14
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IBW08Q

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=f757327c4ce69f9d654aa43889c8c14035090d14



--------------------------------

[ Upstream commit 85d8b11351a8f15d6ec7a5e97909861cb3b6bcec ]

Currently, qcom_cpufreq_hw_recalc_rate() returns the LMh throttled
frequency for the domain even if LMh IRQ is not available. But as per
qcom_cpufreq_hw_get(), the driver has to query LUT entries to get the
actual frequency of the domain. So do the same in
qcom_cpufreq_hw_recalc_rate().

While doing so, refactor the existing qcom_cpufreq_hw_get() function so
that qcom_cpufreq_hw_recalc_rate() can make use of the existing code and
avoid code duplication. This also requires setting the
qcom_cpufreq_data::policy even if LMh IRQ is not available.

Fixes: 4370232c ("cpufreq: qcom-hw: Add CPU clock provider support")
Signed-off-by: default avatarManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
(cherry picked from commit f757327c4ce69f9d654aa43889c8c14035090d14)
Signed-off-by: default avatarWentao Guan <guanwentao@uniontech.com>
parent a0428fee
Loading
Loading
Loading
Loading
+11 −10
Original line number Diff line number Diff line
@@ -142,14 +142,12 @@ static unsigned long qcom_lmh_get_throttle_freq(struct qcom_cpufreq_data *data)
}

/* Get the frequency requested by the cpufreq core for the CPU */
static unsigned int qcom_cpufreq_get_freq(unsigned int cpu)
static unsigned int qcom_cpufreq_get_freq(struct cpufreq_policy *policy)
{
	struct qcom_cpufreq_data *data;
	const struct qcom_cpufreq_soc_data *soc_data;
	struct cpufreq_policy *policy;
	unsigned int index;

	policy = cpufreq_cpu_get_raw(cpu);
	if (!policy)
		return 0;

@@ -162,12 +160,10 @@ static unsigned int qcom_cpufreq_get_freq(unsigned int cpu)
	return policy->freq_table[index].frequency;
}

static unsigned int qcom_cpufreq_hw_get(unsigned int cpu)
static unsigned int __qcom_cpufreq_hw_get(struct cpufreq_policy *policy)
{
	struct qcom_cpufreq_data *data;
	struct cpufreq_policy *policy;

	policy = cpufreq_cpu_get_raw(cpu);
	if (!policy)
		return 0;

@@ -176,7 +172,12 @@ static unsigned int qcom_cpufreq_hw_get(unsigned int cpu)
	if (data->throttle_irq >= 0)
		return qcom_lmh_get_throttle_freq(data) / HZ_PER_KHZ;

	return qcom_cpufreq_get_freq(cpu);
	return qcom_cpufreq_get_freq(policy);
}

static unsigned int qcom_cpufreq_hw_get(unsigned int cpu)
{
	return __qcom_cpufreq_hw_get(cpufreq_cpu_get_raw(cpu));
}

static unsigned int qcom_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
@@ -362,7 +363,7 @@ static void qcom_lmh_dcvs_notify(struct qcom_cpufreq_data *data)
	 * If h/w throttled frequency is higher than what cpufreq has requested
	 * for, then stop polling and switch back to interrupt mechanism.
	 */
	if (throttled_freq >= qcom_cpufreq_get_freq(cpu))
	if (throttled_freq >= qcom_cpufreq_get_freq(cpufreq_cpu_get_raw(cpu)))
		enable_irq(data->throttle_irq);
	else
		mod_delayed_work(system_highpri_wq, &data->throttle_work,
@@ -440,7 +441,6 @@ static int qcom_cpufreq_hw_lmh_init(struct cpufreq_policy *policy, int index)
		return data->throttle_irq;

	data->cancel_throttle = false;
	data->policy = policy;

	mutex_init(&data->throttle_lock);
	INIT_DEFERRABLE_WORK(&data->throttle_work, qcom_lmh_dcvs_poll);
@@ -551,6 +551,7 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)

	policy->driver_data = data;
	policy->dvfs_possible_from_any_cpu = true;
	data->policy = policy;

	ret = qcom_cpufreq_hw_read_lut(cpu_dev, policy);
	if (ret) {
@@ -623,7 +624,7 @@ static unsigned long qcom_cpufreq_hw_recalc_rate(struct clk_hw *hw, unsigned lon
{
	struct qcom_cpufreq_data *data = container_of(hw, struct qcom_cpufreq_data, cpu_clk);

	return qcom_lmh_get_throttle_freq(data);
	return __qcom_cpufreq_hw_get(data->policy) * HZ_PER_KHZ;
}

static const struct clk_ops qcom_cpufreq_hw_clk_ops = {