Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3e235685 authored by Ulf Hansson's avatar Ulf Hansson Committed by Rafael J. Wysocki
Browse files

PM / Domains: Free pm_subsys_data in error path in __pm_genpd_add_device()



The error path in __pm_genpd_add_device() didn't decrease the reference
to the struct pm_subsys_data.

Let's move the calls to dev_pm_get|put_subsys_data() into
genpd_alloc|free_dev_data() to fix this issue and thus prevent a
potential memory leakage.

Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent c0356db7
Loading
Loading
Loading
Loading
+16 −9
Original line number Diff line number Diff line
@@ -1380,18 +1380,30 @@ EXPORT_SYMBOL_GPL(pm_genpd_syscore_poweron);
static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev)
{
	struct generic_pm_domain_data *gpd_data;
	int ret;

	ret = dev_pm_get_subsys_data(dev);
	if (ret)
		return ERR_PTR(ret);

	gpd_data = kzalloc(sizeof(*gpd_data), GFP_KERNEL);
	if (!gpd_data)
		return NULL;
	if (!gpd_data) {
		ret = -ENOMEM;
		goto err_put;
	}

	return 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)
{
	kfree(gpd_data);
	dev_pm_put_subsys_data(dev);
}

/**
@@ -1412,8 +1424,8 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
		return -EINVAL;

	gpd_data = genpd_alloc_dev_data(dev);
	if (!gpd_data)
		return -ENOMEM;
	if (IS_ERR(gpd_data))
		return PTR_ERR(gpd_data);

	genpd_acquire_lock(genpd);

@@ -1422,10 +1434,6 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
		goto out;
	}

	ret = dev_pm_get_subsys_data(dev);
	if (ret)
		goto out;

	spin_lock_irq(&dev->power.lock);

	if (dev->power.subsys_data->domain_data) {
@@ -1528,7 +1536,6 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd,

	genpd_release_lock(genpd);

	dev_pm_put_subsys_data(dev);
	genpd_free_dev_data(dev, gpd_data);

	return 0;