From: "Rafael J. Wysocki" <rjw@sisk.pl>
To: Namhyung Kim <namhyung@gmail.com>
Cc: linux-kernel@vger.kernel.org,
Linux PM list <linux-pm@vger.kernel.org>,
"Greg Kroah-Hartman" <gregkh@suse.de>,
Russell King <linux@arm.linux.org.uk>,
Alan Stern <stern@rowland.harvard.edu>
Subject: Re: [PATCH 1/4] PM / Sleep: Make pm_op() and pm_noirq_op() return callback pointers
Date: Tue, 13 Dec 2011 00:53:37 +0100 [thread overview]
Message-ID: <201112130053.37714.rjw@sisk.pl> (raw)
In-Reply-To: <loom.20111212T041314-709@post.gmane.org>
On Monday, December 12, 2011, Namhyung Kim wrote:
> Rafael J. Wysocki <rjw <at> sisk.pl> writes:
>
> >
> > From: Rafael J. Wysocki <rjw <at> sisk.pl>
> >
> > Make the pm_op() and pm_noirq_op() functions return pointers to
> > appropriate callbacks instead of executing those callbacks and
> > returning their results.
> >
> > This change is required for a subsequent modification that will
> > execute the corresponding driver callback if the subsystem
> > callback returned by either pm_op(), or pm_noirq_op() is NULL.
> >
>
> Hello Rafael,
>
> How about typedef'ing something like pm_callback_t for readability?
>
> typedef int (*pm_callback_t)(struct device *);
>
> This way, the code will be easier to read.
Do you mean something like in the patch below? It does look a bit simpler.
Thanks,
Rafael
---
From: Rafael J. Wysocki <rjw@sisk.pl>
Subject: PM / Sleep: Make pm_op() and pm_noirq_op() return callback pointers
Make the pm_op() and pm_noirq_op() functions return pointers to
appropriate callbacks instead of executing those callbacks and
returning their results.
This change is required for a subsequent modification that will
execute the corresponding driver callback if the subsystem
callback returned by either pm_op(), or pm_noirq_op() is NULL.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
drivers/base/power/main.c | 197 ++++++++++++++++++++++------------------------
1 file changed, 95 insertions(+), 102 deletions(-)
Index: linux/drivers/base/power/main.c
===================================================================
--- linux.orig/drivers/base/power/main.c
+++ linux/drivers/base/power/main.c
@@ -32,6 +32,8 @@
#include "../base.h"
#include "power.h"
+typedef int (*pm_callback_t)(struct device *);
+
/*
* The entries in the dpm_list list are in a depth first order, simply
* because children are guaranteed to be discovered after parents, and
@@ -211,113 +213,70 @@ static void dpm_wait_for_children(struct
device_for_each_child(dev, &async, dpm_wait_fn);
}
-static int dpm_run_callback(struct device *dev, int (*cb)(struct device *))
-{
- ktime_t calltime;
- int error;
-
- if (!cb)
- return 0;
-
- calltime = initcall_debug_start(dev);
-
- error = cb(dev);
- suspend_report_result(cb, error);
-
- initcall_debug_report(dev, calltime, error);
-
- return error;
-}
-
/**
- * pm_op - Execute the PM operation appropriate for given PM event.
- * @dev: Device to handle.
+ * pm_op - Return the PM operation appropriate for given PM event.
* @ops: PM operations to choose from.
* @state: PM transition of the system being carried out.
*/
-static int pm_op(struct device *dev,
- const struct dev_pm_ops *ops,
- pm_message_t state)
+static pm_callback_t pm_op(const struct dev_pm_ops *ops, pm_message_t state)
{
- int error = 0;
-
switch (state.event) {
#ifdef CONFIG_SUSPEND
case PM_EVENT_SUSPEND:
- error = dpm_run_callback(dev, ops->suspend);
- break;
+ return ops->suspend;
case PM_EVENT_RESUME:
- error = dpm_run_callback(dev, ops->resume);
- break;
+ return ops->resume;
#endif /* CONFIG_SUSPEND */
#ifdef CONFIG_HIBERNATE_CALLBACKS
case PM_EVENT_FREEZE:
case PM_EVENT_QUIESCE:
- error = dpm_run_callback(dev, ops->freeze);
- break;
+ return ops->freeze;
case PM_EVENT_HIBERNATE:
- error = dpm_run_callback(dev, ops->poweroff);
- break;
+ return ops->poweroff;
case PM_EVENT_THAW:
case PM_EVENT_RECOVER:
- error = dpm_run_callback(dev, ops->thaw);
+ return ops->thaw;
break;
case PM_EVENT_RESTORE:
- error = dpm_run_callback(dev, ops->restore);
- break;
+ return ops->restore;
#endif /* CONFIG_HIBERNATE_CALLBACKS */
- default:
- error = -EINVAL;
}
- return error;
+ return NULL;
}
/**
- * pm_noirq_op - Execute the PM operation appropriate for given PM event.
- * @dev: Device to handle.
+ * pm_noirq_op - Return the PM operation appropriate for given PM event.
* @ops: PM operations to choose from.
* @state: PM transition of the system being carried out.
*
* The driver of @dev will not receive interrupts while this function is being
* executed.
*/
-static int pm_noirq_op(struct device *dev,
- const struct dev_pm_ops *ops,
- pm_message_t state)
+static pm_callback_t pm_noirq_op(const struct dev_pm_ops *ops, pm_message_t state)
{
- int error = 0;
-
switch (state.event) {
#ifdef CONFIG_SUSPEND
case PM_EVENT_SUSPEND:
- error = dpm_run_callback(dev, ops->suspend_noirq);
- break;
+ return ops->suspend_noirq;
case PM_EVENT_RESUME:
- error = dpm_run_callback(dev, ops->resume_noirq);
- break;
+ return ops->resume_noirq;
#endif /* CONFIG_SUSPEND */
#ifdef CONFIG_HIBERNATE_CALLBACKS
case PM_EVENT_FREEZE:
case PM_EVENT_QUIESCE:
- error = dpm_run_callback(dev, ops->freeze_noirq);
- break;
+ return ops->freeze_noirq;
case PM_EVENT_HIBERNATE:
- error = dpm_run_callback(dev, ops->poweroff_noirq);
- break;
+ return ops->poweroff_noirq;
case PM_EVENT_THAW:
case PM_EVENT_RECOVER:
- error = dpm_run_callback(dev, ops->thaw_noirq);
- break;
+ return ops->thaw_noirq;
case PM_EVENT_RESTORE:
- error = dpm_run_callback(dev, ops->restore_noirq);
- break;
+ return ops->restore_noirq;
#endif /* CONFIG_HIBERNATE_CALLBACKS */
- default:
- error = -EINVAL;
}
- return error;
+ return NULL;
}
static char *pm_verb(int event)
@@ -375,6 +334,26 @@ static void dpm_show_time(ktime_t startt
usecs / USEC_PER_MSEC, usecs % USEC_PER_MSEC);
}
+static int dpm_run_callback(pm_callback_t cb, struct device *dev,
+ pm_message_t state, char *info)
+{
+ ktime_t calltime;
+ int error;
+
+ if (!cb)
+ return 0;
+
+ calltime = initcall_debug_start(dev);
+
+ pm_dev_dbg(dev, state, info);
+ error = cb(dev);
+ suspend_report_result(cb, error);
+
+ initcall_debug_report(dev, calltime, error);
+
+ return error;
+}
+
/*------------------------- Resume routines -------------------------*/
/**
@@ -387,25 +366,29 @@ static void dpm_show_time(ktime_t startt
*/
static int device_resume_noirq(struct device *dev, pm_message_t state)
{
+ pm_callback_t callback = NULL;
+ char *info = NULL;
int error = 0;
TRACE_DEVICE(dev);
TRACE_RESUME(0);
if (dev->pm_domain) {
- pm_dev_dbg(dev, state, "EARLY power domain ");
- error = pm_noirq_op(dev, &dev->pm_domain->ops, state);
+ info = "EARLY power domain ";
+ callback = pm_noirq_op(&dev->pm_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);
+ info = "EARLY type ";
+ callback = pm_noirq_op(dev->type->pm, state);
} else if (dev->class && dev->class->pm) {
- pm_dev_dbg(dev, state, "EARLY class ");
- error = pm_noirq_op(dev, dev->class->pm, state);
+ info = "EARLY class ";
+ callback = pm_noirq_op(dev->class->pm, state);
} else if (dev->bus && dev->bus->pm) {
- pm_dev_dbg(dev, state, "EARLY ");
- error = pm_noirq_op(dev, dev->bus->pm, state);
+ info = "EARLY ";
+ callback = pm_noirq_op(dev->bus->pm, state);
}
+ error = dpm_run_callback(callback, dev, state, info);
+
TRACE_RESUME(error);
return error;
}
@@ -455,6 +438,8 @@ EXPORT_SYMBOL_GPL(dpm_resume_noirq);
*/
static int device_resume(struct device *dev, pm_message_t state, bool async)
{
+ pm_callback_t callback = NULL;
+ char *info = NULL;
int error = 0;
bool put = false;
@@ -477,40 +462,41 @@ static int device_resume(struct device *
put = true;
if (dev->pm_domain) {
- pm_dev_dbg(dev, state, "power domain ");
- error = pm_op(dev, &dev->pm_domain->ops, state);
+ info = "power domain ";
+ callback = pm_op(&dev->pm_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);
+ info = "type ";
+ callback = pm_op(dev->type->pm, state);
goto End;
}
if (dev->class) {
if (dev->class->pm) {
- pm_dev_dbg(dev, state, "class ");
- error = pm_op(dev, dev->class->pm, state);
+ info = "class ";
+ callback = pm_op(dev->class->pm, state);
goto End;
} else if (dev->class->resume) {
- pm_dev_dbg(dev, state, "legacy class ");
- error = dpm_run_callback(dev, dev->class->resume);
+ info = "legacy class ";
+ callback = dev->class->resume;
goto End;
}
}
if (dev->bus) {
if (dev->bus->pm) {
- pm_dev_dbg(dev, state, "");
- error = pm_op(dev, dev->bus->pm, state);
+ info = "";
+ callback = pm_op(dev->bus->pm, state);
} else if (dev->bus->resume) {
- pm_dev_dbg(dev, state, "legacy ");
- error = dpm_run_callback(dev, dev->bus->resume);
+ info = "legacy ";
+ callback = dev->bus->resume;
}
}
End:
+ error = dpm_run_callback(callback, dev, state, info);
dev->power.is_suspended = false;
Unlock:
@@ -705,23 +691,24 @@ static pm_message_t resume_event(pm_mess
*/
static int device_suspend_noirq(struct device *dev, pm_message_t state)
{
- int error = 0;
+ pm_callback_t callback = NULL;
+ char *info = NULL;
if (dev->pm_domain) {
- pm_dev_dbg(dev, state, "LATE power domain ");
- error = pm_noirq_op(dev, &dev->pm_domain->ops, state);
+ info = "LATE power domain ";
+ callback = pm_noirq_op(&dev->pm_domain->ops, state);
} else if (dev->type && dev->type->pm) {
- pm_dev_dbg(dev, state, "LATE type ");
- error = pm_noirq_op(dev, dev->type->pm, state);
+ info = "LATE type ";
+ callback = pm_noirq_op(dev->type->pm, state);
} else if (dev->class && dev->class->pm) {
- pm_dev_dbg(dev, state, "LATE class ");
- error = pm_noirq_op(dev, dev->class->pm, state);
+ info = "LATE class ";
+ callback = pm_noirq_op(dev->class->pm, state);
} else if (dev->bus && dev->bus->pm) {
- pm_dev_dbg(dev, state, "LATE ");
- error = pm_noirq_op(dev, dev->bus->pm, state);
+ info = "LATE ";
+ callback = pm_noirq_op(dev->bus->pm, state);
}
- return error;
+ return dpm_run_callback(callback, dev, state, info);
}
/**
@@ -798,6 +785,8 @@ static int legacy_suspend(struct device
*/
static int __device_suspend(struct device *dev, pm_message_t state, bool async)
{
+ pm_callback_t callback = NULL;
+ char *info = NULL;
int error = 0;
dpm_wait_for_children(dev, async);
@@ -818,22 +807,22 @@ static int __device_suspend(struct devic
device_lock(dev);
if (dev->pm_domain) {
- pm_dev_dbg(dev, state, "power domain ");
- error = pm_op(dev, &dev->pm_domain->ops, state);
- goto End;
+ info = "power domain ";
+ callback = pm_op(&dev->pm_domain->ops, state);
+ goto Run;
}
if (dev->type && dev->type->pm) {
- pm_dev_dbg(dev, state, "type ");
- error = pm_op(dev, dev->type->pm, state);
- goto End;
+ info = "type ";
+ callback = pm_op(dev->type->pm, state);
+ goto Run;
}
if (dev->class) {
if (dev->class->pm) {
- pm_dev_dbg(dev, state, "class ");
- error = pm_op(dev, dev->class->pm, state);
- goto End;
+ info = "class ";
+ callback = pm_op(dev->class->pm, state);
+ goto Run;
} else if (dev->class->suspend) {
pm_dev_dbg(dev, state, "legacy class ");
error = legacy_suspend(dev, state, dev->class->suspend);
@@ -843,14 +832,18 @@ static int __device_suspend(struct devic
if (dev->bus) {
if (dev->bus->pm) {
- pm_dev_dbg(dev, state, "");
- error = pm_op(dev, dev->bus->pm, state);
+ info = "";
+ callback = pm_op(dev->bus->pm, state);
} else if (dev->bus->suspend) {
pm_dev_dbg(dev, state, "legacy ");
error = legacy_suspend(dev, state, dev->bus->suspend);
+ goto End;
}
}
+ Run:
+ error = dpm_run_callback(callback, dev, state, info);
+
End:
if (!error) {
dev->power.is_suspended = true;
next prev parent reply other threads:[~2011-12-12 23:50 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-12-09 23:18 [PATCH 0/4] PM: Make the PM core execute driver callbacks if subsystem ones are not present Rafael J. Wysocki
2011-12-09 23:20 ` [PATCH 1/4] PM / Sleep: Make pm_op() and pm_noirq_op() return callback pointers Rafael J. Wysocki
2011-12-12 4:04 ` Namhyung Kim
2011-12-12 23:53 ` Rafael J. Wysocki [this message]
2011-12-13 13:55 ` Namhyung Kim
2011-12-09 23:20 ` [PATCH 2/4] PM: Run the driver callback directly if the subsystem one is not there Rafael J. Wysocki
2011-12-10 14:59 ` Alan Stern
2011-12-10 18:21 ` Rafael J. Wysocki
2011-12-09 23:21 ` [PATCH 3/4] PM / Sleep: Remove forward-only callbacks from platform bus type Rafael J. Wysocki
2011-12-09 23:23 ` [PATCH 4/4] PM / Sleep: Remove forward-only callbacks from AMBA " Rafael J. Wysocki
2011-12-09 23:47 ` [PATCH 0/4] PM: Make the PM core execute driver callbacks if subsystem ones are not present Greg KH
2011-12-09 23:52 ` Rafael J. Wysocki
2011-12-15 22:34 ` [Update][PATCH 0/5] " Rafael J. Wysocki
2011-12-15 22:35 ` [Update][PATCH 1/5] PM / Sleep: Make pm_op() and pm_noirq_op() return callback pointers Rafael J. Wysocki
2011-12-15 22:36 ` [Update][PATCH 2/5] PM: Run the driver callback directly if the subsystem one is not there Rafael J. Wysocki
2011-12-15 22:37 ` [Update][PATCH 3/5] PM / Sleep: Remove forward-only callbacks from platform bus type Rafael J. Wysocki
2011-12-15 22:38 ` [Update][PATCH 4/5] PM / Sleep: Remove forward-only callbacks from AMBA " Rafael J. Wysocki
2011-12-15 22:39 ` [Update][PATCH 5/5] PM: Drop generic_subsys_pm_ops Rafael J. Wysocki
2011-12-15 22:47 ` Rafael J. Wysocki
2011-12-15 23:08 ` [Update][PATCH 0/5] PM: Make the PM core execute driver callbacks if subsystem ones are not present Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=201112130053.37714.rjw@sisk.pl \
--to=rjw@sisk.pl \
--cc=gregkh@suse.de \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=linux@arm.linux.org.uk \
--cc=namhyung@gmail.com \
--cc=stern@rowland.harvard.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.