diff options
author | Konrad Dybcio <konrad.dybcio@linaro.org> | 2023-06-19 14:32:26 +0200 |
---|---|---|
committer | Bjorn Andersson <andersson@kernel.org> | 2023-07-09 21:11:32 -0700 |
commit | 98c8b3efacaec61287a096dd37ca3c197f298b70 (patch) | |
tree | c60e9dd79efcc40308052f011bad63146c1c6568 /drivers/soc/qcom | |
parent | 2976eec238dcd89475664795f54d4a4d3d05e0f9 (diff) |
soc: qcom: rpmpd: Add sync_state
Add a sync_state implementation, very similar to the one already present
in the RPMhPD driver.
Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
Link: https://lore.kernel.org/r/20230619-topic-rpmpd_syncstate-v1-1-54f986cf9444@linaro.org
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Diffstat (limited to 'drivers/soc/qcom')
-rw-r--r-- | drivers/soc/qcom/rpmpd.c | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c index 99b017fd76b7..fa58c04214ee 100644 --- a/drivers/soc/qcom/rpmpd.c +++ b/drivers/soc/qcom/rpmpd.c @@ -58,6 +58,7 @@ struct rpmpd { struct qcom_smd_rpm *rpm; unsigned int max_state; __le32 key; + bool state_synced; }; struct rpmpd_desc { @@ -823,7 +824,11 @@ static int rpmpd_aggregate_corner(struct rpmpd *pd) unsigned int this_active_corner = 0, this_sleep_corner = 0; unsigned int peer_active_corner = 0, peer_sleep_corner = 0; - to_active_sleep(pd, pd->corner, &this_active_corner, &this_sleep_corner); + /* Clamp to the highest corner/level if sync_state isn't done yet */ + if (!pd->state_synced) + this_active_corner = this_sleep_corner = pd->max_state - 1; + else + to_active_sleep(pd, pd->corner, &this_active_corner, &this_sleep_corner); if (peer && peer->enabled) to_active_sleep(peer, peer->corner, &peer_active_corner, @@ -973,11 +978,38 @@ static int rpmpd_probe(struct platform_device *pdev) return of_genpd_add_provider_onecell(pdev->dev.of_node, data); } +static void rpmpd_sync_state(struct device *dev) +{ + const struct rpmpd_desc *desc = of_device_get_match_data(dev); + struct rpmpd **rpmpds = desc->rpmpds; + struct rpmpd *pd; + unsigned int i; + int ret; + + mutex_lock(&rpmpd_lock); + for (i = 0; i < desc->num_pds; i++) { + pd = rpmpds[i]; + if (!pd) + continue; + + pd->state_synced = true; + + if (!pd->enabled) + pd->corner = 0; + + ret = rpmpd_aggregate_corner(pd); + if (ret) + dev_err(dev, "failed to sync %s: %d\n", pd->pd.name, ret); + } + mutex_unlock(&rpmpd_lock); +} + static struct platform_driver rpmpd_driver = { .driver = { .name = "qcom-rpmpd", .of_match_table = rpmpd_match_table, .suppress_bind_attrs = true, + .sync_state = rpmpd_sync_state, }, .probe = rpmpd_probe, }; |