Commit 788715b5 authored by Nícolas F. R. A. Prado's avatar Nícolas F. R. A. Prado Committed by Viresh Kumar
Browse files

cpufreq: mediatek-hw: Wait for CPU supplies before probing



Before proceeding with the probe and enabling frequency scaling for the
CPUs, make sure that all supplies feeding the CPUs have probed.

This fixes an issue observed on MT8195-Tomato where if the
mediatek-cpufreq-hw driver enabled the hardware (by writing to
REG_FREQ_ENABLE) before the SPMI controller driver (spmi-mtk-pmif),
behind which lies the big CPU supply, probed the platform would hang
shortly after with "rcu: INFO: rcu_preempt detected stalls on
CPUs/tasks" being printed in the log.

Fixes: 4855e26b ("cpufreq: mediatek-hw: Add support for CPUFREQ HW")
Signed-off-by: default avatarNícolas F. R. A. Prado <nfraprado@collabora.com>
Reviewed-by: default avatarAngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: default avatarMatthias Brugger <matthias.bgg@gmail.com>
Signed-off-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
parent f661017e
Loading
Loading
Loading
Loading
+18 −1
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>

#define LUT_MAX_ENTRIES			32U
@@ -300,7 +301,23 @@ static struct cpufreq_driver cpufreq_mtk_hw_driver = {
static int mtk_cpufreq_hw_driver_probe(struct platform_device *pdev)
{
	const void *data;
	int ret;
	int ret, cpu;
	struct device *cpu_dev;
	struct regulator *cpu_reg;

	/* Make sure that all CPU supplies are available before proceeding. */
	for_each_possible_cpu(cpu) {
		cpu_dev = get_cpu_device(cpu);
		if (!cpu_dev)
			return dev_err_probe(&pdev->dev, -EPROBE_DEFER,
					     "Failed to get cpu%d device\n", cpu);

		cpu_reg = devm_regulator_get_optional(cpu_dev, "cpu");
		if (IS_ERR(cpu_reg))
			return dev_err_probe(&pdev->dev, PTR_ERR(cpu_reg),
					     "CPU%d regulator get failed\n", cpu);
	}


	data = of_device_get_match_data(&pdev->dev);
	if (!data)