From: Vladimir Zapolskiy vladimir.zapolskiy@linaro.org
[ Upstream commit e4e6448638a01905faeda9bf96aa9df7c8ef463c ]
It's noted that dcvs interrupts are not self-clearing, thus an interrupt handler runs constantly, which leads to a severe regression in runtime. To fix the problem an explicit write to clear interrupt register is required, note that on OSM platforms the register may not be present.
Fixes: 275157b367f4 ("cpufreq: qcom-cpufreq-hw: Add dcvs interrupt support") Signed-off-by: Vladimir Zapolskiy vladimir.zapolskiy@linaro.org Signed-off-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/qcom-cpufreq-hw.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c index 1e99b71e7844..ca0f1be1c3b2 100644 --- a/drivers/cpufreq/qcom-cpufreq-hw.c +++ b/drivers/cpufreq/qcom-cpufreq-hw.c @@ -24,6 +24,8 @@ #define CLK_HW_DIV 2 #define LUT_TURBO_IND 1
+#define GT_IRQ_STATUS BIT(2) + #define HZ_PER_KHZ 1000
struct qcom_cpufreq_soc_data { @@ -31,6 +33,7 @@ struct qcom_cpufreq_soc_data { u32 reg_domain_state; u32 reg_freq_lut; u32 reg_volt_lut; + u32 reg_intr_clr; u32 reg_current_vote; u32 reg_perf_state; u8 lut_row_size; @@ -347,6 +350,10 @@ static irqreturn_t qcom_lmh_dcvs_handle_irq(int irq, void *data) disable_irq_nosync(c_data->throttle_irq); schedule_delayed_work(&c_data->throttle_work, 0);
+ if (c_data->soc_data->reg_intr_clr) + writel_relaxed(GT_IRQ_STATUS, + c_data->base + c_data->soc_data->reg_intr_clr); + return IRQ_HANDLED; }
@@ -364,6 +371,7 @@ static const struct qcom_cpufreq_soc_data epss_soc_data = { .reg_domain_state = 0x20, .reg_freq_lut = 0x100, .reg_volt_lut = 0x200, + .reg_intr_clr = 0x308, .reg_perf_state = 0x320, .lut_row_size = 4, };