linux-sh.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC][PATCH] PM: Make power domain callbacks take precedence over subsystem ones
@ 2011-04-13  0:05 Rafael J. Wysocki
  2011-04-13 14:17 ` [RFC][PATCH] PM: Make power domain callbacks take precedence Alan Stern
                   ` (4 more replies)
  0 siblings, 5 replies; 64+ messages in thread
From: Rafael J. Wysocki @ 2011-04-13  0:05 UTC (permalink / raw)
  To: Linux PM mailing list
  Cc: Kevin Hilman, LKML, Grant Likely, Len Brown, linux-sh, lethal,
	Magnus Damm, Alan Stern

From: Rafael J. Wysocki <rjw@sisk.pl>

Change the PM core's behavior related to power domains in such a way
that, if a power domain is defined for a given device, its callbacks
will be executed instead of and not in addition to the device
subsystem's PM callbacks.

The idea behind the initial implementation of power domains handling
by the PM core was that power domain callbacks would be executed in
addition to subsystem callbacks, so that it would be possible to
extend the subsystem callbacks by using power domains.  It turns out,
however, that this wouldn't be really convenient in some important
situations.

For example, there are systems in which power can only be removed
from entire power domains.  On those systems it is not desirable to
execute device drivers' PM callbacks until it is known that power is
going to be removed from the devices in question, which means that
they should be executed by power domain callbacks rather then by
subsystem (e.g. bus type) PM callbacks, because subsystems generally
have no information about what devices belong to which power domain.
Thus, for instance, if the bus type in question is the platform bus
type, its PM callbacks generally should not be called in addition to
power domain callbacks, because they run device drivers' callbacks
unconditionally if defined.

While in principle the default subsystem PM callbacks, or a subset of
them, may be replaced with different functions, it doesn't seem
correct to do so, because that would change the subsystem's behavior
with respect to all devices in the system, regardless of whether or
not they belong to any power domains.  Thus, the only remaining
option is to make power domain callbacks take precedence over
subsystem callbacks.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
 drivers/base/power/main.c    |   64 ++++++++++++++++++++-----------------------
 drivers/base/power/runtime.c |   29 ++++++-------------
 2 files changed, 41 insertions(+), 52 deletions(-)

