#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;
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);
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);
}
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);
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);
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);