From: yoy95104 <yahia.a.abdrabou@gmail.com>
To: rafael@kernel.org, viresh.kumar@linaro.org
Cc: linux-pm@vger.kernel.org, yoy95104 <yahia.a.abdrabou@gmail.com>
Subject: [PATCH v2] cpufreq: acpi-cpufreq: Add better support for amd zen
Date: Thu, 14 May 2026 20:37:22 +0300 [thread overview]
Message-ID: <20260514173722.190104-1-yahia.a.abdrabou@gmail.com> (raw)
Found some bugs in the original implementation and repeated code
Signed-off-by: yahia ahmed <yahia.a.abdrabou@gmail.com>
---
drivers/cpufreq/acpi-cpufreq.c | 80 ++++++++++++++++++++++------------
1 file changed, 51 insertions(+), 29 deletions(-)
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
index a488a2e2f914..29daca4ffdc6 100644
--- a/drivers/cpufreq/acpi-cpufreq.c
+++ b/drivers/cpufreq/acpi-cpufreq.c
@@ -65,7 +65,6 @@ struct acpi_cpufreq_data {
void (*cpu_freq_write)(struct acpi_pct_register *reg, u32 val);
u32 (*cpu_freq_read)(struct acpi_pct_register *reg);
int is_amd_zen;
- int on_ac;
};
/* acpi_perf_data is a pointer to percpu data. */
@@ -773,7 +772,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
return blacklisted;
#endif
- data = kzalloc_obj(*data);
+ data = kcalloc(1, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
@@ -781,42 +780,65 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
result = -ENOMEM;
goto err_free;
}
-
perf = per_cpu_ptr(acpi_perf_data, cpu);
- data->acpi_perf_cpu = cpu;
- policy->driver_data = data;
+ result = acpi_processor_register_performance(perf, cpu);
+
+ if (result)
+ goto err_free_mask;
if (c->x86_vendor == X86_VENDOR_AMD && c->x86 >= 0x17 && c->x86_model >= 0x30) {
data->is_amd_zen = 1;
- policy->cur = get_current_freq(cpu);
- policy->shared_type = CPUFREQ_SHARED_TYPE_NONE;
- unsigned int max_boost = get_max_freq(cpu);
- u8 virtual_pstates = 16;
- unsigned int max_freq = get_max_freq(policy->cpu);
- unsigned int min_freq = perf->states[perf->state_count - 1].core_frequency * 1000;
- unsigned int step = (max_freq - min_freq) / (virtual_pstates - 1);
- freq_table = kcalloc(virtual_pstates + 1, sizeof(*freq_table), GFP_KERNEL);
- for (int i = 0; i < virtual_pstates; i++) {
- freq_table[i].driver_data = i;
- freq_table[i].frequency = max_freq - (i * step);
- }
- freq_table[virtual_pstates].frequency = CPUFREQ_TABLE_END;
- policy->freq_table = freq_table;
- if (max_boost) {
- policy->cpuinfo.max_freq = max_boost;
- policy->max = max_boost;
+
+ if (perf->state_count > 0 && perf->states) {
+ policy->cur = get_current_freq(cpu);
+ policy->shared_type = CPUFREQ_SHARED_TYPE_NONE;
+ unsigned int max_boost = get_max_freq(cpu);
+ u8 virtual_pstates = 16;
+ unsigned int max_freq = get_max_freq(policy->cpu);
+ unsigned int min_freq = perf->states[perf->state_count - 1].core_frequency * 1000;
+ unsigned int step = (max_freq - min_freq) / (virtual_pstates - 1);
+ freq_table = kcalloc(virtual_pstates + 1, sizeof(*freq_table), GFP_KERNEL);
+ for (int i = 0; i < virtual_pstates; i++) {
+ freq_table[i].driver_data = i;
+ freq_table[i].frequency = max_freq - (i * step);
+ }
+ freq_table[virtual_pstates].frequency = CPUFREQ_TABLE_END;
+ policy->freq_table = freq_table;
+ if (max_boost) {
+ policy->cpuinfo.max_freq = max_boost;
+ policy->max = max_boost;
+ } else {
+ policy->cpuinfo.max_freq = perf->states[0].core_frequency * 1000;
+ }
+ return 0;
} else {
- policy->cpuinfo.max_freq = perf->states[0].core_frequency * 1000;
+ pr_warn("ACPI Table didnt provide any P-States");
+ unsigned int max_freq = get_max_freq(cpu);
+
+ if (max_freq == 0)
+ max_freq = 2000000;
+ u8 virtual_pstates = 16;
+ unsigned int step = 25000;
+ freq_table = kcalloc(virtual_pstates + 1, sizeof(*freq_table), GFP_KERNEL);
+ if (!freq_table) {
+ result = -ENOMEM;
+ goto err_unreg;
+ }
+ for (int i = 0; i < virtual_pstates; i++) {
+ freq_table[i].driver_data = i;
+ freq_table[i].frequency = max_freq - (i * step);
+ }
+ freq_table[virtual_pstates].frequency = CPUFREQ_TABLE_END;
+ policy->freq_table = freq_table;
+ policy->cpuinfo.max_freq = max_freq;
+ policy->max = max_freq;
+ policy->cur = get_current_freq(cpu);
+ return 0;
}
} else {
policy->shared_type = CPUFREQ_SHARED_TYPE_HW;
}
if (cpu_has(c, X86_FEATURE_CONSTANT_TSC))
acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS;
-
- result = acpi_processor_register_performance(perf, cpu);
- if (result)
- goto err_free_mask;
-
/*
* Will let policy->cpus know about dependency only when software
* coordination is required.
@@ -893,7 +915,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
goto err_unreg;
}
- freq_table = kzalloc_objs(*freq_table, perf->state_count + 1);
+ freq_table = kcalloc(17, sizeof(*freq_table), GFP_KERNEL);
if (!freq_table) {
result = -ENOMEM;
goto err_unreg;
--
2.54.0
reply other threads:[~2026-05-14 17:37 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260514173722.190104-1-yahia.a.abdrabou@gmail.com \
--to=yahia.a.abdrabou@gmail.com \
--cc=linux-pm@vger.kernel.org \
--cc=rafael@kernel.org \
--cc=viresh.kumar@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox