diff options
author | Ulf Hansson <ulf.hansson@linaro.org> | 2015-01-27 15:13:40 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-02-03 16:56:53 -0500 |
commit | 14b530648834c9ec9853954750957bab0f792538 (patch) | |
tree | e5e6905a67adff70fe3df6ffa35f2a9f47ae8c8b | |
parent | c1dbe2fbb33ef425a81e1a7cffd17c113c87cdbc (diff) |
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>
-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, | |||
1444 | if (ret) | 1444 | if (ret) |
1445 | goto out; | 1445 | goto out; |
1446 | 1446 | ||
1447 | genpd->device_count++; | ||
1448 | genpd->max_off_time_changed = true; | ||
1449 | |||
1450 | spin_lock_irq(&dev->power.lock); | 1447 | spin_lock_irq(&dev->power.lock); |
1451 | 1448 | ||
1452 | dev->pm_domain = &genpd->domain; | ||
1453 | if (dev->power.subsys_data->domain_data) { | 1449 | if (dev->power.subsys_data->domain_data) { |
1454 | gpd_data = to_gpd_data(dev->power.subsys_data->domain_data); | 1450 | spin_unlock_irq(&dev->power.lock); |
1455 | } else { | 1451 | ret = -EINVAL; |
1456 | gpd_data = gpd_data_new; | 1452 | goto out; |
1457 | dev->power.subsys_data->domain_data = &gpd_data->base; | ||
1458 | } | 1453 | } |
1454 | |||
1455 | gpd_data = gpd_data_new; | ||
1456 | dev->power.subsys_data->domain_data = &gpd_data->base; | ||
1457 | |||
1459 | if (td) | 1458 | if (td) |
1460 | gpd_data->td = *td; | 1459 | gpd_data->td = *td; |
1461 | 1460 | ||
1461 | dev->pm_domain = &genpd->domain; | ||
1462 | |||
1462 | spin_unlock_irq(&dev->power.lock); | 1463 | spin_unlock_irq(&dev->power.lock); |
1463 | 1464 | ||
1464 | if (genpd->attach_dev) | 1465 | if (genpd->attach_dev) |
1465 | genpd->attach_dev(genpd, dev); | 1466 | genpd->attach_dev(genpd, dev); |
1466 | 1467 | ||
1468 | genpd->device_count++; | ||
1469 | genpd->max_off_time_changed = true; | ||
1470 | |||
1467 | mutex_lock(&gpd_data->lock); | 1471 | mutex_lock(&gpd_data->lock); |
1468 | gpd_data->base.dev = dev; | 1472 | gpd_data->base.dev = dev; |
1469 | list_add_tail(&gpd_data->base.list_node, &genpd->dev_list); | 1473 | list_add_tail(&gpd_data->base.list_node, &genpd->dev_list); |