diff options
author | Ulf Hansson <ulf.hansson@linaro.org> | 2015-01-27 23:13:40 +0300 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-02-04 00:56:53 +0300 |
commit | 14b530648834c9ec9853954750957bab0f792538 (patch) | |
tree | e5e6905a67adff70fe3df6ffa35f2a9f47ae8c8b /drivers/base | |
parent | c1dbe2fbb33ef425a81e1a7cffd17c113c87cdbc (diff) | |
download | linux-14b530648834c9ec9853954750957bab0f792538.tar.xz |
PM / Domains: Don't allow an existing generic_pm_domain_data
When adding a device to a genpd, a struct generic_pm_domain_data is
allocated per device.
Verify that there are no existing generic_pm_domain_data for the device
we are about to add, since that tells us it has already been added to a
genpd.
When genpd supported PM domain device callbacks, this was a valid
scenario. Now it isn't so let's return an error code.
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/power/domain.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 351df5bbd9c9..76eb0c3ef2b3 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -1444,26 +1444,30 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, if (ret) goto out; - genpd->device_count++; - genpd->max_off_time_changed = true; - spin_lock_irq(&dev->power.lock); - dev->pm_domain = &genpd->domain; if (dev->power.subsys_data->domain_data) { - gpd_data = to_gpd_data(dev->power.subsys_data->domain_data); - } else { - gpd_data = gpd_data_new; - dev->power.subsys_data->domain_data = &gpd_data->base; + spin_unlock_irq(&dev->power.lock); + ret = -EINVAL; + goto out; } + + gpd_data = gpd_data_new; + dev->power.subsys_data->domain_data = &gpd_data->base; + if (td) gpd_data->td = *td; + dev->pm_domain = &genpd->domain; + spin_unlock_irq(&dev->power.lock); if (genpd->attach_dev) genpd->attach_dev(genpd, dev); + genpd->device_count++; + genpd->max_off_time_changed = true; + mutex_lock(&gpd_data->lock); gpd_data->base.dev = dev; list_add_tail(&gpd_data->base.list_node, &genpd->dev_list); |