diff options
Diffstat (limited to 'drivers/pmdomain/arm/scmi_pm_domain.c')
| -rw-r--r-- | drivers/pmdomain/arm/scmi_pm_domain.c | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/drivers/pmdomain/arm/scmi_pm_domain.c b/drivers/pmdomain/arm/scmi_pm_domain.c index a7784a8bb5db..b5e2ffd5ea64 100644 --- a/drivers/pmdomain/arm/scmi_pm_domain.c +++ b/drivers/pmdomain/arm/scmi_pm_domain.c @@ -22,39 +22,26 @@ struct scmi_pm_domain { #define to_scmi_pd(gpd) container_of(gpd, struct scmi_pm_domain, genpd) -static int scmi_pd_power(struct generic_pm_domain *domain, bool power_on) +static int scmi_pd_power(struct generic_pm_domain *domain, u32 state) { - int ret; - u32 state, ret_state; struct scmi_pm_domain *pd = to_scmi_pd(domain); - if (power_on) - state = SCMI_POWER_STATE_GENERIC_ON; - else - state = SCMI_POWER_STATE_GENERIC_OFF; - - ret = power_ops->state_set(pd->ph, pd->domain, state); - if (!ret) - ret = power_ops->state_get(pd->ph, pd->domain, &ret_state); - if (!ret && state != ret_state) - return -EIO; - - return ret; + return power_ops->state_set(pd->ph, pd->domain, state); } static int scmi_pd_power_on(struct generic_pm_domain *domain) { - return scmi_pd_power(domain, true); + return scmi_pd_power(domain, SCMI_POWER_STATE_GENERIC_ON); } static int scmi_pd_power_off(struct generic_pm_domain *domain) { - return scmi_pd_power(domain, false); + return scmi_pd_power(domain, SCMI_POWER_STATE_GENERIC_OFF); } static int scmi_pm_domain_probe(struct scmi_device *sdev) { - int num_domains, i; + int num_domains, i, ret; struct device *dev = &sdev->dev; struct device_node *np = dev->of_node; struct scmi_pm_domain *scmi_pd; @@ -96,6 +83,14 @@ static int scmi_pm_domain_probe(struct scmi_device *sdev) continue; } + /* + * Register the explicit power on request to the firmware so + * that it is tracked as used by OSPM agent and not + * accidentally turned off with OSPM's knowledge + */ + if (state == SCMI_POWER_STATE_GENERIC_ON) + power_ops->state_set(ph, i, state); + scmi_pd->domain = i; scmi_pd->ph = ph; scmi_pd->name = power_ops->name_get(ph, i); @@ -113,9 +108,18 @@ static int scmi_pm_domain_probe(struct scmi_device *sdev) scmi_pd_data->domains = domains; scmi_pd_data->num_domains = num_domains; + ret = of_genpd_add_provider_onecell(np, scmi_pd_data); + if (ret) + goto err_rm_genpds; + dev_set_drvdata(dev, scmi_pd_data); - return of_genpd_add_provider_onecell(np, scmi_pd_data); + return 0; +err_rm_genpds: + for (i = num_domains - 1; i >= 0; i--) + pm_genpd_remove(domains[i]); + + return ret; } static void scmi_pm_domain_remove(struct scmi_device *sdev) |
