Skip to content

Commit e41a25c

Browse files
committed
Merge tag 'pmdomain-v7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm
Pull pmdomain updates from Ulf Hansson: "pmdomain core: - Extend statistics for domain idle states with s2idle data - Show latency/residency for domain idle states in debugfs pmdomain providers: - imx: Add support for optional subnodes for imx93-blk-ctrl - marvell: Add audio power island for Marvell PXA1908 - mediatek: - Add legacy support for the MT7622 audio power domain - Add nvmem provider functionality to the mtk-mfg-pmdomain - Add support for the MT8189 power domains - qcom: Add support for the Eliza and Hawi power domains - sunxi: Add support for the Allwinner A733 power domains - ti: Handle wakeup constraints for out-of-band wakeups for ti_sci" * tag 'pmdomain-v7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm: (32 commits) pmdomain: qcom: rpmhpd: Add power domains for Hawi SoC dt-bindings: power: qcom,rpmhpd: Add RPMh power domain for Hawi SoC pmdomain: qcom: cpr: add COMPILE_TEST support PM: domains: De-constify fields in struct dev_pm_domain_attach_data pmdomain: qcom: cpr: simplify main allocation pmdomain: bcm: bcm2835-power: Replace open-coded polling with readl_poll_timeout_atomic() pmdomain: sunxi: Add support for A733 to Allwinner PCK600 driver pmdomain: qcom: rpmhpd: Add Eliza RPMh Power Domains pmdomain: arm: Add print after a successful probe for SCMI power domains pmdomain: rockchip: quiet regulator error on -EPROBE_DEFER pmdomain: mediatek: Add power domain driver for MT8189 SoC pmdomain: mediatek: Add bus protect control flow for MT8189 pmdomain: core: Extend statistics for domain idle states with s2idle data pmdomain: core: Show latency/residency for domain idle states in debugfs pmdomain: core: Restructure domain idle states data for genpd in debugfs pmdomain: qcom: rpmpd: drop stray semicolon pmdomain: imx: scu-pd: Fix device_node reference leak during ->probe() pmdomain: ti: omap_prm: Fix a reference leak on device node pmdomain: mediatek: scpsys: Add MT7622 Audio power domain to legacy driver pmdomain: mediatek: Simplify with scoped for each OF child loop ...
2 parents 4ddd4f0 + 596ca99 commit e41a25c

29 files changed

Lines changed: 932 additions & 104 deletions

Documentation/devicetree/bindings/power/allwinner,sun20i-d1-ppu.yaml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ properties:
2020
- allwinner,sun20i-d1-ppu
2121
- allwinner,sun55i-a523-pck-600
2222
- allwinner,sun55i-a523-ppu
23+
- allwinner,sun60i-a733-pck-600
2324

2425
reg:
2526
maxItems: 1
@@ -38,9 +39,23 @@ required:
3839
- compatible
3940
- reg
4041
- clocks
41-
- resets
4242
- '#power-domain-cells'
4343

44+
allOf:
45+
- if:
46+
properties:
47+
compatible:
48+
contains:
49+
enum:
50+
- allwinner,sun8i-v853-ppu
51+
- allwinner,sun20i-d1-ppu
52+
- allwinner,sun55i-a523-pck-600
53+
- allwinner,sun55i-a523-ppu
54+
55+
then:
56+
required:
57+
- resets
58+
4459
additionalProperties: false
4560

4661
examples:

Documentation/devicetree/bindings/power/mediatek,mt8196-gpufreq.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,18 @@ properties:
7474
"#clock-cells":
7575
const: 1
7676

77+
"#nvmem-cell-cells":
78+
const: 0
79+
7780
"#power-domain-cells":
7881
const: 0
7982

83+
shader-present:
84+
type: object
85+
86+
dependencies:
87+
shader-present: [ "#nvmem-cell-cells" ]
88+
8089
required:
8190
- compatible
8291
- reg
@@ -113,5 +122,9 @@ examples:
113122
"ccf", "fast-dvfs";
114123
memory-region = <&gpueb_shared_memory>;
115124
#clock-cells = <1>;
125+
#nvmem-cell-cells = <0>;
116126
#power-domain-cells = <0>;
127+
128+
shader-present {
129+
};
117130
};

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ properties:
3131
- mediatek,mt8183-power-controller
3232
- mediatek,mt8186-power-controller
3333
- mediatek,mt8188-power-controller
34+
- mediatek,mt8189-power-controller
3435
- mediatek,mt8192-power-controller
3536
- mediatek,mt8195-power-controller
3637
- mediatek,mt8196-hwv-hfrp-power-controller

