From b376471fb47d4905e72fe73e9eeed228f8f2f230 Mon Sep 17 00:00:00 2001 From: Jinzhou Su Date: Thu, 23 Jun 2022 11:15:09 +0800 Subject: cpufreq: amd-pstate: Add resume and suspend callbacks When system resumes from S3, the CPPC enable register will be cleared and reset to 0. So enable the CPPC interface by writing 1 to this register on system resume and disable it during system suspend. Signed-off-by: Jinzhou Su Signed-off-by: Jinzhou Su Acked-by: Huang Rui [ rjw: Subject and changelog edits ] Cc: All applicable Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/amd-pstate.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index 7be38bc6a673..9ac75c1cde9c 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -566,6 +566,28 @@ static int amd_pstate_cpu_exit(struct cpufreq_policy *policy) return 0; } +static int amd_pstate_cpu_resume(struct cpufreq_policy *policy) +{ + int ret; + + ret = amd_pstate_enable(true); + if (ret) + pr_err("failed to enable amd-pstate during resume, return %d\n", ret); + + return ret; +} + +static int amd_pstate_cpu_suspend(struct cpufreq_policy *policy) +{ + int ret; + + ret = amd_pstate_enable(false); + if (ret) + pr_err("failed to disable amd-pstate during suspend, return %d\n", ret); + + return ret; +} + /* Sysfs attributes */ /* @@ -636,6 +658,8 @@ static struct cpufreq_driver amd_pstate_driver = { .target = amd_pstate_target, .init = amd_pstate_cpu_init, .exit = amd_pstate_cpu_exit, + .suspend = amd_pstate_cpu_suspend, + .resume = amd_pstate_cpu_resume, .set_boost = amd_pstate_set_boost, .name = "amd-pstate", .attr = amd_pstate_attr, -- cgit v1.2.3 From 4ff5a9b6d95f3524bf6d27147df497eb21968300 Mon Sep 17 00:00:00 2001 From: Liang He Date: Wed, 15 Jun 2022 17:48:07 +0800 Subject: drivers: cpufreq: Add missing of_node_put() in qoriq-cpufreq.c In qoriq_cpufreq_probe(), of_find_matching_node() will return a node pointer with refcount incremented. We should use of_node_put() when it is not used anymore. Fixes: 157f527639da ("cpufreq: qoriq: convert to a platform driver") [ Viresh: Fixed Author's name in commit log ] Signed-off-by: Liang He Signed-off-by: Viresh Kumar --- drivers/cpufreq/qoriq-cpufreq.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/cpufreq/qoriq-cpufreq.c b/drivers/cpufreq/qoriq-cpufreq.c index 6b6b20da2bcf..573b417e1483 100644 --- a/drivers/cpufreq/qoriq-cpufreq.c +++ b/drivers/cpufreq/qoriq-cpufreq.c @@ -275,6 +275,7 @@ static int qoriq_cpufreq_probe(struct platform_device *pdev) np = of_find_matching_node(NULL, qoriq_cpufreq_blacklist); if (np) { + of_node_put(np); dev_info(&pdev->dev, "Disabling due to erratum A-008083"); return -ENODEV; } -- cgit v1.2.3 From 668a7a12ded7077d4fd7ad1305667e559907e5bb Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 16 Jun 2022 15:45:31 -0700 Subject: cpufreq: qcom-hw: Don't do lmh things without a throttle interrupt Offlining cpu6 and cpu7 and then onlining cpu6 hangs on sc7180-trogdor-lazor because the throttle interrupt doesn't exist. Similarly, things go sideways when suspend/resume runs. That's because the qcom_cpufreq_hw_cpu_online() and qcom_cpufreq_hw_lmh_exit() functions are calling genirq APIs with an interrupt value of '-6', i.e. -ENXIO, and that isn't good. Check the value of the throttle interrupt like we already do in other functions in this file and bail out early from lmh code to fix the hang. Reported-by: Rob Clark Cc: Vladimir Zapolskiy Cc: Bjorn Andersson Cc: Dmitry Baryshkov Fixes: a1eb080a0447 ("cpufreq: qcom-hw: provide online/offline operations") Signed-off-by: Stephen Boyd Reviewed-by: Vladimir Zapolskiy Signed-off-by: Viresh Kumar --- drivers/cpufreq/qcom-cpufreq-hw.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c index 0253731d6d25..36c79580fba2 100644 --- a/drivers/cpufreq/qcom-cpufreq-hw.c +++ b/drivers/cpufreq/qcom-cpufreq-hw.c @@ -442,6 +442,9 @@ static int qcom_cpufreq_hw_cpu_online(struct cpufreq_policy *policy) struct platform_device *pdev = cpufreq_get_driver_data(); int ret; + if (data->throttle_irq <= 0) + return 0; + ret = irq_set_affinity_hint(data->throttle_irq, policy->cpus); if (ret) dev_err(&pdev->dev, "Failed to set CPU affinity of %s[%d]\n", @@ -469,6 +472,9 @@ static int qcom_cpufreq_hw_cpu_offline(struct cpufreq_policy *policy) static void qcom_cpufreq_hw_lmh_exit(struct qcom_cpufreq_data *data) { + if (data->throttle_irq <= 0) + return; + free_irq(data->throttle_irq, data); } -- cgit v1.2.3 From ccd7567d4b6cf187fdfa55f003a9e461ee629e36 Mon Sep 17 00:00:00 2001 From: Liang He Date: Sat, 18 Jun 2022 10:25:45 +0800 Subject: cpufreq: pmac32-cpufreq: Fix refcount leak bug In pmac_cpufreq_init_MacRISC3(), we need to add corresponding of_node_put() for the three node pointers whose refcount have been incremented by of_find_node_by_name(). Signed-off-by: Liang He Signed-off-by: Viresh Kumar --- drivers/cpufreq/pmac32-cpufreq.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/cpufreq/pmac32-cpufreq.c b/drivers/cpufreq/pmac32-cpufreq.c index 20f64a8b0a35..4b8ee2014da6 100644 --- a/drivers/cpufreq/pmac32-cpufreq.c +++ b/drivers/cpufreq/pmac32-cpufreq.c @@ -470,6 +470,10 @@ static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode) if (slew_done_gpio_np) slew_done_gpio = read_gpio(slew_done_gpio_np); + of_node_put(volt_gpio_np); + of_node_put(freq_gpio_np); + of_node_put(slew_done_gpio_np); + /* If we use the frequency GPIOs, calculate the min/max speeds based * on the bus frequencies */ -- cgit v1.2.3 From be4b61ec45b3efe5e9077525fc92d544305eb2a6 Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Fri, 17 Jun 2022 13:09:26 +0200 Subject: cpufreq: Add MT8186 to cpufreq-dt-platdev blocklist This SoC shall use the mediatek-cpufreq driver, or the system will crash upon any clock scaling request: add it to the cpufreq-dt-platdev blocklist. Fixes: 39b360102f3a ("cpufreq: mediatek: Add support for MT8186") Signed-off-by: AngeloGioacchino Del Regno Reviewed-by: Matthias Brugger Signed-off-by: Viresh Kumar --- drivers/cpufreq/cpufreq-dt-platdev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c index 96de1536e1cb..2c96de3f2d83 100644 --- a/drivers/cpufreq/cpufreq-dt-platdev.c +++ b/drivers/cpufreq/cpufreq-dt-platdev.c @@ -127,6 +127,7 @@ static const struct of_device_id blocklist[] __initconst = { { .compatible = "mediatek,mt8173", }, { .compatible = "mediatek,mt8176", }, { .compatible = "mediatek,mt8183", }, + { .compatible = "mediatek,mt8186", }, { .compatible = "mediatek,mt8365", }, { .compatible = "mediatek,mt8516", }, -- cgit v1.2.3 From 57e00b40033a376de3f3cf0bb9bf7590d2dd679d Mon Sep 17 00:00:00 2001 From: Christian 'Ansuel' Marangi Date: Tue, 14 Jun 2022 13:06:59 +0200 Subject: PM / devfreq: Fix kernel panic with cpu based scaling to passive gov The cpufreq passive register notifier can PROBE_DEFER and the devfreq struct is freed and then reallocaed on probe retry. The current logic assume that the code can't PROBE_DEFER so the devfreq struct in the this variable in devfreq_passive_data is assumed to be (if already set) always correct. This cause kernel panic as the code try to access the wrong address. To correctly handle this, update the this variable in devfreq_passive_data to the devfreq reallocated struct. Fixes: a03dacb0316f ("PM / devfreq: Add cpu based scaling support to passive governor") Signed-off-by: Christian 'Ansuel' Marangi Signed-off-by: Chanwoo Choi --- drivers/devfreq/governor_passive.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/devfreq/governor_passive.c b/drivers/devfreq/governor_passive.c index 72c67979ebe1..091a69e1f487 100644 --- a/drivers/devfreq/governor_passive.c +++ b/drivers/devfreq/governor_passive.c @@ -407,8 +407,7 @@ static int devfreq_passive_event_handler(struct devfreq *devfreq, if (!p_data) return -EINVAL; - if (!p_data->this) - p_data->this = devfreq; + p_data->this = devfreq; switch (event) { case DEVFREQ_GOV_START: -- cgit v1.2.3 From e52b045fe07d7874474665c843befa7521853234 Mon Sep 17 00:00:00 2001 From: Christian 'Ansuel' Marangi Date: Wed, 15 Jun 2022 01:09:50 +0200 Subject: PM / devfreq: Mute warning on governor PROBE_DEFER Don't print warning when a governor PROBE_DEFER as it's not a real GOV_START fail. Fixes: a03dacb0316f ("PM / devfreq: Add cpu based scaling support to passive governor") Signed-off-by: Christian 'Ansuel' Marangi Signed-off-by: Chanwoo Choi --- drivers/devfreq/devfreq.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 01474daf4548..80a1235ef8fb 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -932,8 +932,9 @@ struct devfreq *devfreq_add_device(struct device *dev, err = devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_START, NULL); if (err) { - dev_err(dev, "%s: Unable to start governor for the device\n", - __func__); + dev_err_probe(dev, err, + "%s: Unable to start governor for the device\n", + __func__); goto err_init; } create_sysfs_files(devfreq, devfreq->governor); -- cgit v1.2.3 From 0cca7e8dcfa9e6fe7ba697e534a732571f1689d0 Mon Sep 17 00:00:00 2001 From: Christian 'Ansuel' Marangi Date: Wed, 15 Jun 2022 01:09:47 +0200 Subject: PM / devfreq: Fix cpufreq passive unregister erroring on PROBE_DEFER With the passive governor, the cpu based scaling can PROBE_DEFER due to the fact that CPU policy are not ready. The cpufreq passive unregister notifier is called both from the GOV_START errors and for the GOV_STOP and assume the notifier is successfully registred every time. With GOV_START failing it's wrong to loop over each possible CPU since the register path has failed for some CPU policy not ready. Change the logic and unregister the notifer based on the current allocated parent_cpu_data list to correctly handle errors and the governor unregister path. Fixes: a03dacb0316f ("PM / devfreq: Add cpu based scaling support to passive governor") Signed-off-by: Christian 'Ansuel' Marangi Signed-off-by: Chanwoo Choi --- drivers/devfreq/governor_passive.c | 39 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/drivers/devfreq/governor_passive.c b/drivers/devfreq/governor_passive.c index 091a69e1f487..a35b39ac656c 100644 --- a/drivers/devfreq/governor_passive.c +++ b/drivers/devfreq/governor_passive.c @@ -34,6 +34,20 @@ get_parent_cpu_data(struct devfreq_passive_data *p_data, return NULL; } +static void delete_parent_cpu_data(struct devfreq_passive_data *p_data) +{ + struct devfreq_cpu_data *parent_cpu_data, *tmp; + + list_for_each_entry_safe(parent_cpu_data, tmp, &p_data->cpu_data_list, node) { + list_del(&parent_cpu_data->node); + + if (parent_cpu_data->opp_table) + dev_pm_opp_put_opp_table(parent_cpu_data->opp_table); + + kfree(parent_cpu_data); + } +} + static unsigned long get_target_freq_by_required_opp(struct device *p_dev, struct opp_table *p_opp_table, struct opp_table *opp_table, @@ -222,8 +236,7 @@ static int cpufreq_passive_unregister_notifier(struct devfreq *devfreq) { struct devfreq_passive_data *p_data = (struct devfreq_passive_data *)devfreq->data; - struct devfreq_cpu_data *parent_cpu_data; - int cpu, ret = 0; + int ret; if (p_data->nb.notifier_call) { ret = cpufreq_unregister_notifier(&p_data->nb, @@ -232,27 +245,9 @@ static int cpufreq_passive_unregister_notifier(struct devfreq *devfreq) return ret; } - for_each_possible_cpu(cpu) { - struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); - if (!policy) { - ret = -EINVAL; - continue; - } - - parent_cpu_data = get_parent_cpu_data(p_data, policy); - if (!parent_cpu_data) { - cpufreq_cpu_put(policy); - continue; - } - - list_del(&parent_cpu_data->node); - if (parent_cpu_data->opp_table) - dev_pm_opp_put_opp_table(parent_cpu_data->opp_table); - kfree(parent_cpu_data); - cpufreq_cpu_put(policy); - } + delete_parent_cpu_data(p_data); - return ret; + return 0; } static int cpufreq_passive_register_notifier(struct devfreq *devfreq) -- cgit v1.2.3 From 20e6c3cc90c0a86dba659dd9e7d60b429d88746d Mon Sep 17 00:00:00 2001 From: Yicong Yang Date: Fri, 10 Jun 2022 15:54:28 +0800 Subject: PM / devfreq: passive: Use HZ_PER_KHZ macro in units.h HZ macros has been centralized in units.h since [1]. Use it to avoid duplicated definition. [1] commit e2c77032fcbe ("units: add the HZ macros") Signed-off-by: Yicong Yang Signed-off-by: Chanwoo Choi --- drivers/devfreq/governor_passive.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/devfreq/governor_passive.c b/drivers/devfreq/governor_passive.c index a35b39ac656c..69e06725d92b 100644 --- a/drivers/devfreq/governor_passive.c +++ b/drivers/devfreq/governor_passive.c @@ -14,10 +14,9 @@ #include #include #include +#include #include "governor.h" -#define HZ_PER_KHZ 1000 - static struct devfreq_cpu_data * get_parent_cpu_data(struct devfreq_passive_data *p_data, struct cpufreq_policy *policy) -- cgit v1.2.3 From f44b799603a9b5d2e375b0b2d54dd0b791eddfc2 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Thu, 26 May 2022 12:28:56 +0400 Subject: PM / devfreq: exynos-ppmu: Fix refcount leak in of_get_devfreq_events of_get_child_by_name() returns a node pointer with refcount incremented, we should use of_node_put() on it when done. This function only calls of_node_put() in normal path, missing it in error paths. Add missing of_node_put() to avoid refcount leak. Fixes: f262f28c1470 ("PM / devfreq: event: Add devfreq_event class") Signed-off-by: Miaoqian Lin Signed-off-by: Chanwoo Choi --- drivers/devfreq/event/exynos-ppmu.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/devfreq/event/exynos-ppmu.c b/drivers/devfreq/event/exynos-ppmu.c index 9b849d781116..a443e7c42daf 100644 --- a/drivers/devfreq/event/exynos-ppmu.c +++ b/drivers/devfreq/event/exynos-ppmu.c @@ -519,15 +519,19 @@ static int of_get_devfreq_events(struct device_node *np, count = of_get_child_count(events_np); desc = devm_kcalloc(dev, count, sizeof(*desc), GFP_KERNEL); - if (!desc) + if (!desc) { + of_node_put(events_np); return -ENOMEM; + } info->num_events = count; of_id = of_match_device(exynos_ppmu_id_match, dev); if (of_id) info->ppmu_type = (enum exynos_ppmu_type)of_id->data; - else + else { + of_node_put(events_np); return -EINVAL; + } j = 0; for_each_child_of_node(events_np, node) { -- cgit v1.2.3 From b5d281f6c16dd432b618bdfd36ddba1a58d5b603 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Mon, 20 Jun 2022 00:03:51 +0200 Subject: PM / devfreq: Rework freq_table to be local to devfreq struct On a devfreq PROBE_DEFER, the freq_table in the driver profile struct, is never reset and may be leaved in an undefined state. This comes from the fact that we store the freq_table in the driver profile struct that is commonly defined as static and not reset on PROBE_DEFER. We currently skip the reinit of the freq_table if we found it's already defined since a driver may declare his own freq_table. This logic is flawed in the case devfreq core generate a freq_table, set it in the profile struct and then PROBE_DEFER, freeing the freq_table. In this case devfreq will found a NOT NULL freq_table that has been freed, skip the freq_table generation and probe the driver based on the wrong table. To fix this and correctly handle PROBE_DEFER, use a local freq_table and max_state in the devfreq struct and never modify the freq_table present in the profile struct if it does provide it. Fixes: 0ec09ac2cebe ("PM / devfreq: Set the freq_table of devfreq device") Cc: stable@vger.kernel.org Signed-off-by: Christian Marangi Signed-off-by: Chanwoo Choi --- drivers/devfreq/devfreq.c | 71 ++++++++++++++++++-------------------- drivers/devfreq/governor_passive.c | 14 ++++---- include/linux/devfreq.h | 5 +++ 3 files changed, 46 insertions(+), 44 deletions(-) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 80a1235ef8fb..9602141bb8ec 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -123,7 +123,7 @@ void devfreq_get_freq_range(struct devfreq *devfreq, unsigned long *min_freq, unsigned long *max_freq) { - unsigned long *freq_table = devfreq->profile->freq_table; + unsigned long *freq_table = devfreq->freq_table; s32 qos_min_freq, qos_max_freq; lockdep_assert_held(&devfreq->lock); @@ -133,11 +133,11 @@ void devfreq_get_freq_range(struct devfreq *devfreq, * The devfreq drivers can initialize this in either ascending or * descending order and devfreq core supports both. */ - if (freq_table[0] < freq_table[devfreq->profile->max_state - 1]) { + if (freq_table[0] < freq_table[devfreq->max_state - 1]) { *min_freq = freq_table[0]; - *max_freq = freq_table[devfreq->profile->max_state - 1]; + *max_freq = freq_table[devfreq->max_state - 1]; } else { - *min_freq = freq_table[devfreq->profile->max_state - 1]; + *min_freq = freq_table[devfreq->max_state - 1]; *max_freq = freq_table[0]; } @@ -169,8 +169,8 @@ static int devfreq_get_freq_level(struct devfreq *devfreq, unsigned long freq) { int lev; - for (lev = 0; lev < devfreq->profile->max_state; lev++) - if (freq == devfreq->profile->freq_table[lev]) + for (lev = 0; lev < devfreq->max_state; lev++) + if (freq == devfreq->freq_table[lev]) return lev; return -EINVAL; @@ -178,7 +178,6 @@ static int devfreq_get_freq_level(struct devfreq *devfreq, unsigned long freq) static int set_freq_table(struct devfreq *devfreq) { - struct devfreq_dev_profile *profile = devfreq->profile; struct dev_pm_opp *opp; unsigned long freq; int i, count; @@ -188,25 +187,22 @@ static int set_freq_table(struct devfreq *devfreq) if (count <= 0) return -EINVAL; - profile->max_state = count; - profile->freq_table = devm_kcalloc(devfreq->dev.parent, - profile->max_state, - sizeof(*profile->freq_table), - GFP_KERNEL); - if (!profile->freq_table) { - profile->max_state = 0; + devfreq->max_state = count; + devfreq->freq_table = devm_kcalloc(devfreq->dev.parent, + devfreq->max_state, + sizeof(*devfreq->freq_table), + GFP_KERNEL); + if (!devfreq->freq_table) return -ENOMEM; - } - for (i = 0, freq = 0; i < profile->max_state; i++, freq++) { + for (i = 0, freq = 0; i < devfreq->max_state; i++, freq++) { opp = dev_pm_opp_find_freq_ceil(devfreq->dev.parent, &freq); if (IS_ERR(opp)) { - devm_kfree(devfreq->dev.parent, profile->freq_table); - profile->max_state = 0; + devm_kfree(devfreq->dev.parent, devfreq->freq_table); return PTR_ERR(opp); } dev_pm_opp_put(opp); - profile->freq_table[i] = freq; + devfreq->freq_table[i] = freq; } return 0; @@ -246,7 +242,7 @@ int devfreq_update_status(struct devfreq *devfreq, unsigned long freq) if (lev != prev_lev) { devfreq->stats.trans_table[ - (prev_lev * devfreq->profile->max_state) + lev]++; + (prev_lev * devfreq->max_state) + lev]++; devfreq->stats.total_trans++; } @@ -835,6 +831,9 @@ struct devfreq *devfreq_add_device(struct device *dev, if (err < 0) goto err_dev; mutex_lock(&devfreq->lock); + } else { + devfreq->freq_table = devfreq->profile->freq_table; + devfreq->max_state = devfreq->profile->max_state; } devfreq->scaling_min_freq = find_available_min_freq(devfreq); @@ -870,8 +869,8 @@ struct devfreq *devfreq_add_device(struct device *dev, devfreq->stats.trans_table = devm_kzalloc(&devfreq->dev, array3_size(sizeof(unsigned int), - devfreq->profile->max_state, - devfreq->profile->max_state), + devfreq->max_state, + devfreq->max_state), GFP_KERNEL); if (!devfreq->stats.trans_table) { mutex_unlock(&devfreq->lock); @@ -880,7 +879,7 @@ struct devfreq *devfreq_add_device(struct device *dev, } devfreq->stats.time_in_state = devm_kcalloc(&devfreq->dev, - devfreq->profile->max_state, + devfreq->max_state, sizeof(*devfreq->stats.time_in_state), GFP_KERNEL); if (!devfreq->stats.time_in_state) { @@ -1666,9 +1665,9 @@ static ssize_t available_frequencies_show(struct device *d, mutex_lock(&df->lock); - for (i = 0; i < df->profile->max_state; i++) + for (i = 0; i < df->max_state; i++) count += scnprintf(&buf[count], (PAGE_SIZE - count - 2), - "%lu ", df->profile->freq_table[i]); + "%lu ", df->freq_table[i]); mutex_unlock(&df->lock); /* Truncate the trailing space */ @@ -1691,7 +1690,7 @@ static ssize_t trans_stat_show(struct device *dev, if (!df->profile) return -EINVAL; - max_state = df->profile->max_state; + max_state = df->max_state; if (max_state == 0) return sprintf(buf, "Not Supported.\n"); @@ -1708,19 +1707,17 @@ static ssize_t trans_stat_show(struct device *dev, len += sprintf(buf + len, " :"); for (i = 0; i < max_state; i++) len += sprintf(buf + len, "%10lu", - df->profile->freq_table[i]); + df->freq_table[i]); len += sprintf(buf + len, " time(ms)\n"); for (i = 0; i < max_state; i++) { - if (df->profile->freq_table[i] - == df->previous_freq) { + if (df->freq_table[i] == df->previous_freq) len += sprintf(buf + len, "*"); - } else { + else len += sprintf(buf + len, " "); - } - len += sprintf(buf + len, "%10lu:", - df->profile->freq_table[i]); + + len += sprintf(buf + len, "%10lu:", df->freq_table[i]); for (j = 0; j < max_state; j++) len += sprintf(buf + len, "%10u", df->stats.trans_table[(i * max_state) + j]); @@ -1744,7 +1741,7 @@ static ssize_t trans_stat_store(struct device *dev, if (!df->profile) return -EINVAL; - if (df->profile->max_state == 0) + if (df->max_state == 0) return count; err = kstrtoint(buf, 10, &value); @@ -1752,11 +1749,11 @@ static ssize_t trans_stat_store(struct device *dev, return -EINVAL; mutex_lock(&df->lock); - memset(df->stats.time_in_state, 0, (df->profile->max_state * + memset(df->stats.time_in_state, 0, (df->max_state * sizeof(*df->stats.time_in_state))); memset(df->stats.trans_table, 0, array3_size(sizeof(unsigned int), - df->profile->max_state, - df->profile->max_state)); + df->max_state, + df->max_state)); df->stats.total_trans = 0; df->stats.last_update = get_jiffies_64(); mutex_unlock(&df->lock); diff --git a/drivers/devfreq/governor_passive.c b/drivers/devfreq/governor_passive.c index 69e06725d92b..406ef79c0c46 100644 --- a/drivers/devfreq/governor_passive.c +++ b/drivers/devfreq/governor_passive.c @@ -144,18 +144,18 @@ static int get_target_freq_with_devfreq(struct devfreq *devfreq, goto out; /* Use interpolation if required opps is not available */ - for (i = 0; i < parent_devfreq->profile->max_state; i++) - if (parent_devfreq->profile->freq_table[i] == *freq) + for (i = 0; i < parent_devfreq->max_state; i++) + if (parent_devfreq->freq_table[i] == *freq) break; - if (i == parent_devfreq->profile->max_state) + if (i == parent_devfreq->max_state) return -EINVAL; - if (i < devfreq->profile->max_state) { - child_freq = devfreq->profile->freq_table[i]; + if (i < devfreq->max_state) { + child_freq = devfreq->freq_table[i]; } else { - count = devfreq->profile->max_state; - child_freq = devfreq->profile->freq_table[count - 1]; + count = devfreq->max_state; + child_freq = devfreq->freq_table[count - 1]; } out: diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index dc10bee75a72..34aab4dd336c 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -148,6 +148,8 @@ struct devfreq_stats { * reevaluate operable frequencies. Devfreq users may use * devfreq.nb to the corresponding register notifier call chain. * @work: delayed work for load monitoring. + * @freq_table: current frequency table used by the devfreq driver. + * @max_state: count of entry present in the frequency table. * @previous_freq: previously configured frequency value. * @last_status: devfreq user device info, performance statistics * @data: Private data of the governor. The devfreq framework does not @@ -185,6 +187,9 @@ struct devfreq { struct notifier_block nb; struct delayed_work work; + unsigned long *freq_table; + unsigned int max_state; + unsigned long previous_freq; struct devfreq_dev_status last_status; -- cgit v1.2.3 From 82c66d2bbbeda9e493487e7413769087a0b46250 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Mon, 20 Jun 2022 00:29:39 +0200 Subject: PM / devfreq: Fix kernel warning with cpufreq passive register fail Remove cpufreq_passive_unregister_notifier from cpufreq_passive_register_notifier in case of error as devfreq core already call unregister on GOV_START fail. This fix the kernel always printing a WARN on governor PROBE_DEFER as cpufreq_passive_unregister_notifier is called two times and return error on the second call as the cpufreq is already unregistered. Fixes: a03dacb0316f ("PM / devfreq: Add cpu based scaling support to passive governor") Signed-off-by: Christian Marangi Signed-off-by: Chanwoo Choi --- drivers/devfreq/governor_passive.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/devfreq/governor_passive.c b/drivers/devfreq/governor_passive.c index 406ef79c0c46..bce487cc8f3e 100644 --- a/drivers/devfreq/governor_passive.c +++ b/drivers/devfreq/governor_passive.c @@ -330,7 +330,6 @@ err_free_cpu_data: err_put_policy: cpufreq_cpu_put(policy); err: - WARN_ON(cpufreq_passive_unregister_notifier(devfreq)); return ret; } -- cgit v1.2.3 From f08fe6fcbe13f83558ecccc4acaf5af3dce71a1f Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Tue, 28 Jun 2022 07:34:11 +0200 Subject: PM / devfreq: passive: revert an editing accident in SPDX-License line Commit 26984d9d581e ("PM / devfreq: passive: Keep cpufreq_policy for possible cpus") reworked governor_passive.c, and accidently added a tab in the first line, i.e., the SPDX-License-Identifier line. The checkpatch script warns with the SPDX_LICENSE_TAG warning, and hence pointed this issue out while investigating checkpatch warnings. Revert this editing accident. No functional change. Signed-off-by: Lukas Bulwahn Signed-off-by: Chanwoo Choi --- drivers/devfreq/governor_passive.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/devfreq/governor_passive.c b/drivers/devfreq/governor_passive.c index bce487cc8f3e..953cf9a1e9f7 100644 --- a/drivers/devfreq/governor_passive.c +++ b/drivers/devfreq/governor_passive.c @@ -1,4 +1,4 @@ - // SPDX-License-Identifier: GPL-2.0-only +// SPDX-License-Identifier: GPL-2.0-only /* * linux/drivers/devfreq/governor_passive.c * -- cgit v1.2.3