Index: linux-2.6/drivers/base/power/runtime.c
=================================--- linux-2.6.orig/drivers/base/power/runtime.c
+++ linux-2.6/drivers/base/power/runtime.c
@@ -168,7 +168,6 @@ static int rpm_check_suspend_allowed(str
 static int rpm_idle(struct device *dev, int rpmflags)
 {
 	int (*callback)(struct device *);
-	int (*domain_callback)(struct device *);
 	int retval;
 
 	retval = rpm_check_suspend_allowed(dev);
@@ -214,7 +213,9 @@ static int rpm_idle(struct device *dev,
 
 	dev->power.idle_notification = true;
 
-	if (dev->type && dev->type->pm)
+	if (dev->pwr_domain)
+		callback = dev->pwr_domain->ops.runtime_idle;
+	else if (dev->type && dev->type->pm)
 		callback = dev->type->pm->runtime_idle;
 	else if (dev->class && dev->class->pm)
 		callback = dev->class->pm->runtime_idle;
@@ -223,19 +224,10 @@ static int rpm_idle(struct device *dev,
 	else
 		callback = NULL;
 
-	if (dev->pwr_domain)
-		domain_callback = dev->pwr_domain->ops.runtime_idle;
-	else
-		domain_callback = NULL;
-
-	if (callback || domain_callback) {
+	if (callback) {
 		spin_unlock_irq(&dev->power.lock);
 
-		if (domain_callback)
-			retval = domain_callback(dev);
-
-		if (!retval && callback)
-			callback(dev);
+		callback(dev);
 
 		spin_lock_irq(&dev->power.lock);
 	}
@@ -382,7 +374,9 @@ static int rpm_suspend(struct device *de
 
 	__update_runtime_status(dev, RPM_SUSPENDING);
 
-	if (dev->type && dev->type->pm)
+	if (dev->pwr_domain)
+		callback = dev->pwr_domain->ops.runtime_suspend;
+	else if (dev->type && dev->type->pm)
 		callback = dev->type->pm->runtime_suspend;
 	else if (dev->class && dev->class->pm)
 		callback = dev->class->pm->runtime_suspend;
@@ -400,8 +394,6 @@ static int rpm_suspend(struct device *de
 		else
 			pm_runtime_cancel_pending(dev);
 	} else {
-		if (dev->pwr_domain)
-			rpm_callback(dev->pwr_domain->ops.runtime_suspend, dev);
  no_callback:
 		__update_runtime_status(dev, RPM_SUSPENDED);
 		pm_runtime_deactivate_timer(dev);
@@ -582,9 +574,8 @@ static int rpm_resume(struct device *dev
 	__update_runtime_status(dev, RPM_RESUMING);
 
 	if (dev->pwr_domain)
-		rpm_callback(dev->pwr_domain->ops.runtime_resume, dev);
-
-	if (dev->type && dev->type->pm)
+		callback = dev->pwr_domain->ops.runtime_resume;
+	else if (dev->type && dev->type->pm)
 		callback = dev->type->pm->runtime_resume;
 	else if (dev->class && dev->class->pm)
 		callback = dev->class->pm->runtime_resume;
Index: linux-2.6/drivers/base/power/main.c
=================================--- linux-2.6.orig/drivers/base/power/main.c
+++ linux-2.6/drivers/base/power/main.c
@@ -425,10 +425,8 @@ static int device_resume_noirq(struct de
 
 	if (dev->pwr_domain) {
 		pm_dev_dbg(dev, state, "EARLY power domain ");
-		pm_noirq_op(dev, &dev->pwr_domain->ops, state);
-	}
-
-	if (dev->type && dev->type->pm) {
+		error = pm_noirq_op(dev, &dev->pwr_domain->ops, state);
+	} else if (dev->type && dev->type->pm) {
 		pm_dev_dbg(dev, state, "EARLY type ");
 		error = pm_noirq_op(dev, dev->type->pm, state);
 	} else if (dev->class && dev->class->pm) {
@@ -516,7 +514,8 @@ static int device_resume(struct device *
 
 	if (dev->pwr_domain) {
 		pm_dev_dbg(dev, state, "power domain ");
-		pm_op(dev, &dev->pwr_domain->ops, state);
+		error = pm_op(dev, &dev->pwr_domain->ops, state);
+		goto End;
 	}
 
 	if (dev->type && dev->type->pm) {
@@ -628,12 +627,11 @@ static void device_complete(struct devic
 {
 	device_lock(dev);
 
-	if (dev->pwr_domain && dev->pwr_domain->ops.complete) {
+	if (dev->pwr_domain) {
 		pm_dev_dbg(dev, state, "completing power domain ");
-		dev->pwr_domain->ops.complete(dev);
-	}
-
-	if (dev->type && dev->type->pm) {
+		if (dev->pwr_domain->ops.complete)
+			dev->pwr_domain->ops.complete(dev);
+	} else if (dev->type && dev->type->pm) {
 		pm_dev_dbg(dev, state, "completing type ");
 		if (dev->type->pm->complete)
 			dev->type->pm->complete(dev);
@@ -731,7 +729,12 @@ static int device_suspend_noirq(struct d
 {
 	int error;
 
-	if (dev->type && dev->type->pm) {
+	if (dev->pwr_domain) {
+		pm_dev_dbg(dev, state, "LATE power domain ");
+		error = pm_noirq_op(dev, &dev->pwr_domain->ops, state);
+		if (error)
+			return error;
+	} else if (dev->type && dev->type->pm) {
 		pm_dev_dbg(dev, state, "LATE type ");
 		error = pm_noirq_op(dev, dev->type->pm, state);
 		if (error)
@@ -748,11 +751,6 @@ static int device_suspend_noirq(struct d
 			return error;
 	}
 
-	if (dev->pwr_domain) {
-		pm_dev_dbg(dev, state, "LATE power domain ");
-		pm_noirq_op(dev, &dev->pwr_domain->ops, state);
-	}
-
 	return 0;
 }
 
@@ -840,21 +838,27 @@ static int __device_suspend(struct devic
 		goto End;
 	}
 
+	if (dev->pwr_domain) {
+		pm_dev_dbg(dev, state, "power domain ");
+		error = pm_op(dev, &dev->pwr_domain->ops, state);
+		goto End;
+	}
+
 	if (dev->type && dev->type->pm) {
 		pm_dev_dbg(dev, state, "type ");
 		error = pm_op(dev, dev->type->pm, state);
-		goto Domain;
+		goto End;
 	}
 
 	if (dev->class) {
 		if (dev->class->pm) {
 			pm_dev_dbg(dev, state, "class ");
 			error = pm_op(dev, dev->class->pm, state);
-			goto Domain;
+			goto End;
 		} else if (dev->class->suspend) {
 			pm_dev_dbg(dev, state, "legacy class ");
 			error = legacy_suspend(dev, state, dev->class->suspend);
-			goto Domain;
+			goto End;
 		}
 	}
 
@@ -868,12 +872,6 @@ static int __device_suspend(struct devic
 		}
 	}
 
- Domain:
-	if (!error && dev->pwr_domain) {
-		pm_dev_dbg(dev, state, "power domain ");
-		pm_op(dev, &dev->pwr_domain->ops, state);
-	}
-
  End:
 	device_unlock(dev);
 	complete_all(&dev->power.completion);
@@ -964,7 +962,14 @@ static int device_prepare(struct device
 
 	device_lock(dev);
 
-	if (dev->type && dev->type->pm) {
+	if (dev->pwr_domain) {
+		pm_dev_dbg(dev, state, "preparing power domain ");
+		if (dev->pwr_domain->ops.prepare)
+			error = dev->pwr_domain->ops.prepare(dev);
+		suspend_report_result(dev->pwr_domain->ops.prepare, error);
+		if (error)
+			goto End;
+	} else if (dev->type && dev->type->pm) {
 		pm_dev_dbg(dev, state, "preparing type ");
 		if (dev->type->pm->prepare)
 			error = dev->type->pm->prepare(dev);
@@ -983,13 +988,6 @@ static int device_prepare(struct device
 		if (dev->bus->pm->prepare)
 			error = dev->bus->pm->prepare(dev);
 		suspend_report_result(dev->bus->pm->prepare, error);
-		if (error)
-			goto End;
-	}
-
-	if (dev->pwr_domain && dev->pwr_domain->ops.prepare) {
-		pm_dev_dbg(dev, state, "preparing power domain ");
-		dev->pwr_domain->ops.prepare(dev);
 	}
 
  End:

^ permalink raw reply	[flat|nested] 64+ messages in thread

end of thread, other threads:[~2011-05-16 18:26 UTC | newest]

Thread overview: 64+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-04-13  0:05 [RFC][PATCH] PM: Make power domain callbacks take precedence over subsystem ones Rafael J. Wysocki
2011-04-13 14:17 ` [RFC][PATCH] PM: Make power domain callbacks take precedence Alan Stern
2011-04-13 16:15   ` [RFC][PATCH] PM: Make power domain callbacks take precedence over Grant Likely
2011-04-14 23:12     ` [RFC][PATCH] PM: Make power domain callbacks take precedence over subsystem ones Rafael J. Wysocki
2011-04-15 14:38       ` [RFC][PATCH] PM: Make power domain callbacks take precedence over Grant Likely
2011-04-15 14:39       ` [RFC][PATCH] PM: Make power domain callbacks take precedence Alan Stern
2011-04-14 18:20 ` [RFC][PATCH] PM: Make power domain callbacks take precedence over Magnus Damm
2011-04-14 22:45   ` [RFC][PATCH] PM: Make power domain callbacks take precedence over subsystem ones Rafael J. Wysocki
2011-04-15 14:34     ` [RFC][PATCH] PM: Make power domain callbacks take precedence Alan Stern
2011-04-15 23:18       ` [RFC][PATCH] PM: Make power domain callbacks take precedence over subsystem ones Rafael J. Wysocki
2011-04-16 17:15         ` [RFC][PATCH] PM: Make power domain callbacks take precedence Kevin Hilman
2011-04-16 23:12           ` [RFC][PATCH] PM: Make power domain callbacks take precedence over subsystem ones Rafael J. Wysocki
2011-04-14 23:16 ` [RFC][PATCH 0/2] Remove __weak definitions of platform PM callbacks Rafael J. Wysocki
2011-04-14 23:18   ` [RFC][PATCH 1/2] shmobile: Use power domains for platform runtime PM Rafael J. Wysocki
2011-04-14 23:19   ` [RFC][PATCH 2/2] PM / Platform: Use generic runtime PM callbacks directly Rafael J. Wysocki
2011-04-16 17:17 ` [RFC][PATCH] PM: Make power domain callbacks take precedence Kevin Hilman
2011-04-16 23:35 ` [PATCH 0/9] PM: Rework shmobile and OMAP runtime PM using power domains Rafael J. Wysocki
2011-04-16 23:36   ` [PATCH 1/9] PM: Make power domain callbacks take precedence over subsystem ones Rafael J. Wysocki
2011-04-16 23:37   ` [PATCH 2/9] PM: Export platform bus type's default PM callbacks Rafael J. Wysocki
2011-04-16 23:38   ` [PATCH 3/9] shmobile: Use power domains for platform runtime PM Rafael J. Wysocki
2011-04-16 23:38   ` [PATCH 4/9] PM / Platform: Use generic runtime PM callbacks directly Rafael J. Wysocki
2011-04-16 23:39   ` [PATCH 5/9] OMAP2+ / PM: Move runtime PM implementation to use power domains Rafael J. Wysocki
2011-04-16 23:40   ` [PATCH 6/9] PM / Runtime: Add subsystem data field to struct dev_pm_info Rafael J. Wysocki
2011-04-16 23:42   ` [PATCH 7/9] PM / Runtime: Add generic clock manipulation rountines for runtime PM Rafael J. Wysocki
2011-04-18 19:59     ` [Update][PATCH " Rafael J. Wysocki
2011-04-19 10:18       ` [Update][PATCH 7/9] PM / Runtime: Add generic clock manipulation Magnus Damm
2011-04-19 21:42         ` [Update][PATCH 7/9] PM / Runtime: Add generic clock manipulation rountines for runtime PM Rafael J. Wysocki
2011-04-19 21:59           ` Paul Mundt
2011-04-19 22:10             ` Rafael J. Wysocki
2011-04-19 22:20               ` Paul Mundt
2011-04-19 22:50                 ` Rafael J. Wysocki
2011-04-19 10:58     ` [linux-pm] [PATCH 7/9] PM / Runtime: Add generic clock Mark Brown
2011-04-19 21:35       ` [linux-pm] [PATCH 7/9] PM / Runtime: Add generic clock manipulation rountines for runtime PM Rafael J. Wysocki
2011-04-20 11:57         ` [linux-pm] [PATCH 7/9] PM / Runtime: Add generic clock Mark Brown
2011-04-16 23:43   ` [PATCH 8/9] OMAP1 / PM: Use generic clock manipulation routines for runtime PM Rafael J. Wysocki
2011-04-18  8:18     ` Paul Mundt
2011-04-18 19:57       ` Rafael J. Wysocki
2011-04-16 23:44   ` [PATCH 9/9] PM: Revert "driver core: platform_bus: allow runtime override of dev_pm_ops" Rafael J. Wysocki
2011-04-24 21:30   ` [PATCH 0/9] PM: Rework shmobile and OMAP runtime PM using power domains (v2) Rafael J. Wysocki
2011-04-24 21:36     ` [PATCH 1/9] PM: Make power domain callbacks take precedence over subsystem ones Rafael J. Wysocki
2011-04-24 21:37     ` [PATCH 2/9] PM: Export platform bus type's default PM callbacks Rafael J. Wysocki
2011-04-24 21:38     ` [PATCH 3/9] shmobile: Use power domains for platform runtime PM Rafael J. Wysocki
2011-04-24 21:39     ` [PATCH 4/9] PM / Platform: Use generic runtime PM callbacks directly Rafael J. Wysocki
2011-04-24 21:41     ` [PATCH 5/9] OMAP2+ / PM: move runtime PM implementation to use device power domains Rafael J. Wysocki
2011-04-24 21:42     ` [PATCH 6/9] PM / Runtime: Add subsystem data field to struct dev_pm_info Rafael J. Wysocki
2011-04-24 21:42     ` [PATCH 7/9] PM / Runtime: Generic clock manipulation rountines for runtime PM (v2) Rafael J. Wysocki
2011-04-27 21:48       ` [Update][PATCH 7/9] PM / Runtime: Generic clock manipulation rountines for runtime PM (v3) Rafael J. Wysocki
2011-04-27 23:04         ` [Update][PATCH 7/9] PM / Runtime: Generic clock manipulation Colin Cross
2011-04-28  0:58           ` [Update][PATCH 7/9] PM / Runtime: Generic clock manipulation rountines for runtime PM (v3) Rafael J. Wysocki
2011-04-28  1:06             ` Rafael J. Wysocki
2011-04-28  1:33               ` Rafael J. Wysocki
2011-04-28 19:36                 ` [Update x2][PATCH 7/9] PM / Runtime: Generic clock manipulation rountines for runtime PM (v5) Rafael J. Wysocki
2011-04-29 19:35                   ` [Update x2][PATCH 7/9] PM / Runtime: Generic clock manipulation Stephen Boyd
2011-04-29 20:29                     ` [Update x2][PATCH 7/9] PM / Runtime: Generic clock manipulation rountines for runtime PM (v5) Rafael J. Wysocki
2011-04-29 22:04                       ` [Update x3][PATCH 7/9] PM / Runtime: Generic clock manipulation rountines for runtime PM (v6) Rafael J. Wysocki
2011-05-03 17:00                         ` [Update x3][PATCH 7/9] PM / Runtime: Generic clock manipulation Stephen Boyd
2011-05-03 17:38                           ` [Update x3][PATCH 7/9] PM / Runtime: Generic clock manipulation rountines for runtime PM (v6) Rafael J. Wysocki
2011-04-29 20:50             ` [Update][PATCH 7/9] PM / Runtime: Generic clock manipulation Grant Likely
2011-04-29 21:07               ` [Update][PATCH 7/9] PM / Runtime: Generic clock manipulation rountines for runtime PM (v3) Rafael J. Wysocki
2011-04-24 21:43     ` [PATCH 8/9] OMAP1 / PM: Use generic clock manipulation routines for runtime PM Rafael J. Wysocki
2011-05-16 10:16       ` Kevin Hilman
2011-05-16 18:26         ` Rafael J. Wysocki
2011-04-24 21:44     ` [PATCH 9/9] PM: Revert "driver core: platform_bus: allow runtime override of dev_pm_ops" Rafael J. Wysocki
2011-04-24 23:36     ` [PATCH 0/9] PM: Rework shmobile and OMAP runtime PM using power Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).