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

Commit 62dc7c02 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branch 'pm-domains'

* pm-domains:
  PM / shmobile: Make MTU2 driver use pm_genpd_dev_always_on()
  PM / shmobile: Make CMT driver use pm_genpd_dev_always_on()
  PM / shmobile: Make TMU driver use pm_genpd_dev_always_on()
  PM / Domains: Introduce "always on" device flag
  PM / Domains: Fix hibernation restore of devices, v2
  PM / Domains: Fix handling of wakeup devices during system resume
parents cf3bbcaf 57d13370
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1043,6 +1043,8 @@ void __init sh7372_add_standard_devices(void)
	sh7372_add_device_to_domain(&sh7372_a4r, &veu2_device);
	sh7372_add_device_to_domain(&sh7372_a4r, &veu3_device);
	sh7372_add_device_to_domain(&sh7372_a4r, &jpu_device);
	sh7372_add_device_to_domain(&sh7372_a4r, &tmu00_device);
	sh7372_add_device_to_domain(&sh7372_a4r, &tmu01_device);
}

void __init sh7372_add_early_devices(void)
+53 −16
Original line number Diff line number Diff line
@@ -366,7 +366,7 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
	not_suspended = 0;
	list_for_each_entry(pdd, &genpd->dev_list, list_node)
		if (pdd->dev->driver && (!pm_runtime_suspended(pdd->dev)
		    || pdd->dev->power.irq_safe))
		    || pdd->dev->power.irq_safe || to_gpd_data(pdd)->always_on))
			not_suspended++;

	if (not_suspended > genpd->in_progress)
@@ -503,6 +503,9 @@ static int pm_genpd_runtime_suspend(struct device *dev)

	might_sleep_if(!genpd->dev_irq_safe);

	if (dev_gpd_data(dev)->always_on)
		return -EBUSY;

	stop_ok = genpd->gov ? genpd->gov->stop_ok : NULL;
	if (stop_ok && !stop_ok(dev))
		return -EBUSY;
@@ -764,8 +767,10 @@ static int pm_genpd_prepare(struct device *dev)

	genpd_acquire_lock(genpd);

	if (genpd->prepared_count++ == 0)
	if (genpd->prepared_count++ == 0) {
		genpd->suspended_count = 0;
		genpd->suspend_power_off = genpd->status == GPD_STATE_POWER_OFF;
	}

	genpd_release_lock(genpd);

@@ -857,7 +862,7 @@ static int pm_genpd_suspend_noirq(struct device *dev)
	if (IS_ERR(genpd))
		return -EINVAL;

	if (genpd->suspend_power_off
	if (genpd->suspend_power_off || dev_gpd_data(dev)->always_on
	    || (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev)))
		return 0;

@@ -890,7 +895,8 @@ static int pm_genpd_resume_noirq(struct device *dev)
	if (IS_ERR(genpd))
		return -EINVAL;

	if (genpd->suspend_power_off)
	if (genpd->suspend_power_off || dev_gpd_data(dev)->always_on
	    || (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev)))
		return 0;

	/*
@@ -1009,7 +1015,8 @@ static int pm_genpd_freeze_noirq(struct device *dev)
	if (IS_ERR(genpd))
		return -EINVAL;

	return genpd->suspend_power_off ? 0 : genpd_stop_dev(genpd, dev);
	return genpd->suspend_power_off || dev_gpd_data(dev)->always_on ?
		0 : genpd_stop_dev(genpd, dev);
}

/**
@@ -1029,7 +1036,8 @@ static int pm_genpd_thaw_noirq(struct device *dev)
	if (IS_ERR(genpd))
		return -EINVAL;

	return genpd->suspend_power_off ? 0 : genpd_start_dev(genpd, dev);
	return genpd->suspend_power_off || dev_gpd_data(dev)->always_on ?
		0 : genpd_start_dev(genpd, dev);
}

/**
@@ -1096,22 +1104,32 @@ static int pm_genpd_restore_noirq(struct device *dev)
	 * Since all of the "noirq" callbacks are executed sequentially, it is
	 * guaranteed that this function will never run twice in parallel for
	 * the same PM domain, so it is not necessary to use locking here.
	 *
	 * At this point suspended_count == 0 means we are being run for the
	 * first time for the given domain in the present cycle.
	 */
	if (genpd->suspended_count++ == 0) {
		/*
		 * The boot kernel might put the domain into arbitrary state,
		 * so make it appear as powered off to pm_genpd_poweron(), so
		 * that it tries to power it on in case it was really off.
		 */
		genpd->status = GPD_STATE_POWER_OFF;
		if (genpd->suspend_power_off) {
			/*
		 * The boot kernel might put the domain into the power on state,
		 * so make sure it really is powered off.
			 * If the domain was off before the hibernation, make
			 * sure it will be off going forward.
			 */
			if (genpd->power_off)
				genpd->power_off(genpd);

			return 0;
		}
	}

	pm_genpd_poweron(genpd);
	genpd->suspended_count--;

	return genpd_start_dev(genpd, dev);
	return dev_gpd_data(dev)->always_on ? 0 : genpd_start_dev(genpd, dev);
}

