Skip to content

Commit 22b65d3

Browse files
committed
Merge branches 'pm-domains' and 'pm-devfreq'
* pm-domains: PM: domains: Drop/restore performance state votes for devices at runtime PM PM: domains: Return early if perf state is already set for the device PM: domains: Split code in dev_pm_genpd_set_performance_state() PM: domains: fix some kernel-doc issues * pm-devfreq: PM / devfreq: passive: Fix get_target_freq when not using required-opp dt-bindings: devfreq: tegra30-actmon: Add cooling-cells dt-bindings: devfreq: tegra30-actmon: Convert to schema PM / devfreq: userspace: Use DEVICE_ATTR_RW macro PM / devfreq: imx8m-ddrc: Remove DEVFREQ_GOV_SIMPLE_ONDEMAND dependency PM / devfreq: tegra30: Support thermal cooling PM / devfreq: imx-bus: Remove imx_bus_get_dev_status PM / devfreq: Add missing error code in devfreq_add_device()
3 parents ed562d2 + 5937c3c + bc6f492 commit 22b65d3

File tree

11 files changed

+186
-93
lines changed

11 files changed

+186
-93
lines changed

Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-actmon.txt

Lines changed: 0 additions & 57 deletions
This file was deleted.
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+
%YAML 1.2
3+
---
4+
$id: http://devicetree.org/schemas/devfreq/nvidia,tegra30-actmon.yaml#
5+
$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+
title: NVIDIA Tegra30 Activity Monitor
8+
9+
maintainers:
10+
- Dmitry Osipenko <[email protected]>
11+
- Jon Hunter <[email protected]>
12+
- Thierry Reding <[email protected]>
13+
14+
description: |
15+
The activity monitor block collects statistics about the behaviour of other
16+
components in the system. This information can be used to derive the rate at
17+
which the external memory needs to be clocked in order to serve all requests
18+
from the monitored clients.
19+
20+
properties:
21+
compatible:
22+
enum:
23+
- nvidia,tegra30-actmon
24+
- nvidia,tegra114-actmon
25+
- nvidia,tegra124-actmon
26+
- nvidia,tegra210-actmon
27+
28+
reg:
29+
maxItems: 1
30+
31+
clocks:
32+
maxItems: 2
33+
34+
clock-names:
35+
items:
36+
- const: actmon
37+
- const: emc
38+
39+
resets:
40+
maxItems: 1
41+
42+
reset-names:
43+
items:
44+
- const: actmon
45+
46+
interrupts:
47+
maxItems: 1
48+
49+
interconnects:
50+
minItems: 1
51+
maxItems: 12
52+
53+
interconnect-names:
54+
minItems: 1
55+
maxItems: 12
56+
description:
57+
Should include name of the interconnect path for each interconnect
58+
entry. Consult TRM documentation for information about available
59+
memory clients, see MEMORY CONTROLLER and ACTIVITY MONITOR sections.
60+
61+
operating-points-v2:
62+
description:
63+
Should contain freqs and voltages and opp-supported-hw property, which
64+
is a bitfield indicating SoC speedo ID mask.
65+
66+
"#cooling-cells":
67+
const: 2
68+
69+
required:
70+
- compatible
71+
- reg
72+
- clocks
73+
- clock-names
74+
- resets
75+
- reset-names
76+
- interrupts
77+
- interconnects
78+
- interconnect-names
79+
- operating-points-v2
80+
- "#cooling-cells"
81+
82+
additionalProperties: false
83+
84+
examples:
85+
- |
86+
#include <dt-bindings/memory/tegra30-mc.h>
87+
88+
mc: memory-controller@7000f000 {
89+
compatible = "nvidia,tegra30-mc";
90+
reg = <0x7000f000 0x400>;
91+
clocks = <&clk 32>;
92+
clock-names = "mc";
93+
94+
interrupts = <0 77 4>;
95+
96+
#iommu-cells = <1>;
97+
#reset-cells = <1>;
98+
#interconnect-cells = <1>;
99+
};
100+
101+
emc: external-memory-controller@7000f400 {
102+
compatible = "nvidia,tegra30-emc";
103+
reg = <0x7000f400 0x400>;
104+
interrupts = <0 78 4>;
105+
clocks = <&clk 57>;
106+
107+
nvidia,memory-controller = <&mc>;
108+
operating-points-v2 = <&dvfs_opp_table>;
109+
power-domains = <&domain>;
110+
111+
#interconnect-cells = <0>;
112+
};
113+
114+
actmon@6000c800 {
115+
compatible = "nvidia,tegra30-actmon";
116+
reg = <0x6000c800 0x400>;
117+
interrupts = <0 45 4>;
118+
clocks = <&clk 119>, <&clk 57>;
119+
clock-names = "actmon", "emc";
120+
resets = <&rst 119>;
121+
reset-names = "actmon";
122+
operating-points-v2 = <&dvfs_opp_table>;
123+
interconnects = <&mc TEGRA30_MC_MPCORER &emc>;
124+
interconnect-names = "cpu-read";
125+
#cooling-cells = <2>;
126+
};

