Skip to content

Commit 200289d

Browse files
committed
Merge tag 'pmdomain-v6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm
Pull pmdomain updates from Ulf Hansson: "pmdomain core: - Add support for s2idle for CPU PM domains on PREEMPT_RT - Add device managed version of dev_pm_domain_attach|detach_list() - Improve layout of the debugfs summary table pmdomain providers: - amlogic: Remove obsolete vpu domain driver - bcm: raspberrypi: Add support for devices used as wakeup-sources - imx: Fixup clock handling for imx93 at driver remove - rockchip: Add gating support for RK3576 - rockchip: Add support for RK3576 SoC - Some OF parsing simplifications - Some simplifications by using dev_err_probe() and guard() pmdomain consumers: - qcom/media/venus: Convert to the device managed APIs for PM domains cpuidle-psci: - Add support for s2idle/s2ram for the hierarchical topology on PREEMPT_RT - Some OF parsing simplifications" * tag 'pmdomain-v6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm: (39 commits) pmdomain: core: Reduce debug summary table width pmdomain: core: Move mode_status_str() pmdomain: core: Fix "managed by" alignment in debug summary pmdomain: core: Harden inter-column space in debug summary pmdomain: rockchip: Add gating masks for rk3576 pmdomain: rockchip: Add gating support pmdomain: rockchip: Simplify dropping OF node reference pmdomain: mediatek: make use of dev_err_cast_probe() pmdomain: imx93-pd: drop the context variable "init_off" pmdomain: imx93-pd: don't unprepare clocks on driver remove pmdomain: imx93-pd: replace dev_err() with dev_err_probe() pmdomain: qcom: rpmpd: Simplify locking with guard() pmdomain: qcom: rpmhpd: Simplify locking with guard() pmdomain: qcom: cpr: Simplify locking with guard() pmdomain: qcom: cpr: Simplify with dev_err_probe() pmdomain: imx: gpcv2: Simplify with scoped for each OF child loop pmdomain: imx: gpc: Simplify with scoped for each OF child loop pmdomain: rockchip: SimplUlf Hanssonify locking with guard() pmdomain: rockchip: Simplify with scoped for each OF child loop pmdomain: qcom-cpr: Use scope based of_node_put() to simplify code. ...
2 parents 2fe3c78 + c6ccb69 commit 200289d

File tree

22 files changed

+373
-603
lines changed

22 files changed

+373
-603
lines changed

Documentation/devicetree/bindings/power/rockchip,power-controller.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ properties:
4141
- rockchip,rk3368-power-controller
4242
- rockchip,rk3399-power-controller
4343
- rockchip,rk3568-power-controller
44+
- rockchip,rk3576-power-controller
4445
- rockchip,rk3588-power-controller
4546
- rockchip,rv1126-power-controller
4647

drivers/base/power/common.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,51 @@ int dev_pm_domain_attach_list(struct device *dev,
276276
}
277277
EXPORT_SYMBOL_GPL(dev_pm_domain_attach_list);
278278

279+
/**
280+
* devm_pm_domain_detach_list - devres-enabled version of dev_pm_domain_detach_list.
281+
* @_list: The list of PM domains to detach.
282+
*
283+
* This function reverse the actions from devm_pm_domain_attach_list().
284+
* it will be invoked during the remove phase from drivers implicitly if driver
285+
* uses devm_pm_domain_attach_list() to attach the PM domains.
286+
*/
287+
static void devm_pm_domain_detach_list(void *_list)
288+
{
289+
struct dev_pm_domain_list *list = _list;
290+
291+
dev_pm_domain_detach_list(list);
292+
}
293+
294+
/**
295+
* devm_pm_domain_attach_list - devres-enabled version of dev_pm_domain_attach_list
296+
* @dev: The device used to lookup the PM domains for.
297+
* @data: The data used for attaching to the PM domains.
298+
* @list: An out-parameter with an allocated list of attached PM domains.
299+
*
300+
* NOTE: this will also handle calling devm_pm_domain_detach_list() for
301+
* you during remove phase.
302+
*
303+
* Returns the number of attached PM domains or a negative error code in case of
304+
* a failure.
305+
*/
306+
int devm_pm_domain_attach_list(struct device *dev,
307+
const struct dev_pm_domain_attach_data *data,
308+
struct dev_pm_domain_list **list)
309+
{
310+
int ret, num_pds;
311+
312+
num_pds = dev_pm_domain_attach_list(dev, data, list);
313+
if (num_pds <= 0)
314+
return num_pds;
315+
316+
ret = devm_add_action_or_reset(dev, devm_pm_domain_detach_list, *list);
317+
if (ret)
318+
return ret;
319+
320+
return num_pds;
321+
}
322+
EXPORT_SYMBOL_GPL(devm_pm_domain_attach_list);
323+
279324
/**
280325
* dev_pm_domain_detach - Detach a device from its PM domain.
281326
* @dev: Device to detach.

drivers/cpuidle/cpuidle-psci-domain.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,16 @@ static int psci_pd_init(struct device_node *np, bool use_osi)
6767

6868
/*
6969
* Allow power off when OSI has been successfully enabled.
70-
* PREEMPT_RT is not yet ready to enter domain idle states.
70+
* On a PREEMPT_RT based configuration the domain idle states are
71+
* supported, but only during system-wide suspend.
7172
*/
72-
if (use_osi && !IS_ENABLED(CONFIG_PREEMPT_RT))
73+
if (use_osi) {
7374
pd->power_off = psci_pd_power_off;
74-
else
75+
if (IS_ENABLED(CONFIG_PREEMPT_RT))
76+
pd->flags |= GENPD_FLAG_RPM_ALWAYS_ON;
77+
} else {
7578
pd->flags |= GENPD_FLAG_ALWAYS_ON;
79+
}
7680

