Commit 46fa233a authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge generic power domains (genpd) material for v4.16 into pm-core

parents 0026cef0 17218e00
Loading
Loading
Loading
Loading
+33 −36
Original line number Original line Diff line number Diff line
@@ -1032,15 +1032,12 @@ static int genpd_prepare(struct device *dev)
static int genpd_finish_suspend(struct device *dev, bool poweroff)
static int genpd_finish_suspend(struct device *dev, bool poweroff)
{
{
	struct generic_pm_domain *genpd;
	struct generic_pm_domain *genpd;
	int ret;
	int ret = 0;


	genpd = dev_to_genpd(dev);
	genpd = dev_to_genpd(dev);
	if (IS_ERR(genpd))
	if (IS_ERR(genpd))
		return -EINVAL;
		return -EINVAL;


	if (dev->power.wakeup_path && genpd_is_active_wakeup(genpd))
		return 0;

	if (poweroff)
	if (poweroff)
		ret = pm_generic_poweroff_noirq(dev);
		ret = pm_generic_poweroff_noirq(dev);
	else
	else
@@ -1048,11 +1045,20 @@ static int genpd_finish_suspend(struct device *dev, bool poweroff)
	if (ret)
	if (ret)
		return ret;
		return ret;


	if (genpd->dev_ops.stop && genpd->dev_ops.start) {
	if (dev->power.wakeup_path && genpd_is_active_wakeup(genpd))
		ret = pm_runtime_force_suspend(dev);
		return 0;
		if (ret)

	if (genpd->dev_ops.stop && genpd->dev_ops.start &&
	    !pm_runtime_status_suspended(dev)) {
		ret = genpd_stop_dev(genpd, dev);
		if (ret) {
			if (poweroff)
				pm_generic_restore_noirq(dev);
			else
				pm_generic_resume_noirq(dev);
			return ret;
			return ret;
		}
		}
	}


	genpd_lock(genpd);
	genpd_lock(genpd);
	genpd->suspended_count++;
	genpd->suspended_count++;
@@ -1085,7 +1091,7 @@ static int genpd_suspend_noirq(struct device *dev)
static int genpd_resume_noirq(struct device *dev)
static int genpd_resume_noirq(struct device *dev)
{
{
	struct generic_pm_domain *genpd;
	struct generic_pm_domain *genpd;
	int ret = 0;
	int ret;


	dev_dbg(dev, "%s()\n", __func__);
	dev_dbg(dev, "%s()\n", __func__);


@@ -1094,21 +1100,21 @@ static int genpd_resume_noirq(struct device *dev)
		return -EINVAL;
		return -EINVAL;


	if (dev->power.wakeup_path && genpd_is_active_wakeup(genpd))
	if (dev->power.wakeup_path && genpd_is_active_wakeup(genpd))
		return 0;
		return pm_generic_resume_noirq(dev);


	genpd_lock(genpd);
	genpd_lock(genpd);
	genpd_sync_power_on(genpd, true, 0);
	genpd_sync_power_on(genpd, true, 0);
	genpd->suspended_count--;
	genpd->suspended_count--;
	genpd_unlock(genpd);
	genpd_unlock(genpd);


	if (genpd->dev_ops.stop && genpd->dev_ops.start)
	if (genpd->dev_ops.stop && genpd->dev_ops.start &&
		ret = pm_runtime_force_resume(dev);
	    !pm_runtime_status_suspended(dev)) {

		ret = genpd_start_dev(genpd, dev);
	ret = pm_generic_resume_noirq(dev);
		if (ret)
		if (ret)
			return ret;
			return ret;
	}


	return ret;
	return pm_generic_resume_noirq(dev);
}
}


/**
/**
@@ -1135,8 +1141,9 @@ static int genpd_freeze_noirq(struct device *dev)
	if (ret)
	if (ret)
		return ret;
		return ret;


	if (genpd->dev_ops.stop && genpd->dev_ops.start)
	if (genpd->dev_ops.stop && genpd->dev_ops.start &&
		ret = pm_runtime_force_suspend(dev);
	    !pm_runtime_status_suspended(dev))
		ret = genpd_stop_dev(genpd, dev);


	return ret;
	return ret;
}
}
@@ -1159,8 +1166,9 @@ static int genpd_thaw_noirq(struct device *dev)
	if (IS_ERR(genpd))
	if (IS_ERR(genpd))
		return -EINVAL;
		return -EINVAL;


	if (genpd->dev_ops.stop && genpd->dev_ops.start) {
	if (genpd->dev_ops.stop && genpd->dev_ops.start &&
		ret = pm_runtime_force_resume(dev);
	    !pm_runtime_status_suspended(dev)) {
		ret = genpd_start_dev(genpd, dev);
		if (ret)
		if (ret)
			return ret;
			return ret;
	}
	}
@@ -1217,8 +1225,9 @@ static int genpd_restore_noirq(struct device *dev)
	genpd_sync_power_on(genpd, true, 0);
	genpd_sync_power_on(genpd, true, 0);
	genpd_unlock(genpd);
	genpd_unlock(genpd);


	if (genpd->dev_ops.stop && genpd->dev_ops.start) {
	if (genpd->dev_ops.stop && genpd->dev_ops.start &&
		ret = pm_runtime_force_resume(dev);
	    !pm_runtime_status_suspended(dev)) {
		ret = genpd_start_dev(genpd, dev);
		if (ret)
		if (ret)
			return ret;
			return ret;
	}
	}
@@ -2199,21 +2208,9 @@ int genpd_dev_pm_attach(struct device *dev)


	ret = of_parse_phandle_with_args(dev->of_node, "power-domains",
	ret = of_parse_phandle_with_args(dev->of_node, "power-domains",
					"#power-domain-cells", 0, &pd_args);
					"#power-domain-cells", 0, &pd_args);
	if (ret < 0) {
	if (ret < 0)
		if (ret != -ENOENT)
		return ret;
		return ret;


		/*
		 * Try legacy Samsung-specific bindings
		 * (for backwards compatibility of DT ABI)
		 */
		pd_args.args_count = 0;
		pd_args.np = of_parse_phandle(dev->of_node,
						"samsung,power-domain", 0);
		if (!pd_args.np)
			return -ENOENT;
	}

	mutex_lock(&gpd_list_lock);
	mutex_lock(&gpd_list_lock);
	pd = genpd_get_from_provider(&pd_args);
	pd = genpd_get_from_provider(&pd_args);
	of_node_put(pd_args.np);
	of_node_put(pd_args.np);