Merge tag 'cpufreq-arm-updates-6.18-rc' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm

Merge CPUFreq fixes for 6.18 from Viresh Kumar:

"- Update frequency for all tegra CPUs (Aaron Kling).

 - Fix device leak in mediatek driver (Johan Hovold).

 - Rust cpufreq helper cleanup (Thorsten Blum)."

* tag 'cpufreq-arm-updates-6.18-rc' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm:
  cpufreq: tegra186: Initialize all cores to max frequencies
  cpufreq: tegra186: Set target frequency for all cpus in policy
  rust: cpufreq: streamline find_supply_names
  cpufreq: mediatek: fix device leak on probe failure
This commit is contained in:
Rafael J. Wysocki
2025-10-01 13:59:28 +02:00
3 changed files with 41 additions and 18 deletions

View File

@@ -403,9 +403,11 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
}
info->cpu_clk = clk_get(cpu_dev, "cpu");
if (IS_ERR(info->cpu_clk))
return dev_err_probe(cpu_dev, PTR_ERR(info->cpu_clk),
"cpu%d: failed to get cpu clk\n", cpu);
if (IS_ERR(info->cpu_clk)) {
ret = PTR_ERR(info->cpu_clk);
dev_err_probe(cpu_dev, ret, "cpu%d: failed to get cpu clk\n", cpu);
goto out_put_cci_dev;
}
info->inter_clk = clk_get(cpu_dev, "intermediate");
if (IS_ERR(info->inter_clk)) {
@@ -551,6 +553,10 @@ out_free_inter_clock:
out_free_mux_clock:
clk_put(info->cpu_clk);
out_put_cci_dev:
if (info->soc_data->ccifreq_supported)
put_device(info->cci_dev);
return ret;
}
@@ -568,6 +574,8 @@ static void mtk_cpu_dvfs_info_release(struct mtk_cpu_dvfs_info *info)
clk_put(info->inter_clk);
dev_pm_opp_of_cpumask_remove_table(&info->cpus);
dev_pm_opp_unregister_notifier(info->cpu_dev, &info->opp_nb);
if (info->soc_data->ccifreq_supported)
put_device(info->cci_dev);
}
static int mtk_cpufreq_init(struct cpufreq_policy *policy)

View File

@@ -28,15 +28,11 @@ fn find_supply_name_exact(dev: &Device, name: &str) -> Option<CString> {
/// Finds supply name for the CPU from DT.
fn find_supply_names(dev: &Device, cpu: cpu::CpuId) -> Option<KVec<CString>> {
// Try "cpu0" for older DTs, fallback to "cpu".
let name = (cpu.as_u32() == 0)
(cpu.as_u32() == 0)
.then(|| find_supply_name_exact(dev, "cpu0"))
.flatten()
.or_else(|| find_supply_name_exact(dev, "cpu"))?;
let mut list = KVec::with_capacity(1, GFP_KERNEL).ok()?;
list.push(name, GFP_KERNEL).ok()?;
Some(list)
.or_else(|| find_supply_name_exact(dev, "cpu"))
.and_then(|name| kernel::kvec![name].ok())
}
/// Represents the cpufreq dt device.

View File

@@ -93,10 +93,14 @@ static int tegra186_cpufreq_set_target(struct cpufreq_policy *policy,
{
struct tegra186_cpufreq_data *data = cpufreq_get_driver_data();
struct cpufreq_frequency_table *tbl = policy->freq_table + index;
unsigned int edvd_offset = data->cpus[policy->cpu].edvd_offset;
unsigned int edvd_offset;
u32 edvd_val = tbl->driver_data;
u32 cpu;
writel(edvd_val, data->regs + edvd_offset);
for_each_cpu(cpu, policy->cpus) {
edvd_offset = data->cpus[cpu].edvd_offset;
writel(edvd_val, data->regs + edvd_offset);
}
return 0;
}
@@ -132,13 +136,14 @@ static struct cpufreq_driver tegra186_cpufreq_driver = {
static struct cpufreq_frequency_table *init_vhint_table(
struct platform_device *pdev, struct tegra_bpmp *bpmp,
struct tegra186_cpufreq_cluster *cluster, unsigned int cluster_id)
struct tegra186_cpufreq_cluster *cluster, unsigned int cluster_id,
int *num_rates)
{
struct cpufreq_frequency_table *table;
struct mrq_cpu_vhint_request req;
struct tegra_bpmp_message msg;
struct cpu_vhint_data *data;
int err, i, j, num_rates = 0;
int err, i, j;
dma_addr_t phys;
void *virt;
@@ -168,6 +173,7 @@ static struct cpufreq_frequency_table *init_vhint_table(
goto free;
}
*num_rates = 0;
for (i = data->vfloor; i <= data->vceil; i++) {
u16 ndiv = data->ndiv[i];
@@ -178,10 +184,10 @@ static struct cpufreq_frequency_table *init_vhint_table(
if (i > 0 && ndiv == data->ndiv[i - 1])
continue;
num_rates++;
(*num_rates)++;
}
table = devm_kcalloc(&pdev->dev, num_rates + 1, sizeof(*table),
table = devm_kcalloc(&pdev->dev, *num_rates + 1, sizeof(*table),
GFP_KERNEL);
if (!table) {
table = ERR_PTR(-ENOMEM);
@@ -223,7 +229,9 @@ static int tegra186_cpufreq_probe(struct platform_device *pdev)
{
struct tegra186_cpufreq_data *data;
struct tegra_bpmp *bpmp;
unsigned int i = 0, err;
unsigned int i = 0, err, edvd_offset;
int num_rates = 0;
u32 edvd_val, cpu;
data = devm_kzalloc(&pdev->dev,
struct_size(data, clusters, TEGRA186_NUM_CLUSTERS),
@@ -246,10 +254,21 @@ static int tegra186_cpufreq_probe(struct platform_device *pdev)
for (i = 0; i < TEGRA186_NUM_CLUSTERS; i++) {
struct tegra186_cpufreq_cluster *cluster = &data->clusters[i];
cluster->table = init_vhint_table(pdev, bpmp, cluster, i);
cluster->table = init_vhint_table(pdev, bpmp, cluster, i, &num_rates);
if (IS_ERR(cluster->table)) {
err = PTR_ERR(cluster->table);
goto put_bpmp;
} else if (!num_rates) {
err = -EINVAL;
goto put_bpmp;
}
for (cpu = 0; cpu < ARRAY_SIZE(tegra186_cpus); cpu++) {
if (data->cpus[cpu].bpmp_cluster_id == i) {
edvd_val = cluster->table[num_rates - 1].driver_data;
edvd_offset = data->cpus[cpu].edvd_offset;
writel(edvd_val, data->regs + edvd_offset);
}
}
}