[PATCH 09/10] PM / Domains: Store the provider in the PM domain structure
Jon Hunter
jonathanh at nvidia.com
Fri Sep 9 06:57:45 PDT 2016
On 08/09/16 12:56, Ulf Hansson wrote:
> On 16 August 2016 at 11:49, Jon Hunter <jonathanh at nvidia.com> wrote:
>> It is possible that a device has more than one provider of PM domains
>> and to support the removal of a PM domain by provider, it is necessary
>> to store a reference to the provider in the PM domain structure.
>> Therefore, store a reference to the firmware node handle in the PM
>> domain structure and populate it when providers (only device-tree based
>> providers are currently supported by PM domains) are registered.
>>
>> Signed-off-by: Jon Hunter <jonathanh at nvidia.com>
>> ---
>> drivers/base/power/domain.c | 18 ++++++++++++++----
>> include/linux/pm_domain.h | 1 +
>> 2 files changed, 15 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
>> index 72b973539205..0bc145e8e902 100644
>> --- a/drivers/base/power/domain.c
>> +++ b/drivers/base/power/domain.c
>> @@ -1539,6 +1539,8 @@ int of_genpd_add_provider_simple(struct device_node *np,
>> return -EINVAL;
>> }
>>
>> + genpd->provider = &np->fwnode;
>> +
>> ret = genpd_add_provider(np, genpd_xlate_simple, genpd);
>
> I guess you want to reset genpd->provider = NULL, when
> genpd_add_provider() fails!?
Yes, will fix.
> Perhaps better to assign genpd->provider when you know
> genpd_add_provider() has succeeded.
Yes seems sane!
>>
>> mutex_unlock(&gpd_list_lock);
>> @@ -1564,10 +1566,10 @@ int of_genpd_add_provider_onecell(struct device_node *np,
>> mutex_lock(&gpd_list_lock);
>>
>> for (i = 0; i < data->num_domains; i++) {
>> - if (!pm_genpd_present(data->domains[i])) {
>> - mutex_unlock(&gpd_list_lock);
>> - return -EINVAL;
>> - }
>> + if (!pm_genpd_present(data->domains[i]))
>> + goto error;
>> +
>> + data->domains[i]->provider = &np->fwnode;
>> }
>>
>> ret = genpd_add_provider(np, genpd_xlate_onecell, data);
>> @@ -1575,6 +1577,14 @@ int of_genpd_add_provider_onecell(struct device_node *np,
>> mutex_unlock(&gpd_list_lock);
>>
>> return ret;
>> +
>> +error:
>> + while (i--)
>> + data->domains[i]->provider = NULL;
>> +
>> + mutex_unlock(&gpd_list_lock);
>> +
>> + return -EINVAL;
>> }
>> EXPORT_SYMBOL_GPL(of_genpd_add_provider_onecell);
>>
>> diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
>> index fbdc5c4588ef..4aa285e44eb0 100644
>> --- a/include/linux/pm_domain.h
>> +++ b/include/linux/pm_domain.h
>> @@ -51,6 +51,7 @@ struct generic_pm_domain {
>> struct mutex lock;
>> struct dev_power_governor *gov;
>> struct work_struct power_off_work;
>> + struct fwnode_handle *provider; /* Identity of the domain provider */
>> const char *name;
>> atomic_t sd_count; /* Number of subdomains with power "on" */
>> enum gpd_status status; /* Current state of the domain */
>> --
>> 2.1.4
>>
>
> I also think you should extend this change, to also make the
> of_genpd_del_provider() API to reset the genpd->provider = NULL.
> Otherwise you can't track when a provider is removed.
Unfortunately that is not going to work. The function
of_genpd_remove_tail() (patch #10) uses the ->provider member to remove
the last domain for the given provider and of_genpd_del_provider() must
be called before hand.
Cheers
Jon
--
nvpublic
More information about the linux-arm-kernel
mailing list