Documentation/devicetree/bindings/power/qcom,rpmpd.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ properties:
1717
compatible:
1818
oneOf:
1919
- enum:
20+
- qcom,eliza-rpmhpd
2021
- qcom,glymur-rpmhpd
22+
- qcom,hawi-rpmhpd
2123
- qcom,kaanapali-rpmhpd
2224
- qcom,mdm9607-rpmpd
2325
- qcom,milos-rpmhpd

drivers/pmdomain/arm/scmi_pm_domain.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ static int scmi_pm_domain_probe(struct scmi_device *sdev)
113113
goto err_rm_genpds;
114114

115115
dev_set_drvdata(dev, scmi_pd_data);
116+
dev_info(dev, "Initialized %d power domains", num_domains);
116117

117118
return 0;
118119
err_rm_genpds:

drivers/pmdomain/bcm/bcm2835-power.c

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -215,10 +215,10 @@ static int bcm2835_power_power_on(struct bcm2835_power_domain *pd, u32 pm_reg)
215215
{
216216
struct bcm2835_power *power = pd->power;
217217
struct device *dev = power->dev;
218-
u64 start;
219218
int ret;
220219
int inrush;
221220
bool powok;
221+
u32 val;
222222

223223
/* We don't run this on BCM2711 */
224224
if (power->rpivid_asb)
@@ -239,12 +239,8 @@ static int bcm2835_power_power_on(struct bcm2835_power_domain *pd, u32 pm_reg)
239239
(inrush << PM_INRUSH_SHIFT) |
240240
PM_POWUP);
241241

