Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

cpufreq: qcom-cpufreq-hw: Clear dcvs interrupts

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>

authored by

Vladimir Zapolskiy and committed by
Viresh Kumar
e4e64486 1aa24a8f

+8
+8
drivers/cpufreq/qcom-cpufreq-hw.c
··· 24 24 #define CLK_HW_DIV 2 25 25 #define LUT_TURBO_IND 1 26 26 27 + #define GT_IRQ_STATUS BIT(2) 28 + 27 29 #define HZ_PER_KHZ 1000 28 30 29 31 struct qcom_cpufreq_soc_data { ··· 34 32 u32 reg_dcvs_ctrl; 35 33 u32 reg_freq_lut; 36 34 u32 reg_volt_lut; 35 + u32 reg_intr_clr; 37 36 u32 reg_current_vote; 38 37 u32 reg_perf_state; 39 38 u8 lut_row_size; ··· 363 360 disable_irq_nosync(c_data->throttle_irq); 364 361 schedule_delayed_work(&c_data->throttle_work, 0); 365 362 363 + if (c_data->soc_data->reg_intr_clr) 364 + writel_relaxed(GT_IRQ_STATUS, 365 + c_data->base + c_data->soc_data->reg_intr_clr); 366 + 366 367 return IRQ_HANDLED; 367 368 } 368 369 ··· 386 379 .reg_dcvs_ctrl = 0xb0, 387 380 .reg_freq_lut = 0x100, 388 381 .reg_volt_lut = 0x200, 382 + .reg_intr_clr = 0x308, 389 383 .reg_perf_state = 0x320, 390 384 .lut_row_size = 4, 391 385 };