7781
/* Use governor for CPU PM domains if it has some states to manage. */
7882
pd_gov = pd->states ? &pm_domain_cpu_gov : NULL;
@@ -138,7 +142,6 @@ static const struct of_device_id psci_of_match[] = {
138142
static int psci_cpuidle_domain_probe(struct platform_device *pdev)
139143
{
140144
struct device_node *np = pdev->dev.of_node;
141-
struct device_node *node;
142145
bool use_osi = psci_has_osi_support();
143146
int ret = 0, pd_count = 0;
144147

@@ -149,15 +152,13 @@ static int psci_cpuidle_domain_probe(struct platform_device *pdev)
149152
* Parse child nodes for the "#power-domain-cells" property and
150153
* initialize a genpd/genpd-of-provider pair when it's found.
151154
*/
152-
for_each_child_of_node(np, node) {
155+
for_each_child_of_node_scoped(np, node) {
153156
if (!of_property_present(node, "#power-domain-cells"))
154157
continue;
155158

156159
ret = psci_pd_init(node, use_osi);
157-
if (ret) {
158-
of_node_put(node);
160+
if (ret)
159161
goto exit;
160-
}
161162

162163
pd_count++;
163164
}

drivers/cpuidle/cpuidle-psci.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ struct psci_cpuidle_data {
3737

3838
static DEFINE_PER_CPU_READ_MOSTLY(struct psci_cpuidle_data, psci_cpuidle_data);
3939
static DEFINE_PER_CPU(u32, domain_state);
40+
static bool psci_cpuidle_use_syscore;
4041
static bool psci_cpuidle_use_cpuhp;
4142

4243
void psci_set_domain_state(u32 state)
@@ -166,15 +167,19 @@ static struct syscore_ops psci_idle_syscore_ops = {
166167
.resume = psci_idle_syscore_resume,
167168
};
168169

170+
static void psci_idle_init_syscore(void)
171+
{
172+
if (psci_cpuidle_use_syscore)
173+
register_syscore_ops(&psci_idle_syscore_ops);
174+
}
175+
169176
static void psci_idle_init_cpuhp(void)
170177
{
171178
int err;
172179

173180
if (!psci_cpuidle_use_cpuhp)
174181
return;
175182

176-
register_syscore_ops(&psci_idle_syscore_ops);
177-
178183
err = cpuhp_setup_state_nocalls(CPUHP_AP_CPU_PM_STARTING,
179184
"cpuidle/psci:online",
180185
psci_idle_cpuhp_up,
@@ -222,22 +227,23 @@ static int psci_dt_cpu_init_topology(struct cpuidle_driver *drv,
222227
if (!psci_has_osi_support())
223228
return 0;
224229

225-
if (IS_ENABLED(CONFIG_PREEMPT_RT))
226-
return 0;
227-
228230
data->dev = dt_idle_attach_cpu(cpu, "psci");
229231
if (IS_ERR_OR_NULL(data->dev))
230232
return PTR_ERR_OR_ZERO(data->dev);
231233

234+
psci_cpuidle_use_syscore = true;
235+
232236
/*
233237
* Using the deepest state for the CPU to trigger a potential selection
234238
* of a shared state for the domain, assumes the domain states are all
235-
* deeper states.
239+
* deeper states. On PREEMPT_RT the hierarchical topology is limited to
240+
* s2ram and s2idle.
236241
*/
237-
drv->states[state_count - 1].flags |= CPUIDLE_FLAG_RCU_IDLE;
238-
drv->states[state_count - 1].enter = psci_enter_domain_idle_state;
239242
drv->states[state_count - 1].enter_s2idle = psci_enter_s2idle_domain_idle_state;
240-
psci_cpuidle_use_cpuhp = true;
243+
if (!IS_ENABLED(CONFIG_PREEMPT_RT)) {
244+
drv->states[state_count - 1].enter = psci_enter_domain_idle_state;
245+
psci_cpuidle_use_cpuhp = true;
246+
}
241247

242248
return 0;
243249
}
@@ -313,6 +319,7 @@ static void psci_cpu_deinit_idle(int cpu)
313319
struct psci_cpuidle_data *data = per_cpu_ptr(&psci_cpuidle_data, cpu);
314320

315321
dt_idle_detach_cpu(data->dev);
322+
psci_cpuidle_use_syscore = false;
316323
psci_cpuidle_use_cpuhp = false;
317324
}
318325

@@ -409,6 +416,7 @@ static int psci_cpuidle_probe(struct platform_device *pdev)
409416
goto out_fail;
410417
}
411418

419+
psci_idle_init_syscore();
412420
psci_idle_init_cpuhp();
413421
return 0;
414422

drivers/cpuidle/dt_idle_genpd.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,10 @@ struct generic_pm_domain *dt_idle_pd_alloc(struct device_node *np,
130130

131131
int dt_idle_pd_init_topology(struct device_node *np)
132132
{
133-
struct device_node *node;
134133
struct of_phandle_args child, parent;
135134
int ret;
136135

137-
for_each_child_of_node(np, node) {
136+
for_each_child_of_node_scoped(np, node) {
138137
if (of_parse_phandle_with_args(node, "power-domains",
139138
"#power-domain-cells", 0, &parent))
140139
continue;
@@ -143,22 +142,19 @@ int dt_idle_pd_init_topology(struct device_node *np)
143142
child.args_count = 0;
144143
ret = of_genpd_add_subdomain(&parent, &child);
145144
of_node_put(parent.np);
146-
if (ret) {
147-
of_node_put(node);
145+
if (ret)
148146
return ret;
149-
}
150147
}
151148

152149
return 0;
153150
}
154151

155152
int dt_idle_pd_remove_topology(struct device_node *np)
156153
{
157-
struct device_node *node;
158154
struct of_phandle_args child, parent;
159155
int ret;
160156

161-
for_each_child_of_node(np, node) {
157+
for_each_child_of_node_scoped(np, node) {
162158
if (of_parse_phandle_with_args(node, "power-domains",
163159
"#power-domain-cells", 0, &parent))
164160
continue;
@@ -167,10 +163,8 @@ int dt_idle_pd_remove_topology(struct device_node *np)
167163
child.args_count = 0;
168164
ret = of_genpd_remove_subdomain(&parent, &child);
169165
of_node_put(parent.np);
170-
if (ret) {
171-
of_node_put(node);
166+
if (ret)
172167
return ret;
173-
}
174168
}
175169

176170
return 0;

drivers/media/platform/qcom/venus/pm_helpers.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -876,7 +876,7 @@ static int vcodec_domains_get(struct venus_core *core)
876876
if (!res->vcodec_pmdomains_num)
877877
goto skip_pmdomains;
878878

879-
ret = dev_pm_domain_attach_list(dev, &vcodec_data, &core->pmdomains);
879+
ret = devm_pm_domain_attach_list(dev, &vcodec_data, &core->pmdomains);
880880
if (ret < 0)
881881
return ret;
882882

@@ -902,14 +902,11 @@ static int vcodec_domains_get(struct venus_core *core)
902902
return 0;
903903

904904
opp_attach_err:
905-
dev_pm_domain_detach_list(core->pmdomains);
906905
return ret;
907906
}
908907

909908
static void vcodec_domains_put(struct venus_core *core)
910909
{
911-
dev_pm_domain_detach_list(core->pmdomains);
912-
913910
if (!core->has_opp_table)
914911
return;
915912

drivers/pmdomain/amlogic/Kconfig

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,6 @@
11
# SPDX-License-Identifier: GPL-2.0-only
22
menu "Amlogic PM Domains"
33

4-
config MESON_GX_PM_DOMAINS
5-
tristate "Amlogic Meson GX Power Domains driver"
6-
depends on ARCH_MESON || COMPILE_TEST
7-
depends on PM && OF
8-
default ARCH_MESON
9-
select PM_GENERIC_DOMAINS
10-
select PM_GENERIC_DOMAINS_OF
11-
help
12-
Say yes to expose Amlogic Meson GX Power Domains as
13-
Generic Power Domains.
14-
154
config MESON_EE_PM_DOMAINS
165
tristate "Amlogic Meson Everything-Else Power Domains driver"
176
depends on ARCH_MESON || COMPILE_TEST

drivers/pmdomain/amlogic/Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
# SPDX-License-Identifier: GPL-2.0-only
2-
obj-$(CONFIG_MESON_GX_PM_DOMAINS) += meson-gx-pwrc-vpu.o
32
obj-$(CONFIG_MESON_EE_PM_DOMAINS) += meson-ee-pwrc.o
43
obj-$(CONFIG_MESON_SECURE_PM_DOMAINS) += meson-secure-pwrc.o

0 commit comments

Comments
 (0)