242-
start = ktime_get_ns();
243-
while (!(powok = !!(PM_READ(pm_reg) & PM_POWOK))) {
244-
cpu_relax();
245-
if (ktime_get_ns() - start >= 3000)
246-
break;
247-
}
242+
powok = !readl_poll_timeout_atomic(power->base + pm_reg,
243+
val, val & PM_POWOK, 0, 3);
248244
}
249245
if (!powok) {
250246
dev_err(dev, "Timeout waiting for %s power OK\n",
@@ -258,15 +254,12 @@ static int bcm2835_power_power_on(struct bcm2835_power_domain *pd, u32 pm_reg)
258254

259255
/* Repair memory */
260256
PM_WRITE(pm_reg, PM_READ(pm_reg) | PM_MEMREP);
261-
start = ktime_get_ns();
262-
while (!(PM_READ(pm_reg) & PM_MRDONE)) {
263-
cpu_relax();
264-
if (ktime_get_ns() - start >= 1000) {
265-
dev_err(dev, "Timeout waiting for %s memory repair\n",
266-
pd->base.name);
267-
ret = -ETIMEDOUT;
268-
goto err_disable_ispow;
269-
}
257+
if (readl_poll_timeout_atomic(power->base + pm_reg, val,
258+
val & PM_MRDONE, 0, 1)) {
259+
dev_err(dev, "Timeout waiting for %s memory repair\n",
260+
pd->base.name);
261+
ret = -ETIMEDOUT;
262+
goto err_disable_ispow;
270263
}
271264

272265
/* Disable functional isolation */

drivers/pmdomain/core.c

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1438,6 +1438,13 @@ static void genpd_sync_power_off(struct generic_pm_domain *genpd, bool use_lock,
14381438
return;
14391439
} else {
14401440
genpd->states[genpd->state_idx].usage++;
1441+
1442+
/*
1443+
* The ->system_power_down_ok() callback is currently used only
1444+
* for s2idle. Use it to know when to update the usage counter.
1445+
*/
1446+
if (genpd->gov && genpd->gov->system_power_down_ok)
1447+
genpd->states[genpd->state_idx].usage_s2idle++;
14411448
}
14421449

14431450
genpd->status = GENPD_STATE_OFF;
@@ -3772,11 +3779,11 @@ static int idle_states_show(struct seq_file *s, void *data)
37723779
if (ret)
37733780
return -ERESTARTSYS;
37743781

3775-
seq_puts(s, "State Time Spent(ms) Usage Rejected Above Below\n");
3782+
seq_puts(s, "State Time(ms) Usage Rejected Above Below S2idle\n");
37763783

37773784
for (i = 0; i < genpd->state_count; i++) {
37783785
struct genpd_power_state *state = &genpd->states[i];
3779-
char state_name[15];
3786+
char state_name[7];
37803787

37813788
idle_time += state->idle_time;
37823789

@@ -3788,14 +3795,45 @@ static int idle_states_show(struct seq_file *s, void *data)
37883795
}
37893796
}
37903797

3791-
if (!state->name)
3792-
snprintf(state_name, ARRAY_SIZE(state_name), "S%-13d", i);
3793-
3798+
snprintf(state_name, ARRAY_SIZE(state_name), "S%-5d", i);
37943799
do_div(idle_time, NSEC_PER_MSEC);
3795-
seq_printf(s, "%-14s %-14llu %-10llu %-10llu %-10llu %llu\n",
3796-
state->name ?: state_name, idle_time,
3797-
state->usage, state->rejected, state->above,
3798-
state->below);
3800+
seq_printf(s, "%-6s %-14llu %-10llu %-10llu %-10llu %-10llu %llu\n",
3801+
state_name, idle_time, state->usage, state->rejected,
3802+
state->above, state->below, state->usage_s2idle);
3803+
}
3804+
3805+
genpd_unlock(genpd);
3806+
return ret;
3807+
}
3808+
3809+
static int idle_states_desc_show(struct seq_file *s, void *data)
3810+
{
3811+
struct generic_pm_domain *genpd = s->private;
3812+
unsigned int i;
3813+
int ret = 0;
3814+
3815+
ret = genpd_lock_interruptible(genpd);
3816+
if (ret)
3817+
return -ERESTARTSYS;
3818+
3819+
seq_puts(s, "State Latency(us) Residency(us) Name\n");
3820+
3821+
for (i = 0; i < genpd->state_count; i++) {
3822+
struct genpd_power_state *state = &genpd->states[i];
3823+
u64 latency, residency;
3824+
char state_name[7];
3825+
3826+
latency = state->power_off_latency_ns +
3827+
state->power_on_latency_ns;
3828+
do_div(latency, NSEC_PER_USEC);
3829+
3830+
residency = state->residency_ns;
3831+
do_div(residency, NSEC_PER_USEC);
3832+
3833+
snprintf(state_name, ARRAY_SIZE(state_name), "S%-5d", i);
3834+
seq_printf(s, "%-6s %-12llu %-14llu %s\n",
3835+
state_name, latency, residency,
3836+
state->name ?: "N/A");
37993837
}
38003838

38013839
genpd_unlock(genpd);
@@ -3891,6 +3929,7 @@ DEFINE_SHOW_ATTRIBUTE(summary);
38913929
DEFINE_SHOW_ATTRIBUTE(status);
38923930
DEFINE_SHOW_ATTRIBUTE(sub_domains);
38933931
DEFINE_SHOW_ATTRIBUTE(idle_states);
3932+
DEFINE_SHOW_ATTRIBUTE(idle_states_desc);
38943933
DEFINE_SHOW_ATTRIBUTE(active_time);
38953934
DEFINE_SHOW_ATTRIBUTE(total_idle_time);
38963935
DEFINE_SHOW_ATTRIBUTE(devices);
@@ -3911,6 +3950,8 @@ static void genpd_debug_add(struct generic_pm_domain *genpd)
39113950
d, genpd, &sub_domains_fops);
39123951
debugfs_create_file("idle_states", 0444,
39133952
d, genpd, &idle_states_fops);
3953+
debugfs_create_file("idle_states_desc", 0444,
3954+
d, genpd, &idle_states_desc_fops);
39143955
debugfs_create_file("active_time", 0444,
39153956
d, genpd, &active_time_fops);
39163957
debugfs_create_file("total_idle_time", 0444,

drivers/pmdomain/imx/imx93-blk-ctrl.c

Lines changed: 36 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <linux/device.h>
88
#include <linux/module.h>
99
#include <linux/of.h>
10+
#include <linux/of_platform.h>
1011
#include <linux/platform_device.h>
1112
#include <linux/pm_domain.h>
1213
#include <linux/pm_runtime.h>
@@ -188,6 +189,20 @@ static int imx93_blk_ctrl_power_off(struct generic_pm_domain *genpd)
188189
return 0;
189190
}
190191

192+
static void imx93_release_genpd_provider(void *data)
193+
{
194+
struct device_node *of_node = data;
195+
196+
of_genpd_del_provider(of_node);
197+
}
198+
199+
static void imx93_release_pm_genpd(void *data)
200+
{
201+
struct generic_pm_domain *genpd = data;
202+
203+
pm_genpd_remove(genpd);
204+
}
205+
191206
static struct lock_class_key blk_ctrl_genpd_lock_class;
192207

193208
static int imx93_blk_ctrl_probe(struct platform_device *pdev)
@@ -240,10 +255,8 @@ static int imx93_blk_ctrl_probe(struct platform_device *pdev)
240255
bc->num_clks = bc_data->num_clks;
241256

242257
ret = devm_clk_bulk_get(dev, bc->num_clks, bc->clks);
243-
if (ret) {
244-
dev_err_probe(dev, ret, "failed to get bus clock\n");
245-
return ret;
246-
}
258+
if (ret)
259+
return dev_err_probe(dev, ret, "failed to get bus clock\n");
247260

248261
for (i = 0; i < bc_data->num_domains; i++) {
249262
const struct imx93_blk_ctrl_domain_data *data = &bc_data->domains[i];
@@ -258,22 +271,21 @@ static int imx93_blk_ctrl_probe(struct platform_device *pdev)
258271
domain->clks[j].id = data->clk_names[j];
259272

260273
ret = devm_clk_bulk_get(dev, data->num_clks, domain->clks);
261-
if (ret) {
262-
dev_err_probe(dev, ret, "failed to get clock\n");
263-
goto cleanup_pds;
264-
}
274+
if (ret)
275+
return dev_err_probe(dev, ret, "failed to get clock\n");
265276

266277
domain->genpd.name = data->name;
267278
domain->genpd.power_on = imx93_blk_ctrl_power_on;
268279
domain->genpd.power_off = imx93_blk_ctrl_power_off;
269280
domain->bc = bc;
270281

271282
ret = pm_genpd_init(&domain->genpd, NULL, true);
272-
if (ret) {
273-
dev_err_probe(dev, ret, "failed to init power domain\n");
274-
goto cleanup_pds;
275-
}
283+
if (ret)
284+
return dev_err_probe(dev, ret, "failed to init power domain\n");
276285

286+
ret = devm_add_action_or_reset(dev, imx93_release_pm_genpd, &domain->genpd);
287+
if (ret)
288+
return dev_err_probe(dev, ret, "failed to add pm_genpd release callback\n");
277289
/*
278290
* We use runtime PM to trigger power on/off of the upstream GPC
279291
* domain, as a strict hierarchical parent/child power domain
@@ -290,39 +302,23 @@ static int imx93_blk_ctrl_probe(struct platform_device *pdev)
290302
bc->onecell_data.domains[i] = &domain->genpd;
291303
}
292304

293-
pm_runtime_enable(dev);
305+
ret = devm_pm_runtime_enable(dev);
306+
if (ret)
307+
return dev_err_probe(dev, ret, "failed to enable pm-runtime\n");
294308

295309
ret = of_genpd_add_provider_onecell(dev->of_node, &bc->onecell_data);
296-
if (ret) {
297-
dev_err_probe(dev, ret, "failed to add power domain provider\n");
298-
goto cleanup_pds;
299-
}
310+
if (ret)
311+
return dev_err_probe(dev, ret, "failed to add power domain provider\n");
300312

301-
dev_set_drvdata(dev, bc);
313+
ret = devm_add_action_or_reset(dev, imx93_release_genpd_provider, dev->of_node);
314+
if (ret)
315+
return dev_err_probe(dev, ret, "failed to add genpd_provider release callback\n");
302316

303-
return 0;
304-
305-
cleanup_pds:
306-
for (i--; i >= 0; i--)
307-
pm_genpd_remove(&bc->domains[i].genpd);
308-
309-
return ret;
310-
}
311-
312-
static void imx93_blk_ctrl_remove(struct platform_device *pdev)
313-
{
314-
struct imx93_blk_ctrl *bc = dev_get_drvdata(&pdev->dev);
315-
int i;
316-
317-
of_genpd_del_provider(pdev->dev.of_node);
317+
ret = devm_of_platform_populate(dev);
318+
if (ret)
319+
return dev_err_probe(dev, ret, "failed to populate blk-ctrl sub-devices\n");
318320

319-
pm_runtime_disable(&pdev->dev);
320-
321-
for (i = 0; i < bc->onecell_data.num_domains; i++) {
322-
struct imx93_blk_ctrl_domain *domain = &bc->domains[i];
323-
324-
pm_genpd_remove(&domain->genpd);
325-
}
321+
return 0;
326322
}
327323

328324
static const struct imx93_blk_ctrl_domain_data imx93_media_blk_ctl_domain_data[] = {
@@ -457,7 +453,6 @@ MODULE_DEVICE_TABLE(of, imx93_blk_ctrl_of_match);
457453

458454
static struct platform_driver imx93_blk_ctrl_driver = {
459455
.probe = imx93_blk_ctrl_probe,
460-
.remove = imx93_blk_ctrl_remove,
461456
.driver = {
462457
.name = "imx93-blk-ctrl",
463458
.of_match_table = imx93_blk_ctrl_of_match,

drivers/pmdomain/imx/scu-pd.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ static void imx_sc_pd_get_console_rsrc(void)
326326
return;
327327

328328
imx_con_rsrc = specs.args[0];
329+
of_node_put(specs.np);
329330
}
330331

331332
static int imx_sc_get_pd_power(struct device *dev, u32 rsrc)

0 commit comments

Comments
 (0)