drivers/base/power/domain.c

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,44 @@ static int _genpd_set_performance_state(struct generic_pm_domain *genpd,
379379
return ret;
380380
}
381381

382+
static int genpd_set_performance_state(struct device *dev, unsigned int state)
383+
{
384+
struct generic_pm_domain *genpd = dev_to_genpd(dev);
385+
struct generic_pm_domain_data *gpd_data = dev_gpd_data(dev);
386+
unsigned int prev_state;
387+
int ret;
388+
389+
prev_state = gpd_data->performance_state;
390+
if (prev_state == state)
391+
return 0;
392+
393+
gpd_data->performance_state = state;
394+
state = _genpd_reeval_performance_state(genpd, state);
395+
396+
ret = _genpd_set_performance_state(genpd, state, 0);
397+
if (ret)
398+
gpd_data->performance_state = prev_state;
399+
400+
return ret;
401+
}
402+
403+
static int genpd_drop_performance_state(struct device *dev)
404+
{
405+
unsigned int prev_state = dev_gpd_data(dev)->performance_state;
406+
407+
if (!genpd_set_performance_state(dev, 0))
408+
return prev_state;
409+
410+
return 0;
411+
}
412+
413+
static void genpd_restore_performance_state(struct device *dev,
414+
unsigned int state)
415+
{
416+
if (state)
417+
genpd_set_performance_state(dev, state);
418+
}
419+
382420
/**
383421
* dev_pm_genpd_set_performance_state- Set performance state of device's power
384422
* domain.
@@ -397,8 +435,6 @@ static int _genpd_set_performance_state(struct generic_pm_domain *genpd,
397435
int dev_pm_genpd_set_performance_state(struct device *dev, unsigned int state)
398436
{
399437
struct generic_pm_domain *genpd;
400-
struct generic_pm_domain_data *gpd_data;
401-
unsigned int prev;
402438
int ret;
403439

404440
genpd = dev_to_genpd_safe(dev);
@@ -410,16 +446,7 @@ int dev_pm_genpd_set_performance_state(struct device *dev, unsigned int state)
410446
return -EINVAL;
411447

412448
genpd_lock(genpd);
413-
414-
gpd_data = to_gpd_data(dev->power.subsys_data->domain_data);
415-
prev = gpd_data->performance_state;
416-
gpd_data->performance_state = state;
417-
418-
state = _genpd_reeval_performance_state(genpd, state);
419-
ret = _genpd_set_performance_state(genpd, state, 0);
420-
if (ret)
421-
gpd_data->performance_state = prev;
422-
449+
ret = genpd_set_performance_state(dev, state);
423450
genpd_unlock(genpd);
424451

425452
return ret;
@@ -572,6 +599,7 @@ static void genpd_queue_power_off_work(struct generic_pm_domain *genpd)
572599
* RPM status of the releated device is in an intermediate state, not yet turned
573600
* into RPM_SUSPENDED. This means genpd_power_off() must allow one device to not
574601
* be RPM_SUSPENDED, while it tries to power off the PM domain.
602+
* @depth: nesting count for lockdep.
575603
*
576604
* If all of the @genpd's devices have been suspended and all of its subdomains
577605
* have been powered down, remove power from @genpd.
@@ -832,7 +860,8 @@ static int genpd_runtime_suspend(struct device *dev)
832860
{
833861
struct generic_pm_domain *genpd;
834862
bool (*suspend_ok)(struct device *__dev);
835-
struct gpd_timing_data *td = &dev_gpd_data(dev)->td;
863+
struct generic_pm_domain_data *gpd_data = dev_gpd_data(dev);
864+
struct gpd_timing_data *td = &gpd_data->td;
836865
bool runtime_pm = pm_runtime_enabled(dev);
837866
ktime_t time_start;
838867
s64 elapsed_ns;
@@ -889,6 +918,7 @@ static int genpd_runtime_suspend(struct device *dev)
889918
return 0;
890919

891920
genpd_lock(genpd);
921+
gpd_data->rpm_pstate = genpd_drop_performance_state(dev);
892922
genpd_power_off(genpd, true, 0);
893923
genpd_unlock(genpd);
894924

@@ -906,7 +936,8 @@ static int genpd_runtime_suspend(struct device *dev)
906936
static int genpd_runtime_resume(struct device *dev)
907937
{
908938
struct generic_pm_domain *genpd;
909-
struct gpd_timing_data *td = &dev_gpd_data(dev)->td;
939+
struct generic_pm_domain_data *gpd_data = dev_gpd_data(dev);
940+
struct gpd_timing_data *td = &gpd_data->td;
910941
bool runtime_pm = pm_runtime_enabled(dev);
911942
ktime_t time_start;
912943
s64 elapsed_ns;
@@ -930,6 +961,8 @@ static int genpd_runtime_resume(struct device *dev)
930961

931962
genpd_lock(genpd);
932963
ret = genpd_power_on(genpd, 0);
964+
if (!ret)
965+
genpd_restore_performance_state(dev, gpd_data->rpm_pstate);
933966
genpd_unlock(genpd);
934967

935968
if (ret)
@@ -968,6 +1001,7 @@ static int genpd_runtime_resume(struct device *dev)
9681001
err_poweroff:
9691002
if (!pm_runtime_is_irq_safe(dev) || genpd_is_irq_safe(genpd)) {
9701003
genpd_lock(genpd);
1004+
gpd_data->rpm_pstate = genpd_drop_performance_state(dev);
9711005
genpd_power_off(genpd, true, 0);
9721006
genpd_unlock(genpd);
9731007
}
@@ -2505,7 +2539,7 @@ EXPORT_SYMBOL_GPL(of_genpd_remove_subdomain);
25052539

25062540
/**
25072541
* of_genpd_remove_last - Remove the last PM domain registered for a provider
2508-
* @provider: Pointer to device structure associated with provider
2542+
* @np: Pointer to device node associated with provider
25092543
*
25102544
* Find the last PM domain that was added by a particular provider and
25112545
* remove this PM domain from the list of PM domains. The provider is

drivers/base/power/domain_governor.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ static bool __default_power_down_ok(struct dev_pm_domain *pd,
252252
/**
253253
* _default_power_down_ok - Default generic PM domain power off governor routine.
254254
* @pd: PM domain to check.
255+
* @now: current ktime.
255256
*
256257
* This routine must be executed under the PM domain's lock.
257258
*/

