mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-03-22 07:27:12 +08:00
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:
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user