Skip to content

Commit

Permalink
PM / Domains: Re-order initialization of generic_pm_domain_data
Browse files Browse the repository at this point in the history
Move the initialization of the struct generic_pm_domain_data into
genpd_alloc_dev_data(), including the assignment of the device's
->pm_domain() callback. Make corresponding changes to
genpd_free_dev_data().

These changes will make the related code more readable. It will also
decrease the critical regions for where genpd's mutex is being held and
for where the device's power related spinlock is being held.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  • Loading branch information
storulf authored and rafaeljw committed Feb 3, 2015
1 parent 3e23568 commit f104e1e
Showing 1 changed file with 35 additions and 32 deletions.
67 changes: 35 additions & 32 deletions drivers/base/power/domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -1377,7 +1377,9 @@ EXPORT_SYMBOL_GPL(pm_genpd_syscore_poweron);

#endif /* CONFIG_PM_SLEEP */

static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev)
static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev,
struct generic_pm_domain *genpd,
struct gpd_timing_data *td)
{
struct generic_pm_domain_data *gpd_data;
int ret;
Expand All @@ -1392,8 +1394,32 @@ static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev)
goto err_put;
}

if (td)
gpd_data->td = *td;

gpd_data->base.dev = dev;
gpd_data->need_restore = -1;
gpd_data->td.constraint_changed = true;
gpd_data->td.effective_constraint_ns = -1;
gpd_data->nb.notifier_call = genpd_dev_pm_qos_notifier;

spin_lock_irq(&dev->power.lock);

if (dev->power.subsys_data->domain_data) {
ret = -EINVAL;
goto err_free;
}

dev->power.subsys_data->domain_data = &gpd_data->base;
dev->pm_domain = &genpd->domain;

spin_unlock_irq(&dev->power.lock);

return gpd_data;

err_free:
spin_unlock_irq(&dev->power.lock);
kfree(gpd_data);
err_put:
dev_pm_put_subsys_data(dev);
return ERR_PTR(ret);
Expand All @@ -1402,6 +1428,13 @@ static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev)
static void genpd_free_dev_data(struct device *dev,
struct generic_pm_domain_data *gpd_data)
{
spin_lock_irq(&dev->power.lock);

dev->pm_domain = NULL;
dev->power.subsys_data->domain_data = NULL;

spin_unlock_irq(&dev->power.lock);

kfree(gpd_data);
dev_pm_put_subsys_data(dev);
}
Expand All @@ -1423,7 +1456,7 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev))
return -EINVAL;

gpd_data = genpd_alloc_dev_data(dev);
gpd_data = genpd_alloc_dev_data(dev, genpd, td);
if (IS_ERR(gpd_data))
return PTR_ERR(gpd_data);

Expand All @@ -1434,35 +1467,13 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
goto out;
}

spin_lock_irq(&dev->power.lock);

if (dev->power.subsys_data->domain_data) {
spin_unlock_irq(&dev->power.lock);
ret = -EINVAL;
goto out;
}

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;

gpd_data->base.dev = dev;
list_add_tail(&gpd_data->base.list_node, &genpd->dev_list);
gpd_data->need_restore = -1;
gpd_data->td.constraint_changed = true;
gpd_data->td.effective_constraint_ns = -1;
gpd_data->nb.notifier_call = genpd_dev_pm_qos_notifier;

out:
genpd_release_lock(genpd);
Expand Down Expand Up @@ -1524,15 +1535,7 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd,
if (genpd->detach_dev)
genpd->detach_dev(genpd, dev);

spin_lock_irq(&dev->power.lock);

dev->pm_domain = NULL;
list_del_init(&pdd->list_node);
dev->power.subsys_data->domain_data = NULL;

spin_unlock_irq(&dev->power.lock);

pdd->dev = NULL;

genpd_release_lock(genpd);

Expand Down

0 comments on commit f104e1e

Please sign in to comment.