drivers/devfreq/Kconfig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ config ARM_IMX8M_DDRC_DEVFREQ
103103
tristate "i.MX8M DDRC DEVFREQ Driver"
104104
depends on (ARCH_MXC && HAVE_ARM_SMCCC) || \
105105
(COMPILE_TEST && HAVE_ARM_SMCCC)
106-
select DEVFREQ_GOV_SIMPLE_ONDEMAND
107106
select DEVFREQ_GOV_USERSPACE
108107
help
109108
This adds the DEVFREQ driver for the i.MX8M DDR Controller. It allows

drivers/devfreq/devfreq.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,7 @@ struct devfreq *devfreq_add_device(struct device *dev,
823823
if (devfreq->profile->timer < 0
824824
|| devfreq->profile->timer >= DEVFREQ_TIMER_NUM) {
825825
mutex_unlock(&devfreq->lock);
826+
err = -EINVAL;
826827
goto err_dev;
827828
}
828829

drivers/devfreq/governor_passive.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,15 @@ static int devfreq_passive_get_target_freq(struct devfreq *devfreq,
6565
dev_pm_opp_put(p_opp);
6666

6767
if (IS_ERR(opp))
68-
return PTR_ERR(opp);
68+
goto no_required_opp;
6969

7070
*freq = dev_pm_opp_get_freq(opp);
7171
dev_pm_opp_put(opp);
7272

7373
return 0;
7474
}
7575

76+
no_required_opp:
7677
/*
7778
* Get the OPP table's index of decided frequency by governor
7879
* of parent device.

drivers/devfreq/governor_userspace.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ static int devfreq_userspace_func(struct devfreq *df, unsigned long *freq)
3131
return 0;
3232
}
3333

34-
static ssize_t store_freq(struct device *dev, struct device_attribute *attr,
35-
const char *buf, size_t count)
34+
static ssize_t set_freq_store(struct device *dev, struct device_attribute *attr,
35+
const char *buf, size_t count)
3636
{
3737
struct devfreq *devfreq = to_devfreq(dev);
3838
struct userspace_data *data;
@@ -52,8 +52,8 @@ static ssize_t store_freq(struct device *dev, struct device_attribute *attr,
5252
return err;
5353
}
5454

55-
static ssize_t show_freq(struct device *dev, struct device_attribute *attr,
56-
char *buf)
55+
static ssize_t set_freq_show(struct device *dev,
56+
struct device_attribute *attr, char *buf)
5757
{
5858
struct devfreq *devfreq = to_devfreq(dev);
5959
struct userspace_data *data;
@@ -70,7 +70,7 @@ static ssize_t show_freq(struct device *dev, struct device_attribute *attr,
7070
return err;
7171
}
7272

73-
static DEVICE_ATTR(set_freq, 0644, show_freq, store_freq);
73+
static DEVICE_ATTR_RW(set_freq);
7474
static struct attribute *dev_entries[] = {
7575
&dev_attr_set_freq.attr,
7676
NULL,

0 commit comments

Comments
 (0)