/**
@@ -1306,6 +1324,26 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd,
	return ret;
}

/**
 * pm_genpd_dev_always_on - Set/unset the "always on" flag for a given device.
 * @dev: Device to set/unset the flag for.
 * @val: The new value of the device's "always on" flag.
 */
void pm_genpd_dev_always_on(struct device *dev, bool val)
{
	struct pm_subsys_data *psd;
	unsigned long flags;

	spin_lock_irqsave(&dev->power.lock, flags);

	psd = dev_to_psd(dev);
	if (psd && psd->domain_data)
		to_gpd_data(psd->domain_data)->always_on = val;

	spin_unlock_irqrestore(&dev->power.lock, flags);
}
EXPORT_SYMBOL_GPL(pm_genpd_dev_always_on);

/**
 * pm_genpd_add_subdomain - Add a subdomain to an I/O PM domain.
 * @genpd: Master PM domain to add the subdomain to.
@@ -1648,7 +1686,6 @@ void pm_genpd_init(struct generic_pm_domain *genpd,
	genpd->poweroff_task = NULL;
	genpd->resume_count = 0;
	genpd->device_count = 0;
	genpd->suspended_count = 0;
	genpd->max_off_time_ns = -1;
	genpd->domain.ops.runtime_suspend = pm_genpd_runtime_suspend;
	genpd->domain.ops.runtime_resume = pm_genpd_runtime_resume;
+4 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include <linux/sh_timer.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/pm_domain.h>

struct sh_cmt_priv {
	void __iomem *mapbase;
@@ -689,6 +690,9 @@ static int __devinit sh_cmt_probe(struct platform_device *pdev)
	struct sh_cmt_priv *p = platform_get_drvdata(pdev);
	int ret;

	if (!is_early_platform_device(pdev))
		pm_genpd_dev_always_on(&pdev->dev, true);

	if (p) {
		dev_info(&pdev->dev, "kept as earlytimer\n");
		return 0;
+4 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include <linux/sh_timer.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/pm_domain.h>

struct sh_mtu2_priv {
	void __iomem *mapbase;
@@ -306,6 +307,9 @@ static int __devinit sh_mtu2_probe(struct platform_device *pdev)
	struct sh_mtu2_priv *p = platform_get_drvdata(pdev);
	int ret;

	if (!is_early_platform_device(pdev))
		pm_genpd_dev_always_on(&pdev->dev, true);

	if (p) {
		dev_info(&pdev->dev, "kept as earlytimer\n");
		return 0;
+4 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include <linux/sh_timer.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/pm_domain.h>

struct sh_tmu_priv {
	void __iomem *mapbase;
@@ -410,6 +411,9 @@ static int __devinit sh_tmu_probe(struct platform_device *pdev)
	struct sh_tmu_priv *p = platform_get_drvdata(pdev);
	int ret;

	if (!is_early_platform_device(pdev))
		pm_genpd_dev_always_on(&pdev->dev, true);

	if (p) {
		dev_info(&pdev->dev, "kept as earlytimer\n");
		return 0;
Loading