mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-22 22:51:37 +00:00
Power management fixes for 5.10-rc5.
- Add missing RCU_NONIDLE() annotations to the Tegra cpuidle driver (Dmitry Osipenko). - Fix boot frequency computation in the tegra186 cpufreq driver (Jon Hunter). - Make the SCMI cpufreq driver register a dummy clock provider to avoid OPP addition failures (Sudeep Holla). -----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEE4fcc61cGeeHD/fCwgsRv/nhiVHEFAl+2rNoSHHJqd0Byand5 c29ja2kubmV0AAoJEILEb/54YlRx8dgP/371AuIG1MKSFaWfgJnkDuaQN+/jFzXW fkGWOwgdRm2Pwkcpldb5Nve7icz1TQc2JxZQZY8ZPYAjekmDWlBj4NFEp9FS0+Wk nqFL46L3rotWv+YZ6Fr7cjjFXdI/RMDE3806zKv5+J/vxMlsKQdAMmppGHLS2fq1 GKzcSqKfGqeIhFStPrfGaeOc+jQfkqqnTBikfrhLKPusMWF+b3VO841SmqETVYpK D7GJYWlmMKYf+kHzTJeAhuIsH4Uy0f50iXgeW7WBh6ANfumC+Yzk0IklS4TbxD1U kI2CW35NyIIqa9LsFHwUVNBLWf0rxtL8vIOuIgffZ6ph8rRzkKkAPqk/T8/dW4/8 jB6SLTvK+NcSbwHQByQ/nnwvfTPgUdFB6HZwjKSWGIew5PLIydh20p3WAQINQCBI mRQqQ5Y9ORvMavZAQf6IaTY1bEDVBxlVlFYgbRg+6YZ5BS8hofWHOt8XAH/ppajO AxcC2U+fWt5LfDgFO9QsDnhhJB0sMA9TTuq31Zqpn0jfgB1O2n1SQsq4ywGoiXef FSaN9qunOcTkksSp32/H1LUS0Ndzeo+y7Z8XtbtQ9FoshtqyQIW1mKjfX5U5a3uz sq89D3XXhfjSmNlleMkfmr9wayDif0/wQLlBe/ehls+ZSo6V6Ea8d2kcysY51eXu xl6H9E0hWz22 =Hko0 -----END PGP SIGNATURE----- Merge tag 'pm-5.10-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm Pull power management fixes from Rafael Wysocki: "These fix two issues in ARM cpufreq drivers and one cpuidle driver issue. Specifics: - Add missing RCU_NONIDLE() annotations to the Tegra cpuidle driver (Dmitry Osipenko) - Fix boot frequency computation in the tegra186 cpufreq driver (Jon Hunter) - Make the SCMI cpufreq driver register a dummy clock provider to avoid OPP addition failures (Sudeep Holla)" * tag 'pm-5.10-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: cpufreq: scmi: Fix OPP addition failure with a dummy clock provider cpufreq: tegra186: Fix get frequency callback cpuidle: tegra: Annotate tegra_pm_set_cpu_in_lp2() with RCU_NONIDLE
This commit is contained in:
commit
4ca35b4f45
3 changed files with 29 additions and 14 deletions
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||||
|
|
||||||
|
#include <linux/clk-provider.h>
|
||||||
#include <linux/cpu.h>
|
#include <linux/cpu.h>
|
||||||
#include <linux/cpufreq.h>
|
#include <linux/cpufreq.h>
|
||||||
#include <linux/cpumask.h>
|
#include <linux/cpumask.h>
|
||||||
|
@ -228,12 +229,17 @@ static struct cpufreq_driver scmi_cpufreq_driver = {
|
||||||
static int scmi_cpufreq_probe(struct scmi_device *sdev)
|
static int scmi_cpufreq_probe(struct scmi_device *sdev)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
struct device *dev = &sdev->dev;
|
||||||
|
|
||||||
handle = sdev->handle;
|
handle = sdev->handle;
|
||||||
|
|
||||||
if (!handle || !handle->perf_ops)
|
if (!handle || !handle->perf_ops)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
/* dummy clock provider as needed by OPP if clocks property is used */
|
||||||
|
if (of_find_property(dev->of_node, "#clock-cells", NULL))
|
||||||
|
devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, NULL);
|
||||||
|
|
||||||
ret = cpufreq_register_driver(&scmi_cpufreq_driver);
|
ret = cpufreq_register_driver(&scmi_cpufreq_driver);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&sdev->dev, "%s: registering cpufreq failed, err: %d\n",
|
dev_err(&sdev->dev, "%s: registering cpufreq failed, err: %d\n",
|
||||||
|
|
|
@ -42,6 +42,8 @@ static const struct tegra186_cpufreq_cluster_info tegra186_clusters[] = {
|
||||||
struct tegra186_cpufreq_cluster {
|
struct tegra186_cpufreq_cluster {
|
||||||
const struct tegra186_cpufreq_cluster_info *info;
|
const struct tegra186_cpufreq_cluster_info *info;
|
||||||
struct cpufreq_frequency_table *table;
|
struct cpufreq_frequency_table *table;
|
||||||
|
u32 ref_clk_khz;
|
||||||
|
u32 div;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tegra186_cpufreq_data {
|
struct tegra186_cpufreq_data {
|
||||||
|
@ -94,7 +96,7 @@ static int tegra186_cpufreq_set_target(struct cpufreq_policy *policy,
|
||||||
|
|
||||||
static unsigned int tegra186_cpufreq_get(unsigned int cpu)
|
static unsigned int tegra186_cpufreq_get(unsigned int cpu)
|
||||||
{
|
{
|
||||||
struct cpufreq_frequency_table *tbl;
|
struct tegra186_cpufreq_data *data = cpufreq_get_driver_data();
|
||||||
struct cpufreq_policy *policy;
|
struct cpufreq_policy *policy;
|
||||||
void __iomem *edvd_reg;
|
void __iomem *edvd_reg;
|
||||||
unsigned int i, freq = 0;
|
unsigned int i, freq = 0;
|
||||||
|
@ -104,17 +106,23 @@ static unsigned int tegra186_cpufreq_get(unsigned int cpu)
|
||||||
if (!policy)
|
if (!policy)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
tbl = policy->freq_table;
|
|
||||||
edvd_reg = policy->driver_data;
|
edvd_reg = policy->driver_data;
|
||||||
ndiv = readl(edvd_reg) & EDVD_CORE_VOLT_FREQ_F_MASK;
|
ndiv = readl(edvd_reg) & EDVD_CORE_VOLT_FREQ_F_MASK;
|
||||||
|
|
||||||
for (i = 0; tbl[i].frequency != CPUFREQ_TABLE_END; i++) {
|
for (i = 0; i < data->num_clusters; i++) {
|
||||||
if ((tbl[i].driver_data & EDVD_CORE_VOLT_FREQ_F_MASK) == ndiv) {
|
struct tegra186_cpufreq_cluster *cluster = &data->clusters[i];
|
||||||
freq = tbl[i].frequency;
|
int core;
|
||||||
break;
|
|
||||||
|
for (core = 0; core < ARRAY_SIZE(cluster->info->cpus); core++) {
|
||||||
|
if (cluster->info->cpus[core] != policy->cpu)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
freq = (cluster->ref_clk_khz * ndiv) / cluster->div;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
cpufreq_cpu_put(policy);
|
cpufreq_cpu_put(policy);
|
||||||
|
|
||||||
return freq;
|
return freq;
|
||||||
|
@ -133,7 +141,7 @@ static struct cpufreq_driver tegra186_cpufreq_driver = {
|
||||||
|
|
||||||
static struct cpufreq_frequency_table *init_vhint_table(
|
static struct cpufreq_frequency_table *init_vhint_table(
|
||||||
struct platform_device *pdev, struct tegra_bpmp *bpmp,
|
struct platform_device *pdev, struct tegra_bpmp *bpmp,
|
||||||
unsigned int cluster_id)
|
struct tegra186_cpufreq_cluster *cluster)
|
||||||
{
|
{
|
||||||
struct cpufreq_frequency_table *table;
|
struct cpufreq_frequency_table *table;
|
||||||
struct mrq_cpu_vhint_request req;
|
struct mrq_cpu_vhint_request req;
|
||||||
|
@ -152,7 +160,7 @@ static struct cpufreq_frequency_table *init_vhint_table(
|
||||||
|
|
||||||
memset(&req, 0, sizeof(req));
|
memset(&req, 0, sizeof(req));
|
||||||
req.addr = phys;
|
req.addr = phys;
|
||||||
req.cluster_id = cluster_id;
|
req.cluster_id = cluster->info->bpmp_cluster_id;
|
||||||
|
|
||||||
memset(&msg, 0, sizeof(msg));
|
memset(&msg, 0, sizeof(msg));
|
||||||
msg.mrq = MRQ_CPU_VHINT;
|
msg.mrq = MRQ_CPU_VHINT;
|
||||||
|
@ -185,6 +193,9 @@ static struct cpufreq_frequency_table *init_vhint_table(
|
||||||
goto free;
|
goto free;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cluster->ref_clk_khz = data->ref_clk_hz / 1000;
|
||||||
|
cluster->div = data->pdiv * data->mdiv;
|
||||||
|
|
||||||
for (i = data->vfloor, j = 0; i <= data->vceil; i++) {
|
for (i = data->vfloor, j = 0; i <= data->vceil; i++) {
|
||||||
struct cpufreq_frequency_table *point;
|
struct cpufreq_frequency_table *point;
|
||||||
u16 ndiv = data->ndiv[i];
|
u16 ndiv = data->ndiv[i];
|
||||||
|
@ -202,8 +213,7 @@ static struct cpufreq_frequency_table *init_vhint_table(
|
||||||
|
|
||||||
point = &table[j++];
|
point = &table[j++];
|
||||||
point->driver_data = edvd_val;
|
point->driver_data = edvd_val;
|
||||||
point->frequency = data->ref_clk_hz * ndiv / data->pdiv /
|
point->frequency = (cluster->ref_clk_khz * ndiv) / cluster->div;
|
||||||
data->mdiv / 1000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
table[j].frequency = CPUFREQ_TABLE_END;
|
table[j].frequency = CPUFREQ_TABLE_END;
|
||||||
|
@ -245,8 +255,7 @@ static int tegra186_cpufreq_probe(struct platform_device *pdev)
|
||||||
struct tegra186_cpufreq_cluster *cluster = &data->clusters[i];
|
struct tegra186_cpufreq_cluster *cluster = &data->clusters[i];
|
||||||
|
|
||||||
cluster->info = &tegra186_clusters[i];
|
cluster->info = &tegra186_clusters[i];
|
||||||
cluster->table = init_vhint_table(
|
cluster->table = init_vhint_table(pdev, bpmp, cluster);
|
||||||
pdev, bpmp, cluster->info->bpmp_cluster_id);
|
|
||||||
if (IS_ERR(cluster->table)) {
|
if (IS_ERR(cluster->table)) {
|
||||||
err = PTR_ERR(cluster->table);
|
err = PTR_ERR(cluster->table);
|
||||||
goto put_bpmp;
|
goto put_bpmp;
|
||||||
|
|
|
@ -189,7 +189,7 @@ static int tegra_cpuidle_state_enter(struct cpuidle_device *dev,
|
||||||
}
|
}
|
||||||
|
|
||||||
local_fiq_disable();
|
local_fiq_disable();
|
||||||
tegra_pm_set_cpu_in_lp2();
|
RCU_NONIDLE(tegra_pm_set_cpu_in_lp2());
|
||||||
cpu_pm_enter();
|
cpu_pm_enter();
|
||||||
|
|
||||||
switch (index) {
|
switch (index) {
|
||||||
|
@ -207,7 +207,7 @@ static int tegra_cpuidle_state_enter(struct cpuidle_device *dev,
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu_pm_exit();
|
cpu_pm_exit();
|
||||||
tegra_pm_clear_cpu_in_lp2();
|
RCU_NONIDLE(tegra_pm_clear_cpu_in_lp2());
|
||||||
local_fiq_enable();
|
local_fiq_enable();
|
||||||
|
|
||||||
return err ?: index;
|
return err ?: index;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue