You've already forked linux-rockchip
mirror of
https://github.com/armbian/linux-rockchip.git
synced 2026-01-06 11:08:10 -08:00
Merge tag 'pm-5.20-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull more power management updates from Rafael Wysocki:
"These are ARM cpufreq updates and operating performance points (OPP)
updates plus one cpuidle update adding a new trace point.
Specifics:
- Fix return error code in mtk_cpu_dvfs_info_init (Yang Yingliang).
- Minor cleanups and support for new boards for Qcom cpufreq drivers
(Bryan O'Donoghue, Konrad Dybcio, Pierre Gondois, and Yicong Yang).
- Fix sparse warnings for Tegra cpufreq driver (Viresh Kumar).
- Make dev_pm_opp_set_regulators() accept NULL terminated list
(Viresh Kumar).
- Add dev_pm_opp_set_config() and friends and migrate other users and
helpers to using them (Viresh Kumar).
- Add support for multiple clocks for a device (Viresh Kumar and
Krzysztof Kozlowski).
- Configure resources before adding OPP table for Venus (Stanimir
Varbanov).
- Keep reference count up for opp->np and opp_table->np while they
are still in use (Liang He).
- Minor OPP cleanups (Viresh Kumar and Yang Li).
- Add a trace event for cpuidle to track missed (too deep or too
shallow) wakeups (Kajetan Puchalski)"
* tag 'pm-5.20-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (55 commits)
cpuidle: Add cpu_idle_miss trace event
venus: pm_helpers: Fix warning in OPP during probe
OPP: Don't drop opp->np reference while it is still in use
OPP: Don't drop opp_table->np reference while it is still in use
cpufreq: tegra194: Staticize struct tegra_cpufreq_soc instances
dt-bindings: cpufreq: cpufreq-qcom-hw: Add SM6375 compatible
dt-bindings: opp: Add msm8939 to the compatible list
dt-bindings: opp: Add missing compat devices
dt-bindings: opp: opp-v2-kryo-cpu: Fix example binding checks
cpufreq: Change order of online() CB and policy->cpus modification
cpufreq: qcom-hw: Remove deprecated irq_set_affinity_hint() call
cpufreq: qcom-hw: Disable LMH irq when disabling policy
cpufreq: qcom-hw: Reset cancel_throttle when policy is re-enabled
cpufreq: qcom-cpufreq-hw: use HZ_PER_KHZ macro in units.h
cpufreq: mediatek: fix error return code in mtk_cpu_dvfs_info_init()
OPP: Remove dev{m}_pm_opp_of_add_table_noclk()
PM / devfreq: tegra30: Register config_clks helper
OPP: Allow config_clks helper for single clk case
OPP: Provide a simple implementation to configure multiple clocks
OPP: Assert clk_count == 1 for single clk helpers
...
This commit is contained in:
@@ -25,6 +25,7 @@ properties:
|
||||
- description: v2 of CPUFREQ HW (EPSS)
|
||||
items:
|
||||
- enum:
|
||||
- qcom,sm6375-cpufreq-epss
|
||||
- qcom,sm8250-cpufreq-epss
|
||||
- const: qcom,cpufreq-epss
|
||||
|
||||
|
||||
@@ -22,6 +22,13 @@ select:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,apq8064
|
||||
- qcom,apq8096
|
||||
- qcom,ipq8064
|
||||
- qcom,msm8939
|
||||
- qcom,msm8960
|
||||
- qcom,msm8974
|
||||
- qcom,msm8996
|
||||
- qcom,qcs404
|
||||
required:
|
||||
- compatible
|
||||
|
||||
@@ -50,6 +50,16 @@ patternProperties:
|
||||
property to uniquely identify the OPP nodes exists. Devices like power
|
||||
domains must have another (implementation dependent) property.
|
||||
|
||||
Entries for multiple clocks shall be provided in the same field, as
|
||||
array of frequencies. The OPP binding doesn't provide any provisions
|
||||
to relate the values to their clocks or the order in which the clocks
|
||||
need to be configured and that is left for the implementation
|
||||
specific binding.
|
||||
minItems: 1
|
||||
maxItems: 16
|
||||
items:
|
||||
maxItems: 1
|
||||
|
||||
opp-microvolt:
|
||||
description: |
|
||||
Voltage for the OPP
|
||||
|
||||
@@ -98,6 +98,8 @@ examples:
|
||||
capacity-dmips-mhz = <1024>;
|
||||
clocks = <&kryocc 0>;
|
||||
operating-points-v2 = <&cluster0_opp>;
|
||||
power-domains = <&cpr>;
|
||||
power-domain-names = "cpr";
|
||||
#cooling-cells = <2>;
|
||||
next-level-cache = <&L2_0>;
|
||||
L2_0: l2-cache {
|
||||
@@ -115,6 +117,8 @@ examples:
|
||||
capacity-dmips-mhz = <1024>;
|
||||
clocks = <&kryocc 0>;
|
||||
operating-points-v2 = <&cluster0_opp>;
|
||||
power-domains = <&cpr>;
|
||||
power-domain-names = "cpr";
|
||||
#cooling-cells = <2>;
|
||||
next-level-cache = <&L2_0>;
|
||||
};
|
||||
@@ -128,6 +132,8 @@ examples:
|
||||
capacity-dmips-mhz = <1024>;
|
||||
clocks = <&kryocc 1>;
|
||||
operating-points-v2 = <&cluster1_opp>;
|
||||
power-domains = <&cpr>;
|
||||
power-domain-names = "cpr";
|
||||
#cooling-cells = <2>;
|
||||
next-level-cache = <&L2_1>;
|
||||
L2_1: l2-cache {
|
||||
@@ -145,6 +151,8 @@ examples:
|
||||
capacity-dmips-mhz = <1024>;
|
||||
clocks = <&kryocc 1>;
|
||||
operating-points-v2 = <&cluster1_opp>;
|
||||
power-domains = <&cpr>;
|
||||
power-domain-names = "cpr";
|
||||
#cooling-cells = <2>;
|
||||
next-level-cache = <&L2_1>;
|
||||
};
|
||||
@@ -182,18 +190,21 @@ examples:
|
||||
opp-microvolt = <905000 905000 1140000>;
|
||||
opp-supported-hw = <0x7>;
|
||||
clock-latency-ns = <200000>;
|
||||
required-opps = <&cpr_opp1>;
|
||||
};
|
||||
opp-1401600000 {
|
||||
opp-hz = /bits/ 64 <1401600000>;
|
||||
opp-microvolt = <1140000 905000 1140000>;
|
||||
opp-supported-hw = <0x5>;
|
||||
clock-latency-ns = <200000>;
|
||||
required-opps = <&cpr_opp2>;
|
||||
};
|
||||
opp-1593600000 {
|
||||
opp-hz = /bits/ 64 <1593600000>;
|
||||
opp-microvolt = <1140000 905000 1140000>;
|
||||
opp-supported-hw = <0x1>;
|
||||
clock-latency-ns = <200000>;
|
||||
required-opps = <&cpr_opp3>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -207,24 +218,28 @@ examples:
|
||||
opp-microvolt = <905000 905000 1140000>;
|
||||
opp-supported-hw = <0x7>;
|
||||
clock-latency-ns = <200000>;
|
||||
required-opps = <&cpr_opp1>;
|
||||
};
|
||||
opp-1804800000 {
|
||||
opp-hz = /bits/ 64 <1804800000>;
|
||||
opp-microvolt = <1140000 905000 1140000>;
|
||||
opp-supported-hw = <0x6>;
|
||||
clock-latency-ns = <200000>;
|
||||
required-opps = <&cpr_opp4>;
|
||||
};
|
||||
opp-1900800000 {
|
||||
opp-hz = /bits/ 64 <1900800000>;
|
||||
opp-microvolt = <1140000 905000 1140000>;
|
||||
opp-supported-hw = <0x4>;
|
||||
clock-latency-ns = <200000>;
|
||||
required-opps = <&cpr_opp5>;
|
||||
};
|
||||
opp-2150400000 {
|
||||
opp-hz = /bits/ 64 <2150400000>;
|
||||
opp-microvolt = <1140000 905000 1140000>;
|
||||
opp-supported-hw = <0x1>;
|
||||
clock-latency-ns = <200000>;
|
||||
required-opps = <&cpr_opp6>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -29,9 +29,9 @@ struct private_data {
|
||||
|
||||
cpumask_var_t cpus;
|
||||
struct device *cpu_dev;
|
||||
struct opp_table *opp_table;
|
||||
struct cpufreq_frequency_table *freq_table;
|
||||
bool have_static_opps;
|
||||
int opp_token;
|
||||
};
|
||||
|
||||
static LIST_HEAD(priv_list);
|
||||
@@ -193,7 +193,7 @@ static int dt_cpufreq_early_init(struct device *dev, int cpu)
|
||||
struct private_data *priv;
|
||||
struct device *cpu_dev;
|
||||
bool fallback = false;
|
||||
const char *reg_name;
|
||||
const char *reg_name[] = { NULL, NULL };
|
||||
int ret;
|
||||
|
||||
/* Check if this CPU is already covered by some other policy */
|
||||
@@ -218,12 +218,11 @@ static int dt_cpufreq_early_init(struct device *dev, int cpu)
|
||||
* OPP layer will be taking care of regulators now, but it needs to know
|
||||
* the name of the regulator first.
|
||||
*/
|
||||
reg_name = find_supply_name(cpu_dev);
|
||||
if (reg_name) {
|
||||
priv->opp_table = dev_pm_opp_set_regulators(cpu_dev, ®_name,
|
||||
1);
|
||||
if (IS_ERR(priv->opp_table)) {
|
||||
ret = PTR_ERR(priv->opp_table);
|
||||
reg_name[0] = find_supply_name(cpu_dev);
|
||||
if (reg_name[0]) {
|
||||
priv->opp_token = dev_pm_opp_set_regulators(cpu_dev, reg_name);
|
||||
if (priv->opp_token < 0) {
|
||||
ret = priv->opp_token;
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(cpu_dev, "failed to set regulators: %d\n",
|
||||
ret);
|
||||
@@ -295,7 +294,7 @@ static int dt_cpufreq_early_init(struct device *dev, int cpu)
|
||||
out:
|
||||
if (priv->have_static_opps)
|
||||
dev_pm_opp_of_cpumask_remove_table(priv->cpus);
|
||||
dev_pm_opp_put_regulators(priv->opp_table);
|
||||
dev_pm_opp_put_regulators(priv->opp_token);
|
||||
free_cpumask:
|
||||
free_cpumask_var(priv->cpus);
|
||||
return ret;
|
||||
@@ -309,7 +308,7 @@ static void dt_cpufreq_release(void)
|
||||
dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &priv->freq_table);
|
||||
if (priv->have_static_opps)
|
||||
dev_pm_opp_of_cpumask_remove_table(priv->cpus);
|
||||
dev_pm_opp_put_regulators(priv->opp_table);
|
||||
dev_pm_opp_put_regulators(priv->opp_token);
|
||||
free_cpumask_var(priv->cpus);
|
||||
list_del(&priv->node);
|
||||
}
|
||||
|
||||
@@ -1348,15 +1348,15 @@ static int cpufreq_online(unsigned int cpu)
|
||||
}
|
||||
|
||||
if (!new_policy && cpufreq_driver->online) {
|
||||
/* Recover policy->cpus using related_cpus */
|
||||
cpumask_copy(policy->cpus, policy->related_cpus);
|
||||
|
||||
ret = cpufreq_driver->online(policy);
|
||||
if (ret) {
|
||||
pr_debug("%s: %d: initialization failed\n", __func__,
|
||||
__LINE__);
|
||||
goto out_exit_policy;
|
||||
}
|
||||
|
||||
/* Recover policy->cpus using related_cpus */
|
||||
cpumask_copy(policy->cpus, policy->related_cpus);
|
||||
} else {
|
||||
cpumask_copy(policy->cpus, cpumask_of(cpu));
|
||||
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
|
||||
/* cpufreq-dt device registered by imx-cpufreq-dt */
|
||||
static struct platform_device *cpufreq_dt_pdev;
|
||||
static struct opp_table *cpufreq_opp_table;
|
||||
static struct device *cpu_dev;
|
||||
static int cpufreq_opp_token;
|
||||
|
||||
enum IMX7ULP_CPUFREQ_CLKS {
|
||||
ARM,
|
||||
@@ -153,9 +153,9 @@ static int imx_cpufreq_dt_probe(struct platform_device *pdev)
|
||||
dev_info(&pdev->dev, "cpu speed grade %d mkt segment %d supported-hw %#x %#x\n",
|
||||
speed_grade, mkt_segment, supported_hw[0], supported_hw[1]);
|
||||
|
||||
cpufreq_opp_table = dev_pm_opp_set_supported_hw(cpu_dev, supported_hw, 2);
|
||||
if (IS_ERR(cpufreq_opp_table)) {
|
||||
ret = PTR_ERR(cpufreq_opp_table);
|
||||
cpufreq_opp_token = dev_pm_opp_set_supported_hw(cpu_dev, supported_hw, 2);
|
||||
if (cpufreq_opp_token < 0) {
|
||||
ret = cpufreq_opp_token;
|
||||
dev_err(&pdev->dev, "Failed to set supported opp: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
@@ -163,7 +163,7 @@ static int imx_cpufreq_dt_probe(struct platform_device *pdev)
|
||||
cpufreq_dt_pdev = platform_device_register_data(
|
||||
&pdev->dev, "cpufreq-dt", -1, NULL, 0);
|
||||
if (IS_ERR(cpufreq_dt_pdev)) {
|
||||
dev_pm_opp_put_supported_hw(cpufreq_opp_table);
|
||||
dev_pm_opp_put_supported_hw(cpufreq_opp_token);
|
||||
ret = PTR_ERR(cpufreq_dt_pdev);
|
||||
dev_err(&pdev->dev, "Failed to register cpufreq-dt: %d\n", ret);
|
||||
return ret;
|
||||
@@ -176,7 +176,7 @@ static int imx_cpufreq_dt_remove(struct platform_device *pdev)
|
||||
{
|
||||
platform_device_unregister(cpufreq_dt_pdev);
|
||||
if (!of_machine_is_compatible("fsl,imx7ulp"))
|
||||
dev_pm_opp_put_supported_hw(cpufreq_opp_table);
|
||||
dev_pm_opp_put_supported_hw(cpufreq_opp_token);
|
||||
else
|
||||
clk_bulk_put(ARRAY_SIZE(imx7ulp_clks), imx7ulp_clks);
|
||||
|
||||
|
||||
@@ -478,6 +478,7 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
|
||||
if (info->soc_data->ccifreq_supported) {
|
||||
info->vproc_on_boot = regulator_get_voltage(info->proc_reg);
|
||||
if (info->vproc_on_boot < 0) {
|
||||
ret = info->vproc_on_boot;
|
||||
dev_err(info->cpu_dev,
|
||||
"invalid Vproc value: %d\n", info->vproc_on_boot);
|
||||
goto out_disable_inter_clock;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <linux/pm_opp.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/units.h>
|
||||
|
||||
#define LUT_MAX_ENTRIES 40U
|
||||
#define LUT_SRC GENMASK(31, 30)
|
||||
@@ -26,8 +27,6 @@
|
||||
|
||||
#define GT_IRQ_STATUS BIT(2)
|
||||
|
||||
#define HZ_PER_KHZ 1000
|
||||
|
||||
struct qcom_cpufreq_soc_data {
|
||||
u32 reg_enable;
|
||||
u32 reg_domain_state;
|
||||
@@ -428,7 +427,7 @@ static int qcom_cpufreq_hw_lmh_init(struct cpufreq_policy *policy, int index)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = irq_set_affinity_hint(data->throttle_irq, policy->cpus);
|
||||
ret = irq_set_affinity_and_hint(data->throttle_irq, policy->cpus);
|
||||
if (ret)
|
||||
dev_err(&pdev->dev, "Failed to set CPU affinity of %s[%d]\n",
|
||||
data->irq_name, data->throttle_irq);
|
||||
@@ -445,7 +444,11 @@ static int qcom_cpufreq_hw_cpu_online(struct cpufreq_policy *policy)
|
||||
if (data->throttle_irq <= 0)
|
||||
return 0;
|
||||
|
||||
ret = irq_set_affinity_hint(data->throttle_irq, policy->cpus);
|
||||
mutex_lock(&data->throttle_lock);
|
||||
data->cancel_throttle = false;
|
||||
mutex_unlock(&data->throttle_lock);
|
||||
|
||||
ret = irq_set_affinity_and_hint(data->throttle_irq, policy->cpus);
|
||||
if (ret)
|
||||
dev_err(&pdev->dev, "Failed to set CPU affinity of %s[%d]\n",
|
||||
data->irq_name, data->throttle_irq);
|
||||
@@ -465,7 +468,8 @@ static int qcom_cpufreq_hw_cpu_offline(struct cpufreq_policy *policy)
|
||||
mutex_unlock(&data->throttle_lock);
|
||||
|
||||
cancel_delayed_work_sync(&data->throttle_work);
|
||||
irq_set_affinity_hint(data->throttle_irq, NULL);
|
||||
irq_set_affinity_and_hint(data->throttle_irq, NULL);
|
||||
disable_irq_nosync(data->throttle_irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -55,9 +55,7 @@ struct qcom_cpufreq_match_data {
|
||||
};
|
||||
|
||||
struct qcom_cpufreq_drv {
|
||||
struct opp_table **names_opp_tables;
|
||||
struct opp_table **hw_opp_tables;
|
||||
struct opp_table **genpd_opp_tables;
|
||||
int *opp_tokens;
|
||||
u32 versions;
|
||||
const struct qcom_cpufreq_match_data *data;
|
||||
};
|
||||
@@ -315,72 +313,43 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
|
||||
}
|
||||
of_node_put(np);
|
||||
|
||||
drv->names_opp_tables = kcalloc(num_possible_cpus(),
|
||||
sizeof(*drv->names_opp_tables),
|
||||
drv->opp_tokens = kcalloc(num_possible_cpus(), sizeof(*drv->opp_tokens),
|
||||
GFP_KERNEL);
|
||||
if (!drv->names_opp_tables) {
|
||||
if (!drv->opp_tokens) {
|
||||
ret = -ENOMEM;
|
||||
goto free_drv;
|
||||
}
|
||||
drv->hw_opp_tables = kcalloc(num_possible_cpus(),
|
||||
sizeof(*drv->hw_opp_tables),
|
||||
GFP_KERNEL);
|
||||
if (!drv->hw_opp_tables) {
|
||||
ret = -ENOMEM;
|
||||
goto free_opp_names;
|
||||
}
|
||||
|
||||
drv->genpd_opp_tables = kcalloc(num_possible_cpus(),
|
||||
sizeof(*drv->genpd_opp_tables),
|
||||
GFP_KERNEL);
|
||||
if (!drv->genpd_opp_tables) {
|
||||
ret = -ENOMEM;
|
||||
goto free_opp;
|
||||
}
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
struct dev_pm_opp_config config = {
|
||||
.supported_hw = NULL,
|
||||
};
|
||||
|
||||
cpu_dev = get_cpu_device(cpu);
|
||||
if (NULL == cpu_dev) {
|
||||
ret = -ENODEV;
|
||||
goto free_genpd_opp;
|
||||
goto free_opp;
|
||||
}
|
||||
|
||||
if (drv->data->get_version) {
|
||||
config.supported_hw = &drv->versions;
|
||||
config.supported_hw_count = 1;
|
||||
|
||||
if (pvs_name) {
|
||||
drv->names_opp_tables[cpu] = dev_pm_opp_set_prop_name(
|
||||
cpu_dev,
|
||||
pvs_name);
|
||||
if (IS_ERR(drv->names_opp_tables[cpu])) {
|
||||
ret = PTR_ERR(drv->names_opp_tables[cpu]);
|
||||
dev_err(cpu_dev, "Failed to add OPP name %s\n",
|
||||
pvs_name);
|
||||
goto free_opp;
|
||||
}
|
||||
}
|
||||
|
||||
drv->hw_opp_tables[cpu] = dev_pm_opp_set_supported_hw(
|
||||
cpu_dev, &drv->versions, 1);
|
||||
if (IS_ERR(drv->hw_opp_tables[cpu])) {
|
||||
ret = PTR_ERR(drv->hw_opp_tables[cpu]);
|
||||
dev_err(cpu_dev,
|
||||
"Failed to set supported hardware\n");
|
||||
goto free_genpd_opp;
|
||||
}
|
||||
if (pvs_name)
|
||||
config.prop_name = pvs_name;
|
||||
}
|
||||
|
||||
if (drv->data->genpd_names) {
|
||||
drv->genpd_opp_tables[cpu] =
|
||||
dev_pm_opp_attach_genpd(cpu_dev,
|
||||
drv->data->genpd_names,
|
||||
NULL);
|
||||
if (IS_ERR(drv->genpd_opp_tables[cpu])) {
|
||||
ret = PTR_ERR(drv->genpd_opp_tables[cpu]);
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(cpu_dev,
|
||||
"Could not attach to pm_domain: %d\n",
|
||||
ret);
|
||||
goto free_genpd_opp;
|
||||
config.genpd_names = drv->data->genpd_names;
|
||||
config.virt_devs = NULL;
|
||||
}
|
||||
|
||||
if (config.supported_hw || config.genpd_names) {
|
||||
drv->opp_tokens[cpu] = dev_pm_opp_set_config(cpu_dev, &config);
|
||||
if (drv->opp_tokens[cpu] < 0) {
|
||||
ret = drv->opp_tokens[cpu];
|
||||
dev_err(cpu_dev, "Failed to set OPP config\n");
|
||||
goto free_opp;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -395,27 +364,10 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
|
||||
ret = PTR_ERR(cpufreq_dt_pdev);
|
||||
dev_err(cpu_dev, "Failed to register platform device\n");
|
||||
|
||||
free_genpd_opp:
|
||||
for_each_possible_cpu(cpu) {
|
||||
if (IS_ERR(drv->genpd_opp_tables[cpu]))
|
||||
break;
|
||||
dev_pm_opp_detach_genpd(drv->genpd_opp_tables[cpu]);
|
||||
}
|
||||
kfree(drv->genpd_opp_tables);
|
||||
free_opp:
|
||||
for_each_possible_cpu(cpu) {
|
||||
if (IS_ERR(drv->names_opp_tables[cpu]))
|
||||
break;
|
||||
dev_pm_opp_put_prop_name(drv->names_opp_tables[cpu]);
|
||||
}
|
||||
for_each_possible_cpu(cpu) {
|
||||
if (IS_ERR(drv->hw_opp_tables[cpu]))
|
||||
break;
|
||||
dev_pm_opp_put_supported_hw(drv->hw_opp_tables[cpu]);
|
||||
}
|
||||
kfree(drv->hw_opp_tables);
|
||||
free_opp_names:
|
||||
kfree(drv->names_opp_tables);
|
||||
for_each_possible_cpu(cpu)
|
||||
dev_pm_opp_clear_config(drv->opp_tokens[cpu]);
|
||||
kfree(drv->opp_tokens);
|
||||
free_drv:
|
||||
kfree(drv);
|
||||
|
||||
@@ -429,15 +381,10 @@ static int qcom_cpufreq_remove(struct platform_device *pdev)
|
||||
|
||||
platform_device_unregister(cpufreq_dt_pdev);
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
dev_pm_opp_put_supported_hw(drv->names_opp_tables[cpu]);
|
||||
dev_pm_opp_put_supported_hw(drv->hw_opp_tables[cpu]);
|
||||
dev_pm_opp_detach_genpd(drv->genpd_opp_tables[cpu]);
|
||||
}
|
||||
for_each_possible_cpu(cpu)
|
||||
dev_pm_opp_clear_config(drv->opp_tokens[cpu]);
|
||||
|
||||
kfree(drv->names_opp_tables);
|
||||
kfree(drv->hw_opp_tables);
|
||||
kfree(drv->genpd_opp_tables);
|
||||
kfree(drv->opp_tokens);
|
||||
kfree(drv);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -156,9 +156,13 @@ static int sti_cpufreq_set_opp_info(void)
|
||||
unsigned int hw_info_offset;
|
||||
unsigned int version[VERSION_ELEMENTS];
|
||||
int pcode, substrate, major, minor;
|
||||
int ret;
|
||||
int opp_token, ret;
|
||||
char name[MAX_PCODE_NAME_LEN];
|
||||
struct opp_table *opp_table;
|
||||
struct dev_pm_opp_config config = {
|
||||
.supported_hw = version,
|
||||
.supported_hw_count = ARRAY_SIZE(version),
|
||||
.prop_name = name,
|
||||
};
|
||||
|
||||
reg_fields = sti_cpufreq_match();
|
||||
if (!reg_fields) {
|
||||
@@ -210,21 +214,14 @@ use_defaults:
|
||||
|
||||
snprintf(name, MAX_PCODE_NAME_LEN, "pcode%d", pcode);
|
||||
|
||||
opp_table = dev_pm_opp_set_prop_name(dev, name);
|
||||
if (IS_ERR(opp_table)) {
|
||||
dev_err(dev, "Failed to set prop name\n");
|
||||
return PTR_ERR(opp_table);
|
||||
}
|
||||
|
||||
version[0] = BIT(major);
|
||||
version[1] = BIT(minor);
|
||||
version[2] = BIT(substrate);
|
||||
|
||||
opp_table = dev_pm_opp_set_supported_hw(dev, version, VERSION_ELEMENTS);
|
||||
if (IS_ERR(opp_table)) {
|
||||
dev_err(dev, "Failed to set supported hardware\n");
|
||||
ret = PTR_ERR(opp_table);
|
||||
goto err_put_prop_name;
|
||||
opp_token = dev_pm_opp_set_config(dev, &config);
|
||||
if (opp_token < 0) {
|
||||
dev_err(dev, "Failed to set OPP config\n");
|
||||
return opp_token;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "pcode: %d major: %d minor: %d substrate: %d\n",
|
||||
@@ -233,10 +230,6 @@ use_defaults:
|
||||
version[0], version[1], version[2]);
|
||||
|
||||
return 0;
|
||||
|
||||
err_put_prop_name:
|
||||
dev_pm_opp_put_prop_name(opp_table);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sti_cpufreq_fetch_syscon_registers(void)
|
||||
|
||||
@@ -86,20 +86,20 @@ static int sun50i_cpufreq_get_efuse(u32 *versions)
|
||||
|
||||
static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct opp_table **opp_tables;
|
||||
int *opp_tokens;
|
||||
char name[MAX_NAME_LEN];
|
||||
unsigned int cpu;
|
||||
u32 speed = 0;
|
||||
int ret;
|
||||
|
||||
opp_tables = kcalloc(num_possible_cpus(), sizeof(*opp_tables),
|
||||
opp_tokens = kcalloc(num_possible_cpus(), sizeof(*opp_tokens),
|
||||
GFP_KERNEL);
|
||||
if (!opp_tables)
|
||||
if (!opp_tokens)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = sun50i_cpufreq_get_efuse(&speed);
|
||||
if (ret) {
|
||||
kfree(opp_tables);
|
||||
kfree(opp_tokens);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -113,9 +113,9 @@ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev)
|
||||
goto free_opp;
|
||||
}
|
||||
|
||||
opp_tables[cpu] = dev_pm_opp_set_prop_name(cpu_dev, name);
|
||||
if (IS_ERR(opp_tables[cpu])) {
|
||||
ret = PTR_ERR(opp_tables[cpu]);
|
||||
opp_tokens[cpu] = dev_pm_opp_set_prop_name(cpu_dev, name);
|
||||
if (opp_tokens[cpu] < 0) {
|
||||
ret = opp_tokens[cpu];
|
||||
pr_err("Failed to set prop name\n");
|
||||
goto free_opp;
|
||||
}
|
||||
@@ -124,7 +124,7 @@ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev)
|
||||
cpufreq_dt_pdev = platform_device_register_simple("cpufreq-dt", -1,
|
||||
NULL, 0);
|
||||
if (!IS_ERR(cpufreq_dt_pdev)) {
|
||||
platform_set_drvdata(pdev, opp_tables);
|
||||
platform_set_drvdata(pdev, opp_tokens);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -132,27 +132,24 @@ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev)
|
||||
pr_err("Failed to register platform device\n");
|
||||
|
||||
free_opp:
|
||||
for_each_possible_cpu(cpu) {
|
||||
if (IS_ERR_OR_NULL(opp_tables[cpu]))
|
||||
break;
|
||||
dev_pm_opp_put_prop_name(opp_tables[cpu]);
|
||||
}
|
||||
kfree(opp_tables);
|
||||
for_each_possible_cpu(cpu)
|
||||
dev_pm_opp_put_prop_name(opp_tokens[cpu]);
|
||||
kfree(opp_tokens);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sun50i_cpufreq_nvmem_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct opp_table **opp_tables = platform_get_drvdata(pdev);
|
||||
int *opp_tokens = platform_get_drvdata(pdev);
|
||||
unsigned int cpu;
|
||||
|
||||
platform_device_unregister(cpufreq_dt_pdev);
|
||||
|
||||
for_each_possible_cpu(cpu)
|
||||
dev_pm_opp_put_prop_name(opp_tables[cpu]);
|
||||
dev_pm_opp_put_prop_name(opp_tokens[cpu]);
|
||||
|
||||
kfree(opp_tables);
|
||||
kfree(opp_tokens);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ static struct tegra_cpufreq_ops tegra234_cpufreq_ops = {
|
||||
.set_cpu_ndiv = tegra234_set_cpu_ndiv,
|
||||
};
|
||||
|
||||
const struct tegra_cpufreq_soc tegra234_cpufreq_soc = {
|
||||
static const struct tegra_cpufreq_soc tegra234_cpufreq_soc = {
|
||||
.ops = &tegra234_cpufreq_ops,
|
||||
.actmon_cntr_base = 0x9000,
|
||||
.maxcpus_per_cluster = 4,
|
||||
@@ -430,7 +430,7 @@ static struct tegra_cpufreq_ops tegra194_cpufreq_ops = {
|
||||
.set_cpu_ndiv = tegra194_set_cpu_ndiv,
|
||||
};
|
||||
|
||||
const struct tegra_cpufreq_soc tegra194_cpufreq_soc = {
|
||||
static const struct tegra_cpufreq_soc tegra194_cpufreq_soc = {
|
||||
.ops = &tegra194_cpufreq_ops,
|
||||
.maxcpus_per_cluster = 2,
|
||||
};
|
||||
|
||||
@@ -32,9 +32,9 @@ static bool cpu0_node_has_opp_v2_prop(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void tegra20_cpufreq_put_supported_hw(void *opp_table)
|
||||
static void tegra20_cpufreq_put_supported_hw(void *opp_token)
|
||||
{
|
||||
dev_pm_opp_put_supported_hw(opp_table);
|
||||
dev_pm_opp_put_supported_hw((unsigned long) opp_token);
|
||||
}
|
||||
|
||||
static void tegra20_cpufreq_dt_unregister(void *cpufreq_dt)
|
||||
@@ -45,7 +45,6 @@ static void tegra20_cpufreq_dt_unregister(void *cpufreq_dt)
|
||||
static int tegra20_cpufreq_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct platform_device *cpufreq_dt;
|
||||
struct opp_table *opp_table;
|
||||
struct device *cpu_dev;
|
||||
u32 versions[2];
|
||||
int err;
|
||||
@@ -71,16 +70,15 @@ static int tegra20_cpufreq_probe(struct platform_device *pdev)
|
||||
if (WARN_ON(!cpu_dev))
|
||||
return -ENODEV;
|
||||
|
||||
opp_table = dev_pm_opp_set_supported_hw(cpu_dev, versions, 2);
|
||||
err = PTR_ERR_OR_ZERO(opp_table);
|
||||
if (err) {
|
||||
err = dev_pm_opp_set_supported_hw(cpu_dev, versions, 2);
|
||||
if (err < 0) {
|
||||
dev_err(&pdev->dev, "failed to set supported hw: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = devm_add_action_or_reset(&pdev->dev,
|
||||
tegra20_cpufreq_put_supported_hw,
|
||||
opp_table);
|
||||
(void *)((unsigned long) err));
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
||||
@@ -60,7 +60,6 @@ struct ti_cpufreq_data {
|
||||
struct device_node *opp_node;
|
||||
struct regmap *syscon;
|
||||
const struct ti_cpufreq_soc_data *soc_data;
|
||||
struct opp_table *opp_table;
|
||||
};
|
||||
|
||||
static unsigned long amx3_efuse_xlate(struct ti_cpufreq_data *opp_data,
|
||||
@@ -173,7 +172,7 @@ static struct ti_cpufreq_soc_data omap34xx_soc_data = {
|
||||
* seems to always read as 0).
|
||||
*/
|
||||
|
||||
static const char * const omap3_reg_names[] = {"cpu0", "vbb"};
|
||||
static const char * const omap3_reg_names[] = {"cpu0", "vbb", NULL};
|
||||
|
||||
static struct ti_cpufreq_soc_data omap36xx_soc_data = {
|
||||
.reg_names = omap3_reg_names,
|
||||
@@ -324,10 +323,13 @@ static int ti_cpufreq_probe(struct platform_device *pdev)
|
||||
{
|
||||
u32 version[VERSION_COUNT];
|
||||
const struct of_device_id *match;
|
||||
struct opp_table *ti_opp_table;
|
||||
struct ti_cpufreq_data *opp_data;
|
||||
const char * const default_reg_names[] = {"vdd", "vbb"};
|
||||
const char * const default_reg_names[] = {"vdd", "vbb", NULL};
|
||||
int ret;
|
||||
struct dev_pm_opp_config config = {
|
||||
.supported_hw = version,
|
||||
.supported_hw_count = ARRAY_SIZE(version),
|
||||
};
|
||||
|
||||
match = dev_get_platdata(&pdev->dev);
|
||||
if (!match)
|
||||
@@ -370,33 +372,21 @@ static int ti_cpufreq_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
goto fail_put_node;
|
||||
|
||||
ti_opp_table = dev_pm_opp_set_supported_hw(opp_data->cpu_dev,
|
||||
version, VERSION_COUNT);
|
||||
if (IS_ERR(ti_opp_table)) {
|
||||
dev_err(opp_data->cpu_dev,
|
||||
"Failed to set supported hardware\n");
|
||||
ret = PTR_ERR(ti_opp_table);
|
||||
if (opp_data->soc_data->multi_regulator) {
|
||||
if (opp_data->soc_data->reg_names)
|
||||
config.regulator_names = opp_data->soc_data->reg_names;
|
||||
else
|
||||
config.regulator_names = default_reg_names;
|
||||
}
|
||||
|
||||
ret = dev_pm_opp_set_config(opp_data->cpu_dev, &config);
|
||||
if (ret < 0) {
|
||||
dev_err(opp_data->cpu_dev, "Failed to set OPP config\n");
|
||||
goto fail_put_node;
|
||||
}
|
||||
|
||||
opp_data->opp_table = ti_opp_table;
|
||||
|
||||
if (opp_data->soc_data->multi_regulator) {
|
||||
const char * const *reg_names = default_reg_names;
|
||||
|
||||
if (opp_data->soc_data->reg_names)
|
||||
reg_names = opp_data->soc_data->reg_names;
|
||||
ti_opp_table = dev_pm_opp_set_regulators(opp_data->cpu_dev,
|
||||
reg_names,
|
||||
ARRAY_SIZE(default_reg_names));
|
||||
if (IS_ERR(ti_opp_table)) {
|
||||
dev_pm_opp_put_supported_hw(opp_data->opp_table);
|
||||
ret = PTR_ERR(ti_opp_table);
|
||||
goto fail_put_node;
|
||||
}
|
||||
}
|
||||
|
||||
of_node_put(opp_data->opp_node);
|
||||
|
||||
register_cpufreq_dt:
|
||||
platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
* This code is licenced under the GPL.
|
||||
*/
|
||||
|
||||
#include "linux/percpu-defs.h"
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mutex.h>
|
||||
@@ -279,6 +280,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
|
||||
|
||||
/* Shallower states are enabled, so update. */
|
||||
dev->states_usage[entered_state].above++;
|
||||
trace_cpu_idle_miss(dev->cpu, entered_state, false);
|
||||
break;
|
||||
}
|
||||
} else if (diff > delay) {
|
||||
@@ -290,8 +292,10 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
|
||||
* Update if a deeper state would have been a
|
||||
* better match for the observed idle duration.
|
||||
*/
|
||||
if (diff - delay >= drv->states[i].target_residency_ns)
|
||||
if (diff - delay >= drv->states[i].target_residency_ns) {
|
||||
dev->states_usage[entered_state].below++;
|
||||
trace_cpu_idle_miss(dev->cpu, entered_state, true);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ struct exynos_bus {
|
||||
|
||||
unsigned long curr_freq;
|
||||
|
||||
struct opp_table *opp_table;
|
||||
int opp_token;
|
||||
struct clk *clk;
|
||||
unsigned int ratio;
|
||||
};
|
||||
@@ -161,8 +161,7 @@ static void exynos_bus_exit(struct device *dev)
|
||||
|
||||
dev_pm_opp_of_remove_table(dev);
|
||||
clk_disable_unprepare(bus->clk);
|
||||
dev_pm_opp_put_regulators(bus->opp_table);
|
||||
bus->opp_table = NULL;
|
||||
dev_pm_opp_put_regulators(bus->opp_token);
|
||||
}
|
||||
|
||||
static void exynos_bus_passive_exit(struct device *dev)
|
||||
@@ -179,18 +178,16 @@ static int exynos_bus_parent_parse_of(struct device_node *np,
|
||||
struct exynos_bus *bus)
|
||||
{
|
||||
struct device *dev = bus->dev;
|
||||
struct opp_table *opp_table;
|
||||
const char *vdd = "vdd";
|
||||
const char *supplies[] = { "vdd", NULL };
|
||||
int i, ret, count, size;
|
||||
|
||||
opp_table = dev_pm_opp_set_regulators(dev, &vdd, 1);
|
||||
if (IS_ERR(opp_table)) {
|
||||
ret = PTR_ERR(opp_table);
|
||||
ret = dev_pm_opp_set_regulators(dev, supplies);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to set regulators %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bus->opp_table = opp_table;
|
||||
bus->opp_token = ret;
|
||||
|
||||
/*
|
||||
* Get the devfreq-event devices to get the current utilization of
|
||||
@@ -236,8 +233,7 @@ static int exynos_bus_parent_parse_of(struct device_node *np,
|
||||
return 0;
|
||||
|
||||
err_regulator:
|
||||
dev_pm_opp_put_regulators(bus->opp_table);
|
||||
bus->opp_table = NULL;
|
||||
dev_pm_opp_put_regulators(bus->opp_token);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -459,8 +455,7 @@ err:
|
||||
dev_pm_opp_of_remove_table(dev);
|
||||
clk_disable_unprepare(bus->clk);
|
||||
err_reg:
|
||||
dev_pm_opp_put_regulators(bus->opp_table);
|
||||
bus->opp_table = NULL;
|
||||
dev_pm_opp_put_regulators(bus->opp_token);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -821,6 +821,15 @@ static int devm_tegra_devfreq_init_hw(struct device *dev,
|
||||
return err;
|
||||
}
|
||||
|
||||
static int tegra_devfreq_config_clks_nop(struct device *dev,
|
||||
struct opp_table *opp_table,
|
||||
struct dev_pm_opp *opp, void *data,
|
||||
bool scaling_down)
|
||||
{
|
||||
/* We want to skip clk configuration via dev_pm_opp_set_opp() */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_devfreq_probe(struct platform_device *pdev)
|
||||
{
|
||||
u32 hw_version = BIT(tegra_sku_info.soc_speedo_id);
|
||||
@@ -830,6 +839,13 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
|
||||
unsigned int i;
|
||||
long rate;
|
||||
int err;
|
||||
const char *clk_names[] = { "actmon", NULL };
|
||||
struct dev_pm_opp_config config = {
|
||||
.supported_hw = &hw_version,
|
||||
.supported_hw_count = 1,
|
||||
.clk_names = clk_names,
|
||||
.config_clks = tegra_devfreq_config_clks_nop,
|
||||
};
|
||||
|
||||
tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
|
||||
if (!tegra)
|
||||
@@ -874,13 +890,13 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
|
||||
return err;
|
||||
}
|
||||
|
||||
err = devm_pm_opp_set_supported_hw(&pdev->dev, &hw_version, 1);
|
||||
err = devm_pm_opp_set_config(&pdev->dev, &config);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "Failed to set supported HW: %d\n", err);
|
||||
dev_err(&pdev->dev, "Failed to set OPP config: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = devm_pm_opp_of_add_table_noclk(&pdev->dev, 0);
|
||||
err = devm_pm_opp_of_add_table_indexed(&pdev->dev, 0);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "Failed to add OPP table: %d\n", err);
|
||||
return err;
|
||||
|
||||
@@ -111,6 +111,12 @@ int lima_devfreq_init(struct lima_device *ldev)
|
||||
struct dev_pm_opp *opp;
|
||||
unsigned long cur_freq;
|
||||
int ret;
|
||||
const char *regulator_names[] = { "mali", NULL };
|
||||
const char *clk_names[] = { "core", NULL };
|
||||
struct dev_pm_opp_config config = {
|
||||
.regulator_names = regulator_names,
|
||||
.clk_names = clk_names,
|
||||
};
|
||||
|
||||
if (!device_property_present(dev, "operating-points-v2"))
|
||||
/* Optional, continue without devfreq */
|
||||
@@ -118,11 +124,7 @@ int lima_devfreq_init(struct lima_device *ldev)
|
||||
|
||||
spin_lock_init(&ldevfreq->lock);
|
||||
|
||||
ret = devm_pm_opp_set_clkname(dev, "core");
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_pm_opp_set_regulators(dev, (const char *[]){ "mali" }, 1);
|
||||
ret = devm_pm_opp_set_config(dev, &config);
|
||||
if (ret) {
|
||||
/* Continue if the optional regulator is missing */
|
||||
if (ret != -ENODEV)
|
||||
|
||||
@@ -101,8 +101,7 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = devm_pm_opp_set_regulators(dev, pfdev->comp->supply_names,
|
||||
pfdev->comp->num_supplies);
|
||||
ret = devm_pm_opp_set_regulators(dev, pfdev->comp->supply_names);
|
||||
if (ret) {
|
||||
/* Continue if the optional regulator is missing */
|
||||
if (ret != -ENODEV) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user