When a PM domain provider is added, there is currently no way to tell if
any PM domains associated with the provider are present. Naturally, the
PM domain provider should not be registered if the PM domains have not
been added. Nonetheless, verify that the PM domain(s) associated with a
provider are present when registering the PM domain provider.
This change adds a dependency on the function pm_genpd_present() when
CONFIG_PM_GENERIC_DOMAINS_OF is enabled and so ensure this function is
available when CONFIG_PM_GENERIC_DOMAINS_OF selected.
Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
}
late_initcall(genpd_poweroff_unused);
}
late_initcall(genpd_poweroff_unused);
+#if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM_GENERIC_DOMAINS_OF)
/**
* pm_genpd_present - Check if the given PM domain has been initialized.
/**
* pm_genpd_present - Check if the given PM domain has been initialized.
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+
static bool genpd_dev_active_wakeup(struct generic_pm_domain *genpd,
struct device *dev)
{
static bool genpd_dev_active_wakeup(struct generic_pm_domain *genpd,
struct device *dev)
{
int of_genpd_add_provider_simple(struct device_node *np,
struct generic_pm_domain *genpd)
{
int of_genpd_add_provider_simple(struct device_node *np,
struct generic_pm_domain *genpd)
{
- return genpd_add_provider(np, genpd_xlate_simple, genpd);
+ int ret = -EINVAL;
+
+ if (!np || !genpd)
+ return -EINVAL;
+
+ mutex_lock(&gpd_list_lock);
+
+ if (pm_genpd_present(genpd))
+ ret = genpd_add_provider(np, genpd_xlate_simple, genpd);
+
+ mutex_unlock(&gpd_list_lock);
+
+ return ret;
}
EXPORT_SYMBOL_GPL(of_genpd_add_provider_simple);
}
EXPORT_SYMBOL_GPL(of_genpd_add_provider_simple);
int of_genpd_add_provider_onecell(struct device_node *np,
struct genpd_onecell_data *data)
{
int of_genpd_add_provider_onecell(struct device_node *np,
struct genpd_onecell_data *data)
{
- return genpd_add_provider(np, genpd_xlate_onecell, data);
+ unsigned int i;
+ int ret;
+
+ if (!np || !data)
+ return -EINVAL;
+
+ 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;
+ }
+ }
+
+ ret = genpd_add_provider(np, genpd_xlate_onecell, data);
+
+ mutex_unlock(&gpd_list_lock);
+
+ return ret;
}
EXPORT_SYMBOL_GPL(of_genpd_add_provider_onecell);
}
EXPORT_SYMBOL_GPL(of_genpd_add_provider_onecell);