LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH 0/3] PM core fixes
@ 2008-03-11 23:55 Rafael J. Wysocki
2008-03-11 23:57 ` [PATCH 1/3] PM: Handle device registrations during suspend/resume Rafael J. Wysocki
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Rafael J. Wysocki @ 2008-03-11 23:55 UTC (permalink / raw)
To: Greg KH
Cc: Alan Stern, Andrew Morton, David Brownell, LKML, Pavel Machek, pm list
Hi Greg,
The following series of patches contains some fixes of the PM core related to
the suspending and resuming of devices. All of the details are (hopefully)
described in the patches' changelogs.
These patches are targeted at 2.6.26, but we (the authors) would like them to
get as much linux-next and -mm testing as possible, so please add them to your
queue.
Thanks,
Rafael
--
"Premature optimization is the root of all evil." - Donald Knuth
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/3] PM: Handle device registrations during suspend/resume
2008-03-11 23:55 [PATCH 0/3] PM core fixes Rafael J. Wysocki
@ 2008-03-11 23:57 ` Rafael J. Wysocki
2008-03-13 8:37 ` Pavel Machek
2008-03-13 20:54 ` patch pm-handle-device-registrations-during-suspend-resume.patch added to gregkh-2.6 tree gregkh
2008-03-11 23:59 ` [PATCH 2/3] Driver core: Call device_pm_add() after bus_add_device() in device_add() Rafael J. Wysocki
2008-03-12 0:01 ` [PATCH 3/3] PM: make wakeup flags available whenever CONFIG_PM is set Rafael J. Wysocki
2 siblings, 2 replies; 11+ messages in thread
From: Rafael J. Wysocki @ 2008-03-11 23:57 UTC (permalink / raw)
To: Greg KH
Cc: Alan Stern, Andrew Morton, David Brownell, LKML, Pavel Machek, pm list
From: Rafael J. Wysocki <rjw@sisk.pl>
Modify the PM core to protect its data structures, specifically the
dpm_active list, from being corrupted if a child of the currently
suspending device is registered concurrently with its ->suspend()
callback. In that case, since the new device (the child) is added
to dpm_active after its parent, the PM core will attempt to
suspend it after the parent, which is wrong.
Introduce a new member of struct dev_pm_info, called 'sleeping',
and use it to check if the parent of the device being added to
dpm_active has been suspended, in which case the device registration
fails. Also, use 'sleeping' for checking if the ordering of devices
on dpm_active is correct.
Introduce variable 'all_sleeping' that will be set to 'true' once all
devices have been suspended and make new device registrations fail
until 'all_sleeping' is reset to 'false', in order to avoid having
unsuspended devices around while the system is going into a sleep state.
Remove pm_sleep_rwsem which is not necessary any more.
Special thanks to Alan Stern for discussions and suggestions that
lead to the creation of this patch.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
Documentation/power/devices.txt | 5 +++
drivers/base/core.c | 6 +++-
drivers/base/power/main.c | 57 ++++++++++++++++++----------------------
drivers/base/power/power.h | 23 ++--------------
include/linux/pm.h | 1
5 files changed, 40 insertions(+), 52 deletions(-)
Index: linux-2.6/include/linux/pm.h
===================================================================
--- linux-2.6.orig/include/linux/pm.h
+++ linux-2.6/include/linux/pm.h
@@ -183,6 +183,7 @@ typedef struct pm_message {
struct dev_pm_info {
pm_message_t power_state;
unsigned can_wakeup:1;
+ bool sleeping:1; /* Owned by the PM core */
#ifdef CONFIG_PM_SLEEP
unsigned should_wakeup:1;
struct list_head entry;
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
@@ -54,7 +54,8 @@ static LIST_HEAD(dpm_destroy);
static DEFINE_MUTEX(dpm_list_mtx);
-static DECLARE_RWSEM(pm_sleep_rwsem);
+/* 'true' if all devices have been suspended, protected by dpm_list_mtx */
+static bool all_sleeping;
int (*platform_enable_wakeup)(struct device *dev, int is_on);
@@ -62,14 +63,28 @@ int (*platform_enable_wakeup)(struct dev
* device_pm_add - add a device to the list of active devices
* @dev: Device to be added to the list
*/
-void device_pm_add(struct device *dev)
+int device_pm_add(struct device *dev)
{
+ int error = 0;
+
pr_debug("PM: Adding info for %s:%s\n",
dev->bus ? dev->bus->name : "No Bus",
kobject_name(&dev->kobj));
mutex_lock(&dpm_list_mtx);
- list_add_tail(&dev->power.entry, &dpm_active);
+ if ((dev->parent && dev->parent->power.sleeping) || all_sleeping) {
+ if (dev->parent->power.sleeping)
+ dev_warn(dev,
+ "parent %s is sleeping, will not add\n",
+ dev->parent->bus_id);
+ else
+ dev_warn(dev, "devices are sleeping, will not add\n");
+ WARN_ON(true);
+ error = -EBUSY;
+ } else {
+ list_add_tail(&dev->power.entry, &dpm_active);
+ }
mutex_unlock(&dpm_list_mtx);
+ return error;
}
/**
@@ -107,32 +122,6 @@ void device_pm_schedule_removal(struct d
}
EXPORT_SYMBOL_GPL(device_pm_schedule_removal);
-/**
- * pm_sleep_lock - mutual exclusion for registration and suspend
- *
- * Returns 0 if no suspend is underway and device registration
- * may proceed, otherwise -EBUSY.
- */
-int pm_sleep_lock(void)
-{
- if (down_read_trylock(&pm_sleep_rwsem))
- return 0;
-
- return -EBUSY;
-}
-
-/**
- * pm_sleep_unlock - mutual exclusion for registration and suspend
- *
- * This routine undoes the effect of device_pm_add_lock
- * when a device's registration is complete.
- */
-void pm_sleep_unlock(void)
-{
- up_read(&pm_sleep_rwsem);
-}
-
-
/*------------------------- Resume routines -------------------------*/
/**
@@ -242,11 +231,13 @@ static int resume_device(struct device *
static void dpm_resume(void)
{
mutex_lock(&dpm_list_mtx);
+ all_sleeping = false;
while(!list_empty(&dpm_off)) {
struct list_head *entry = dpm_off.next;
struct device *dev = to_device(entry);
list_move_tail(entry, &dpm_active);
+ dev->power.sleeping = false;
mutex_unlock(&dpm_list_mtx);
resume_device(dev);
mutex_lock(&dpm_list_mtx);
@@ -285,7 +276,6 @@ void device_resume(void)
might_sleep();
dpm_resume();
unregister_dropped_devices();
- up_write(&pm_sleep_rwsem);
}
EXPORT_SYMBOL_GPL(device_resume);
@@ -426,6 +416,9 @@ static int dpm_suspend(pm_message_t stat
struct list_head *entry = dpm_active.prev;
struct device *dev = to_device(entry);
+ WARN_ON(dev->parent && dev->parent->power.sleeping);
+
+ dev->power.sleeping = true;
mutex_unlock(&dpm_list_mtx);
error = suspend_device(dev, state);
mutex_lock(&dpm_list_mtx);
@@ -437,11 +430,14 @@ static int dpm_suspend(pm_message_t stat
(error == -EAGAIN ?
" (please convert to suspend_late)" :
""));
+ dev->power.sleeping = false;
break;
}
if (!list_empty(&dev->power.entry))
list_move(&dev->power.entry, &dpm_off);
}
+ if (!error)
+ all_sleeping = true;
mutex_unlock(&dpm_list_mtx);
return error;
@@ -459,7 +455,6 @@ int device_suspend(pm_message_t state)
int error;
might_sleep();
- down_write(&pm_sleep_rwsem);
error = dpm_suspend(state);
if (error)
device_resume();
Index: linux-2.6/drivers/base/power/power.h
===================================================================
--- linux-2.6.orig/drivers/base/power/power.h
+++ linux-2.6/drivers/base/power/power.h
@@ -11,30 +11,13 @@ static inline struct device *to_device(s
return container_of(entry, struct device, power.entry);
}
-extern void device_pm_add(struct device *);
+extern int device_pm_add(struct device *);
extern void device_pm_remove(struct device *);
-extern int pm_sleep_lock(void);
-extern void pm_sleep_unlock(void);
#else /* CONFIG_PM_SLEEP */
-
-static inline void device_pm_add(struct device *dev)
-{
-}
-
-static inline void device_pm_remove(struct device *dev)
-{
-}
-
-static inline int pm_sleep_lock(void)
-{
- return 0;
-}
-
-static inline void pm_sleep_unlock(void)
-{
-}
+static inline int device_pm_add(struct device *dev) { return 0; }
+static inline void device_pm_remove(struct device *dev) {}
#endif
Index: linux-2.6/drivers/base/core.c
===================================================================
--- linux-2.6.orig/drivers/base/core.c
+++ linux-2.6/drivers/base/core.c
@@ -815,7 +815,11 @@ int device_add(struct device *dev)
error = dpm_sysfs_add(dev);
if (error)
goto PMError;
- device_pm_add(dev);
+ error = device_pm_add(dev);
+ if (error) {
+ dpm_sysfs_remove(dev);
+ goto PMError;
+ }
error = bus_add_device(dev);
if (error)
goto BusError;
Index: linux-2.6/Documentation/power/devices.txt
===================================================================
--- linux-2.6.orig/Documentation/power/devices.txt
+++ linux-2.6/Documentation/power/devices.txt
@@ -196,6 +196,11 @@ its parent; and can't be removed or susp
The policy is that the device tree should match hardware bus topology.
(Or at least the control bus, for devices which use multiple busses.)
+In particular, this means that a device registration may fail if the parent of
+the device is suspending (ie. has been chosen by the PM core as the next
+device to suspend) or has already suspended, as well as after all of the other
+devices have been suspended. Device drivers must be prepared to cope with such
+situations.
Suspending Devices
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 2/3] Driver core: Call device_pm_add() after bus_add_device() in device_add()
2008-03-11 23:55 [PATCH 0/3] PM core fixes Rafael J. Wysocki
2008-03-11 23:57 ` [PATCH 1/3] PM: Handle device registrations during suspend/resume Rafael J. Wysocki
@ 2008-03-11 23:59 ` Rafael J. Wysocki
2008-03-13 9:30 ` Pavel Machek
2008-03-13 20:54 ` patch driver-core-call-device_pm_add-after-bus_add_device-in-device_add.patch added to gregkh-2.6 tree gregkh
2008-03-12 0:01 ` [PATCH 3/3] PM: make wakeup flags available whenever CONFIG_PM is set Rafael J. Wysocki
2 siblings, 2 replies; 11+ messages in thread
From: Rafael J. Wysocki @ 2008-03-11 23:59 UTC (permalink / raw)
To: Greg KH
Cc: Alan Stern, Andrew Morton, David Brownell, LKML, Pavel Machek, pm list
From: Rafael J. Wysocki <rjw@sisk.pl>
Include dpm_sysfs_add() into device_pm_add(), in analogy with
device_pm_remove(), and modify device_add() to call the latter after
bus_add_device(), to avoid situations in which the PM core may
attempt to suspend a device the registration of which has not been
successful.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
drivers/base/core.c | 15 +++++----------
drivers/base/power/main.c | 4 +++-
2 files changed, 8 insertions(+), 11 deletions(-)
Index: linux-2.6/drivers/base/core.c
===================================================================
--- linux-2.6.orig/drivers/base/core.c
+++ linux-2.6/drivers/base/core.c
@@ -812,17 +812,12 @@ int device_add(struct device *dev)
error = device_add_attrs(dev);
if (error)
goto AttrsError;
- error = dpm_sysfs_add(dev);
- if (error)
- goto PMError;
- error = device_pm_add(dev);
- if (error) {
- dpm_sysfs_remove(dev);
- goto PMError;
- }
error = bus_add_device(dev);
if (error)
goto BusError;
+ error = device_pm_add(dev);
+ if (error)
+ goto PMError;
kobject_uevent(&dev->kobj, KOBJ_ADD);
bus_attach_device(dev);
if (parent)
@@ -842,9 +837,9 @@ int device_add(struct device *dev)
Done:
put_device(dev);
return error;
- BusError:
- device_pm_remove(dev);
PMError:
+ bus_remove_device(dev);
+ BusError:
if (dev->bus)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
BUS_NOTIFY_DEL_DEVICE, dev);
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
@@ -81,7 +81,9 @@ int device_pm_add(struct device *dev)
WARN_ON(true);
error = -EBUSY;
} else {
- list_add_tail(&dev->power.entry, &dpm_active);
+ error = dpm_sysfs_add(dev);
+ if (!error)
+ list_add_tail(&dev->power.entry, &dpm_active);
}
mutex_unlock(&dpm_list_mtx);
return error;
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 3/3] PM: make wakeup flags available whenever CONFIG_PM is set
2008-03-11 23:55 [PATCH 0/3] PM core fixes Rafael J. Wysocki
2008-03-11 23:57 ` [PATCH 1/3] PM: Handle device registrations during suspend/resume Rafael J. Wysocki
2008-03-11 23:59 ` [PATCH 2/3] Driver core: Call device_pm_add() after bus_add_device() in device_add() Rafael J. Wysocki
@ 2008-03-12 0:01 ` Rafael J. Wysocki
2008-03-13 9:31 ` Pavel Machek
2008-03-13 20:54 ` patch pm-make-wakeup-flags-available-whenever-config_pm-is-set.patch added to gregkh-2.6 tree gregkh
2 siblings, 2 replies; 11+ messages in thread
From: Rafael J. Wysocki @ 2008-03-12 0:01 UTC (permalink / raw)
To: Greg KH
Cc: Alan Stern, Andrew Morton, David Brownell, LKML, Pavel Machek, pm list
From: Alan Stern <stern@rowland.harvard.edu>
The various wakeup flags and their accessor macros in struct
dev_pm_info should be available whenever CONFIG_PM is enabled, not
just when CONFIG_PM_SLEEP is on. Otherwise remote wakeup won't always
be configurable for runtime power management. This patch (as1056)
fixes the oversight.
[rjw: rebased the patch on top of the previous two.]
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
CC: David Brownell <david-b@pacbell.net>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
drivers/base/power/main.c | 2 -
drivers/base/power/sysfs.c | 2 +
include/linux/pm.h | 64 +++++++++++++++++++++++++--------------------
3 files changed, 38 insertions(+), 30 deletions(-)
Index: linux-2.6/include/linux/pm.h
===================================================================
--- linux-2.6.orig/include/linux/pm.h
+++ linux-2.6/include/linux/pm.h
@@ -183,9 +183,9 @@ typedef struct pm_message {
struct dev_pm_info {
pm_message_t power_state;
unsigned can_wakeup:1;
+ unsigned should_wakeup:1;
bool sleeping:1; /* Owned by the PM core */
#ifdef CONFIG_PM_SLEEP
- unsigned should_wakeup:1;
struct list_head entry;
#endif
};
@@ -198,11 +198,6 @@ extern void device_resume(void);
extern int device_suspend(pm_message_t state);
extern int device_prepare_suspend(pm_message_t state);
-#define device_set_wakeup_enable(dev,val) \
- ((dev)->power.should_wakeup = !!(val))
-#define device_may_wakeup(dev) \
- (device_can_wakeup(dev) && (dev)->power.should_wakeup)
-
extern void __suspend_report_result(const char *function, void *fn, int ret);
#define suspend_report_result(fn, ret) \
@@ -210,6 +205,35 @@ extern void __suspend_report_result(cons
__suspend_report_result(__FUNCTION__, fn, ret); \
} while (0)
+#else /* !CONFIG_PM_SLEEP */
+
+static inline int device_suspend(pm_message_t state)
+{
+ return 0;
+}
+
+#define suspend_report_result(fn, ret) do {} while (0)
+
+#endif /* !CONFIG_PM_SLEEP */
+
+#ifdef CONFIG_PM
+
+/* changes to device_may_wakeup take effect on the next pm state change.
+ * by default, devices should wakeup if they can.
+ */
+#define device_can_wakeup(dev) \
+ ((dev)->power.can_wakeup)
+#define device_init_wakeup(dev,val) \
+ do { \
+ device_can_wakeup(dev) = !!(val); \
+ device_set_wakeup_enable(dev,val); \
+ } while(0)
+
+#define device_set_wakeup_enable(dev,val) \
+ ((dev)->power.should_wakeup = !!(val))
+#define device_may_wakeup(dev) \
+ (device_can_wakeup(dev) && (dev)->power.should_wakeup)
+
/*
* Platform hook to activate device wakeup capability, if that's not already
* handled by enable_irq_wake() etc.
@@ -224,35 +248,19 @@ static inline int call_platform_enable_w
return 0;
}
-#else /* !CONFIG_PM_SLEEP */
-
-static inline int device_suspend(pm_message_t state)
-{
- return 0;
-}
-
-#define device_set_wakeup_enable(dev,val) do{}while(0)
-#define device_may_wakeup(dev) (0)
+#else /* !CONFIG_PM */
-#define suspend_report_result(fn, ret) do { } while (0)
+#define device_can_wakeup(dev) 0
+#define device_init_wakeup(dev,val) do {} while (0)
+#define device_set_wakeup_enable(dev,val) do {} while (0)
+#define device_may_wakeup(dev) 0
static inline int call_platform_enable_wakeup(struct device *dev, int is_on)
{
return 0;
}
-#endif /* !CONFIG_PM_SLEEP */
-
-/* changes to device_may_wakeup take effect on the next pm state change.
- * by default, devices should wakeup if they can.
- */
-#define device_can_wakeup(dev) \
- ((dev)->power.can_wakeup)
-#define device_init_wakeup(dev,val) \
- do { \
- device_can_wakeup(dev) = !!(val); \
- device_set_wakeup_enable(dev,val); \
- } while(0)
+#endif /* !CONFIG_PM */
/*
* Global Power Management flags
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
@@ -57,8 +57,6 @@ static DEFINE_MUTEX(dpm_list_mtx);
/* 'true' if all devices have been suspended, protected by dpm_list_mtx */
static bool all_sleeping;
-int (*platform_enable_wakeup)(struct device *dev, int is_on);
-
/**
* device_pm_add - add a device to the list of active devices
* @dev: Device to be added to the list
Index: linux-2.6/drivers/base/power/sysfs.c
===================================================================
--- linux-2.6.orig/drivers/base/power/sysfs.c
+++ linux-2.6/drivers/base/power/sysfs.c
@@ -6,6 +6,8 @@
#include <linux/string.h>
#include "power.h"
+int (*platform_enable_wakeup)(struct device *dev, int is_on);
+
/*
* wakeup - Report/change current wakeup option for device
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/3] PM: Handle device registrations during suspend/resume
2008-03-11 23:57 ` [PATCH 1/3] PM: Handle device registrations during suspend/resume Rafael J. Wysocki
@ 2008-03-13 8:37 ` Pavel Machek
2008-03-13 20:54 ` patch pm-handle-device-registrations-during-suspend-resume.patch added to gregkh-2.6 tree gregkh
1 sibling, 0 replies; 11+ messages in thread
From: Pavel Machek @ 2008-03-13 8:37 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Greg KH, Alan Stern, Andrew Morton, David Brownell, LKML, pm list
On Wed 2008-03-12 00:57:22, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rjw@sisk.pl>
>
> Modify the PM core to protect its data structures, specifically the
> dpm_active list, from being corrupted if a child of the currently
> suspending device is registered concurrently with its ->suspend()
> callback. In that case, since the new device (the child) is added
> to dpm_active after its parent, the PM core will attempt to
> suspend it after the parent, which is wrong.
>
> Introduce a new member of struct dev_pm_info, called 'sleeping',
> and use it to check if the parent of the device being added to
> dpm_active has been suspended, in which case the device registration
> fails. Also, use 'sleeping' for checking if the ordering of devices
> on dpm_active is correct.
>
> Introduce variable 'all_sleeping' that will be set to 'true' once all
> devices have been suspended and make new device registrations fail
> until 'all_sleeping' is reset to 'false', in order to avoid having
> unsuspended devices around while the system is going into a sleep state.
>
> Remove pm_sleep_rwsem which is not necessary any more.
>
> Special thanks to Alan Stern for discussions and suggestions that
> lead to the creation of this patch.
>
> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
ACK.
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/3] Driver core: Call device_pm_add() after bus_add_device() in device_add()
2008-03-11 23:59 ` [PATCH 2/3] Driver core: Call device_pm_add() after bus_add_device() in device_add() Rafael J. Wysocki
@ 2008-03-13 9:30 ` Pavel Machek
2008-03-13 20:54 ` patch driver-core-call-device_pm_add-after-bus_add_device-in-device_add.patch added to gregkh-2.6 tree gregkh
1 sibling, 0 replies; 11+ messages in thread
From: Pavel Machek @ 2008-03-13 9:30 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Greg KH, Alan Stern, Andrew Morton, David Brownell, LKML, pm list
On Wed 2008-03-12 00:59:38, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rjw@sisk.pl>
>
> Include dpm_sysfs_add() into device_pm_add(), in analogy with
> device_pm_remove(), and modify device_add() to call the latter after
> bus_add_device(), to avoid situations in which the PM core may
> attempt to suspend a device the registration of which has not been
> successful.
>
> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
ACK.
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 3/3] PM: make wakeup flags available whenever CONFIG_PM is set
2008-03-12 0:01 ` [PATCH 3/3] PM: make wakeup flags available whenever CONFIG_PM is set Rafael J. Wysocki
@ 2008-03-13 9:31 ` Pavel Machek
2008-03-13 20:54 ` patch pm-make-wakeup-flags-available-whenever-config_pm-is-set.patch added to gregkh-2.6 tree gregkh
1 sibling, 0 replies; 11+ messages in thread
From: Pavel Machek @ 2008-03-13 9:31 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Greg KH, Alan Stern, Andrew Morton, David Brownell, LKML, pm list
On Wed 2008-03-12 01:01:47, Rafael J. Wysocki wrote:
> From: Alan Stern <stern@rowland.harvard.edu>
>
> The various wakeup flags and their accessor macros in struct
> dev_pm_info should be available whenever CONFIG_PM is enabled, not
> just when CONFIG_PM_SLEEP is on. Otherwise remote wakeup won't always
> be configurable for runtime power management. This patch (as1056)
> fixes the oversight.
>
> [rjw: rebased the patch on top of the previous two.]
>
> Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
> CC: David Brownell <david-b@pacbell.net>
> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
ACK. But I wonder if we should reduce ammount of config options we
have in power management. All those combinations are hard to test...
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply [flat|nested] 11+ messages in thread
* patch driver-core-call-device_pm_add-after-bus_add_device-in-device_add.patch added to gregkh-2.6 tree
2008-03-11 23:59 ` [PATCH 2/3] Driver core: Call device_pm_add() after bus_add_device() in device_add() Rafael J. Wysocki
2008-03-13 9:30 ` Pavel Machek
@ 2008-03-13 20:54 ` gregkh
1 sibling, 0 replies; 11+ messages in thread
From: gregkh @ 2008-03-13 20:54 UTC (permalink / raw)
To: rjw, akpm, david-b, greg, gregkh, linux-kernel, linux-pm, pavel, stern
This is a note to let you know that I've just added the patch titled
Subject: Driver core: Call device_pm_add() after bus_add_device() in device_add()
to my gregkh-2.6 tree. Its filename is
driver-core-call-device_pm_add-after-bus_add_device-in-device_add.patch
This tree can be found at
http://www.kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/patches/
>From rjw@sisk.pl Thu Mar 13 13:45:38 2008
From: "Rafael J. Wysocki" <rjw@sisk.pl>
Date: Wed, 12 Mar 2008 00:59:38 +0100
Subject: Driver core: Call device_pm_add() after bus_add_device() in device_add()
To: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>, Andrew Morton <akpm@linux-foundation.org>, David Brownell <david-b@pacbell.net>, LKML <linux-kernel@vger.kernel.org>, Pavel Machek <pavel@ucw.cz>, pm list <linux-pm@lists.linux-foundation.org>
Message-ID: <200803120059.39902.rjw@sisk.pl>
Content-Disposition: inline
From: Rafael J. Wysocki <rjw@sisk.pl>
Include dpm_sysfs_add() into device_pm_add(), in analogy with
device_pm_remove(), and modify device_add() to call the latter after
bus_add_device(), to avoid situations in which the PM core may
attempt to suspend a device the registration of which has not been
successful.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/base/core.c | 15 +++++----------
drivers/base/power/main.c | 4 +++-
2 files changed, 8 insertions(+), 11 deletions(-)
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -818,17 +818,12 @@ int device_add(struct device *dev)
error = device_add_attrs(dev);
if (error)
goto AttrsError;
- error = dpm_sysfs_add(dev);
- if (error)
- goto PMError;
- error = device_pm_add(dev);
- if (error) {
- dpm_sysfs_remove(dev);
- goto PMError;
- }
error = bus_add_device(dev);
if (error)
goto BusError;
+ error = device_pm_add(dev);
+ if (error)
+ goto PMError;
kobject_uevent(&dev->kobj, KOBJ_ADD);
bus_attach_device(dev);
if (parent)
@@ -848,9 +843,9 @@ int device_add(struct device *dev)
Done:
put_device(dev);
return error;
- BusError:
- device_pm_remove(dev);
PMError:
+ bus_remove_device(dev);
+ BusError:
if (dev->bus)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
BUS_NOTIFY_DEL_DEVICE, dev);
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -81,7 +81,9 @@ int device_pm_add(struct device *dev)
WARN_ON(true);
error = -EBUSY;
} else {
- list_add_tail(&dev->power.entry, &dpm_active);
+ error = dpm_sysfs_add(dev);
+ if (!error)
+ list_add_tail(&dev->power.entry, &dpm_active);
}
mutex_unlock(&dpm_list_mtx);
return error;
Patches currently in gregkh-2.6 which might be from rjw@sisk.pl are
driver-core/power_state-remove-it-from-driver-core.patch
driver-core/pm-handle-device-registrations-during-suspend-resume.patch
driver-core/pm-make-wakeup-flags-available-whenever-config_pm-is-set.patch
driver-core/driver-core-call-device_pm_add-after-bus_add_device-in-device_add.patch
^ permalink raw reply [flat|nested] 11+ messages in thread
* patch pm-handle-device-registrations-during-suspend-resume.patch added to gregkh-2.6 tree
2008-03-11 23:57 ` [PATCH 1/3] PM: Handle device registrations during suspend/resume Rafael J. Wysocki
2008-03-13 8:37 ` Pavel Machek
@ 2008-03-13 20:54 ` gregkh
1 sibling, 0 replies; 11+ messages in thread
From: gregkh @ 2008-03-13 20:54 UTC (permalink / raw)
To: rjw, akpm, david-b, greg, gregkh, linux-kernel, linux-pm, pavel, stern
This is a note to let you know that I've just added the patch titled
Subject: PM: Handle device registrations during suspend/resume
to my gregkh-2.6 tree. Its filename is
pm-handle-device-registrations-during-suspend-resume.patch
This tree can be found at
http://www.kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/patches/
>From rjw@sisk.pl Thu Mar 13 13:44:50 2008
From: "Rafael J. Wysocki" <rjw@sisk.pl>
Date: Wed, 12 Mar 2008 00:57:22 +0100
Subject: PM: Handle device registrations during suspend/resume
To: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>, Andrew Morton <akpm@linux-foundation.org>, David Brownell <david-b@pacbell.net>, LKML <linux-kernel@vger.kernel.org>, Pavel Machek <pavel@ucw.cz>, pm list <linux-pm@lists.linux-foundation.org>
Message-ID: <200803120057.23101.rjw@sisk.pl>
Content-Disposition: inline
From: Rafael J. Wysocki <rjw@sisk.pl>
Modify the PM core to protect its data structures, specifically the
dpm_active list, from being corrupted if a child of the currently
suspending device is registered concurrently with its ->suspend()
callback. In that case, since the new device (the child) is added
to dpm_active after its parent, the PM core will attempt to
suspend it after the parent, which is wrong.
Introduce a new member of struct dev_pm_info, called 'sleeping',
and use it to check if the parent of the device being added to
dpm_active has been suspended, in which case the device registration
fails. Also, use 'sleeping' for checking if the ordering of devices
on dpm_active is correct.
Introduce variable 'all_sleeping' that will be set to 'true' once all
devices have been suspended and make new device registrations fail
until 'all_sleeping' is reset to 'false', in order to avoid having
unsuspended devices around while the system is going into a sleep state.
Remove pm_sleep_rwsem which is not necessary any more.
Special thanks to Alan Stern for discussions and suggestions that
lead to the creation of this patch.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
Documentation/power/devices.txt | 5 +++
drivers/base/core.c | 6 +++-
drivers/base/power/main.c | 57 ++++++++++++++++++----------------------
drivers/base/power/power.h | 23 ++--------------
include/linux/pm.h | 1
5 files changed, 40 insertions(+), 52 deletions(-)
--- a/Documentation/power/devices.txt
+++ b/Documentation/power/devices.txt
@@ -196,6 +196,11 @@ its parent; and can't be removed or susp
The policy is that the device tree should match hardware bus topology.
(Or at least the control bus, for devices which use multiple busses.)
+In particular, this means that a device registration may fail if the parent of
+the device is suspending (ie. has been chosen by the PM core as the next
+device to suspend) or has already suspended, as well as after all of the other
+devices have been suspended. Device drivers must be prepared to cope with such
+situations.
Suspending Devices
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -821,7 +821,11 @@ int device_add(struct device *dev)
error = dpm_sysfs_add(dev);
if (error)
goto PMError;
- device_pm_add(dev);
+ error = device_pm_add(dev);
+ if (error) {
+ dpm_sysfs_remove(dev);
+ goto PMError;
+ }
error = bus_add_device(dev);
if (error)
goto BusError;
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -54,7 +54,8 @@ static LIST_HEAD(dpm_destroy);
static DEFINE_MUTEX(dpm_list_mtx);
-static DECLARE_RWSEM(pm_sleep_rwsem);
+/* 'true' if all devices have been suspended, protected by dpm_list_mtx */
+static bool all_sleeping;
int (*platform_enable_wakeup)(struct device *dev, int is_on);
@@ -62,14 +63,28 @@ int (*platform_enable_wakeup)(struct dev
* device_pm_add - add a device to the list of active devices
* @dev: Device to be added to the list
*/
-void device_pm_add(struct device *dev)
+int device_pm_add(struct device *dev)
{
+ int error = 0;
+
pr_debug("PM: Adding info for %s:%s\n",
dev->bus ? dev->bus->name : "No Bus",
kobject_name(&dev->kobj));
mutex_lock(&dpm_list_mtx);
- list_add_tail(&dev->power.entry, &dpm_active);
+ if ((dev->parent && dev->parent->power.sleeping) || all_sleeping) {
+ if (dev->parent->power.sleeping)
+ dev_warn(dev,
+ "parent %s is sleeping, will not add\n",
+ dev->parent->bus_id);
+ else
+ dev_warn(dev, "devices are sleeping, will not add\n");
+ WARN_ON(true);
+ error = -EBUSY;
+ } else {
+ list_add_tail(&dev->power.entry, &dpm_active);
+ }
mutex_unlock(&dpm_list_mtx);
+ return error;
}
/**
@@ -107,32 +122,6 @@ void device_pm_schedule_removal(struct d
}
EXPORT_SYMBOL_GPL(device_pm_schedule_removal);
-/**
- * pm_sleep_lock - mutual exclusion for registration and suspend
- *
- * Returns 0 if no suspend is underway and device registration
- * may proceed, otherwise -EBUSY.
- */
-int pm_sleep_lock(void)
-{
- if (down_read_trylock(&pm_sleep_rwsem))
- return 0;
-
- return -EBUSY;
-}
-
-/**
- * pm_sleep_unlock - mutual exclusion for registration and suspend
- *
- * This routine undoes the effect of device_pm_add_lock
- * when a device's registration is complete.
- */
-void pm_sleep_unlock(void)
-{
- up_read(&pm_sleep_rwsem);
-}
-
-
/*------------------------- Resume routines -------------------------*/
/**
@@ -242,11 +231,13 @@ static int resume_device(struct device *
static void dpm_resume(void)
{
mutex_lock(&dpm_list_mtx);
+ all_sleeping = false;
while(!list_empty(&dpm_off)) {
struct list_head *entry = dpm_off.next;
struct device *dev = to_device(entry);
list_move_tail(entry, &dpm_active);
+ dev->power.sleeping = false;
mutex_unlock(&dpm_list_mtx);
resume_device(dev);
mutex_lock(&dpm_list_mtx);
@@ -285,7 +276,6 @@ void device_resume(void)
might_sleep();
dpm_resume();
unregister_dropped_devices();
- up_write(&pm_sleep_rwsem);
}
EXPORT_SYMBOL_GPL(device_resume);
@@ -421,6 +411,9 @@ static int dpm_suspend(pm_message_t stat
struct list_head *entry = dpm_active.prev;
struct device *dev = to_device(entry);
+ WARN_ON(dev->parent && dev->parent->power.sleeping);
+
+ dev->power.sleeping = true;
mutex_unlock(&dpm_list_mtx);
error = suspend_device(dev, state);
mutex_lock(&dpm_list_mtx);
@@ -432,11 +425,14 @@ static int dpm_suspend(pm_message_t stat
(error == -EAGAIN ?
" (please convert to suspend_late)" :
""));
+ dev->power.sleeping = false;
break;
}
if (!list_empty(&dev->power.entry))
list_move(&dev->power.entry, &dpm_off);
}
+ if (!error)
+ all_sleeping = true;
mutex_unlock(&dpm_list_mtx);
return error;
@@ -454,7 +450,6 @@ int device_suspend(pm_message_t state)
int error;
might_sleep();
- down_write(&pm_sleep_rwsem);
error = dpm_suspend(state);
if (error)
device_resume();
--- a/drivers/base/power/power.h
+++ b/drivers/base/power/power.h
@@ -11,30 +11,13 @@ static inline struct device *to_device(s
return container_of(entry, struct device, power.entry);
}
-extern void device_pm_add(struct device *);
+extern int device_pm_add(struct device *);
extern void device_pm_remove(struct device *);
-extern int pm_sleep_lock(void);
-extern void pm_sleep_unlock(void);
#else /* CONFIG_PM_SLEEP */
-
-static inline void device_pm_add(struct device *dev)
-{
-}
-
-static inline void device_pm_remove(struct device *dev)
-{
-}
-
-static inline int pm_sleep_lock(void)
-{
- return 0;
-}
-
-static inline void pm_sleep_unlock(void)
-{
-}
+static inline int device_pm_add(struct device *dev) { return 0; }
+static inline void device_pm_remove(struct device *dev) {}
#endif
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -183,6 +183,7 @@ typedef struct pm_message {
struct dev_pm_info {
pm_message_t power_state;
unsigned can_wakeup:1;
+ bool sleeping:1; /* Owned by the PM core */
#ifdef CONFIG_PM_SLEEP
unsigned should_wakeup:1;
struct list_head entry;
Patches currently in gregkh-2.6 which might be from rjw@sisk.pl are
driver-core/power_state-remove-it-from-driver-core.patch
driver-core/pm-handle-device-registrations-during-suspend-resume.patch
driver-core/pm-make-wakeup-flags-available-whenever-config_pm-is-set.patch
driver-core/driver-core-call-device_pm_add-after-bus_add_device-in-device_add.patch
^ permalink raw reply [flat|nested] 11+ messages in thread
* patch pm-make-wakeup-flags-available-whenever-config_pm-is-set.patch added to gregkh-2.6 tree
2008-03-12 0:01 ` [PATCH 3/3] PM: make wakeup flags available whenever CONFIG_PM is set Rafael J. Wysocki
2008-03-13 9:31 ` Pavel Machek
@ 2008-03-13 20:54 ` gregkh
1 sibling, 0 replies; 11+ messages in thread
From: gregkh @ 2008-03-13 20:54 UTC (permalink / raw)
To: stern, akpm, david-b, greg, gregkh, linux-kernel, linux-pm, pavel, rjw
This is a note to let you know that I've just added the patch titled
Subject: PM: make wakeup flags available whenever CONFIG_PM is set
to my gregkh-2.6 tree. Its filename is
pm-make-wakeup-flags-available-whenever-config_pm-is-set.patch
This tree can be found at
http://www.kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/patches/
>From rjw@sisk.pl Thu Mar 13 13:46:04 2008
From: Alan Stern <stern@rowland.harvard.edu>
Date: Wed, 12 Mar 2008 01:01:47 +0100
Subject: PM: make wakeup flags available whenever CONFIG_PM is set
To: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>, Andrew Morton <akpm@linux-foundation.org>, David Brownell <david-b@pacbell.net>, LKML <linux-kernel@vger.kernel.org>, Pavel Machek <pavel@ucw.cz>, pm list <linux-pm@lists.linux-foundation.org>
Message-ID: <200803120101.48805.rjw@sisk.pl>
Content-Disposition: inline
From: Alan Stern <stern@rowland.harvard.edu>
The various wakeup flags and their accessor macros in struct
dev_pm_info should be available whenever CONFIG_PM is enabled, not
just when CONFIG_PM_SLEEP is on. Otherwise remote wakeup won't always
be configurable for runtime power management. This patch (as1056)
fixes the oversight.
[rjw: rebased the patch on top of the previous two.]
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
CC: David Brownell <david-b@pacbell.net>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/base/power/main.c | 2 -
drivers/base/power/sysfs.c | 2 +
include/linux/pm.h | 64 +++++++++++++++++++++++++--------------------
3 files changed, 38 insertions(+), 30 deletions(-)
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -57,8 +57,6 @@ static DEFINE_MUTEX(dpm_list_mtx);
/* 'true' if all devices have been suspended, protected by dpm_list_mtx */
static bool all_sleeping;
-int (*platform_enable_wakeup)(struct device *dev, int is_on);
-
/**
* device_pm_add - add a device to the list of active devices
* @dev: Device to be added to the list
--- a/drivers/base/power/sysfs.c
+++ b/drivers/base/power/sysfs.c
@@ -6,6 +6,8 @@
#include <linux/string.h>
#include "power.h"
+int (*platform_enable_wakeup)(struct device *dev, int is_on);
+
/*
* wakeup - Report/change current wakeup option for device
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -183,9 +183,9 @@ typedef struct pm_message {
struct dev_pm_info {
pm_message_t power_state;
unsigned can_wakeup:1;
+ unsigned should_wakeup:1;
bool sleeping:1; /* Owned by the PM core */
#ifdef CONFIG_PM_SLEEP
- unsigned should_wakeup:1;
struct list_head entry;
#endif
};
@@ -198,11 +198,6 @@ extern void device_resume(void);
extern int device_suspend(pm_message_t state);
extern int device_prepare_suspend(pm_message_t state);
-#define device_set_wakeup_enable(dev,val) \
- ((dev)->power.should_wakeup = !!(val))
-#define device_may_wakeup(dev) \
- (device_can_wakeup(dev) && (dev)->power.should_wakeup)
-
extern void __suspend_report_result(const char *function, void *fn, int ret);
#define suspend_report_result(fn, ret) \
@@ -210,6 +205,35 @@ extern void __suspend_report_result(cons
__suspend_report_result(__FUNCTION__, fn, ret); \
} while (0)
+#else /* !CONFIG_PM_SLEEP */
+
+static inline int device_suspend(pm_message_t state)
+{
+ return 0;
+}
+
+#define suspend_report_result(fn, ret) do {} while (0)
+
+#endif /* !CONFIG_PM_SLEEP */
+
+#ifdef CONFIG_PM
+
+/* changes to device_may_wakeup take effect on the next pm state change.
+ * by default, devices should wakeup if they can.
+ */
+#define device_can_wakeup(dev) \
+ ((dev)->power.can_wakeup)
+#define device_init_wakeup(dev,val) \
+ do { \
+ device_can_wakeup(dev) = !!(val); \
+ device_set_wakeup_enable(dev,val); \
+ } while(0)
+
+#define device_set_wakeup_enable(dev,val) \
+ ((dev)->power.should_wakeup = !!(val))
+#define device_may_wakeup(dev) \
+ (device_can_wakeup(dev) && (dev)->power.should_wakeup)
+
/*
* Platform hook to activate device wakeup capability, if that's not already
* handled by enable_irq_wake() etc.
@@ -224,35 +248,19 @@ static inline int call_platform_enable_w
return 0;
}
-#else /* !CONFIG_PM_SLEEP */
-
-static inline int device_suspend(pm_message_t state)
-{
- return 0;
-}
-
-#define device_set_wakeup_enable(dev,val) do{}while(0)
-#define device_may_wakeup(dev) (0)
+#else /* !CONFIG_PM */
-#define suspend_report_result(fn, ret) do { } while (0)
+#define device_can_wakeup(dev) 0
+#define device_init_wakeup(dev,val) do {} while (0)
+#define device_set_wakeup_enable(dev,val) do {} while (0)
+#define device_may_wakeup(dev) 0
static inline int call_platform_enable_wakeup(struct device *dev, int is_on)
{
return 0;
}
-#endif /* !CONFIG_PM_SLEEP */
-
-/* changes to device_may_wakeup take effect on the next pm state change.
- * by default, devices should wakeup if they can.
- */
-#define device_can_wakeup(dev) \
- ((dev)->power.can_wakeup)
-#define device_init_wakeup(dev,val) \
- do { \
- device_can_wakeup(dev) = !!(val); \
- device_set_wakeup_enable(dev,val); \
- } while(0)
+#endif /* !CONFIG_PM */
/*
* Global Power Management flags
Patches currently in gregkh-2.6 which might be from stern@rowland.harvard.edu are
usb/usb-convert-usb.h-struct-usb_device-to-kernel-doc.patch
usb/usb-make-usb_storage_onetouch-available-with-pm.patch
usb/usb-usb-ohci-sm501-driver-use-the-conventional-convention-for-suspend-and-resume.patch
usb/usb-reorganize-code-in-hub.c.patch
usb/usb-ehci-carry-out-port-handover-during-each-root-hub-resume.patch
usb/usb-new-quirk-flag-to-avoid-set-interface.patch
usb/drivers-usb-core-devio.c-suppress-warning-with-64k-page_size.patch
usb/usb-make-usb-persist-work-after-every-system-sleep.patch
usb/usb-remove-config_usb_persist-setting.patch
usb/usb-check-serial-number-string-after-device-reset.patch
usb/usb-enable-usb-persist-by-default.patch
usb/usb-remove-dev-power.power_state.patch
driver-core/pm-handle-device-registrations-during-suspend-resume.patch
driver-core/pm-make-wakeup-flags-available-whenever-config_pm-is-set.patch
driver-core/driver-core-call-device_pm_add-after-bus_add_device-in-device_add.patch
^ permalink raw reply [flat|nested] 11+ messages in thread
* patch pm-make-wakeup-flags-available-whenever-config_pm-is-set.patch added to gregkh-2.6 tree
2008-03-19 21:37 [PATCH 2/3] PM: Make wakeup flags available whenever CONFIG_PM is set (ver 2) Rafael J. Wysocki
@ 2008-03-20 23:23 ` gregkh
0 siblings, 0 replies; 11+ messages in thread
From: gregkh @ 2008-03-20 23:23 UTC (permalink / raw)
To: stern, akpm, greg, gregkh, linux-kernel, linux-pm, rjw
This is a note to let you know that I've just added the patch titled
Subject: PM: Make wakeup flags available whenever CONFIG_PM is set
to my gregkh-2.6 tree. Its filename is
pm-make-wakeup-flags-available-whenever-config_pm-is-set.patch
This tree can be found at
http://www.kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/patches/
>From rjw@sisk.pl Thu Mar 20 16:20:59 2008
From: Alan Stern <stern@rowland.harvard.edu>
Date: Wed, 19 Mar 2008 22:37:42 +0100
Subject: PM: Make wakeup flags available whenever CONFIG_PM is set
To: Greg KH <greg@kroah.com>
Cc: Andrew Morton <akpm@linux-foundation.org>, Alan Stern <stern@rowland.harvard.edu>, Linux-pm mailing list <linux-pm@lists.linux-foundation.org>, Kernel development list <linux-kernel@vger.kernel.org>, lenb@kernel.org
Message-ID: <200803192237.43123.rjw@sisk.pl>
Content-Disposition: inline
From: Alan Stern <stern@rowland.harvard.edu>
The various wakeup flags and their accessor macros in struct
dev_pm_info should be available whenever CONFIG_PM is enabled, not
just when CONFIG_PM_SLEEP is on. Otherwise remote wakeup won't always
be configurable for runtime power management. This patch (as1056b)
fixes the oversight.
David Brownell adds:
More accurately, fixes the "regression" ... as noted sometime
last summer, after 296699de6bdc717189a331ab6bbe90e05c94db06
introduced CONFIG_SUSPEND. But that didn't make the regression
list for that kernel, ergo the delay in fixing it.
[rjw: rebased]
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/base/power/main.c | 2 --
drivers/base/power/sysfs.c | 2 ++
include/linux/pm.h | 36 +++++++++++++++++++++---------------
3 files changed, 23 insertions(+), 17 deletions(-)
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -57,8 +57,6 @@ static DEFINE_MUTEX(dpm_list_mtx);
/* 'true' if all devices have been suspended, protected by dpm_list_mtx */
static bool all_sleeping;
-int (*platform_enable_wakeup)(struct device *dev, int is_on);
-
/**
* device_pm_add - add a device to the list of active devices
* @dev: Device to be added to the list
--- a/drivers/base/power/sysfs.c
+++ b/drivers/base/power/sysfs.c
@@ -6,6 +6,8 @@
#include <linux/string.h>
#include "power.h"
+int (*platform_enable_wakeup)(struct device *dev, int is_on);
+
/*
* wakeup - Report/change current wakeup option for device
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -183,9 +183,9 @@ typedef struct pm_message {
struct dev_pm_info {
pm_message_t power_state;
unsigned can_wakeup:1;
+ unsigned should_wakeup:1;
bool sleeping:1; /* Owned by the PM core */
#ifdef CONFIG_PM_SLEEP
- unsigned should_wakeup:1;
struct list_head entry;
#endif
};
@@ -198,11 +198,6 @@ extern void device_resume(void);
extern int device_suspend(pm_message_t state);
extern int device_prepare_suspend(pm_message_t state);
-#define device_set_wakeup_enable(dev,val) \
- ((dev)->power.should_wakeup = !!(val))
-#define device_may_wakeup(dev) \
- (device_can_wakeup(dev) && (dev)->power.should_wakeup)
-
extern void __suspend_report_result(const char *function, void *fn, int ret);
#define suspend_report_result(fn, ret) \
@@ -210,6 +205,24 @@ extern void __suspend_report_result(cons
__suspend_report_result(__FUNCTION__, fn, ret); \
} while (0)
+#else /* !CONFIG_PM_SLEEP */
+
+static inline int device_suspend(pm_message_t state)
+{
+ return 0;
+}
+
+#define suspend_report_result(fn, ret) do { } while (0)
+
+#endif /* !CONFIG_PM_SLEEP */
+
+#ifdef CONFIG_PM
+
+#define device_set_wakeup_enable(dev,val) \
+ ((dev)->power.should_wakeup = !!(val))
+#define device_may_wakeup(dev) \
+ (device_can_wakeup(dev) && (dev)->power.should_wakeup)
+
/*
* Platform hook to activate device wakeup capability, if that's not already
* handled by enable_irq_wake() etc.
@@ -224,24 +237,17 @@ static inline int call_platform_enable_w
return 0;
}
-#else /* !CONFIG_PM_SLEEP */
-
-static inline int device_suspend(pm_message_t state)
-{
- return 0;
-}
+#else /* !CONFIG_PM */
#define device_set_wakeup_enable(dev,val) do{}while(0)
#define device_may_wakeup(dev) (0)
-#define suspend_report_result(fn, ret) do { } while (0)
-
static inline int call_platform_enable_wakeup(struct device *dev, int is_on)
{
return 0;
}
-#endif /* !CONFIG_PM_SLEEP */
+#endif /* !CONFIG_PM */
/* changes to device_may_wakeup take effect on the next pm state change.
* by default, devices should wakeup if they can.
Patches currently in gregkh-2.6 which might be from stern@rowland.harvard.edu are
usb/usb-convert-usb.h-struct-usb_device-to-kernel-doc.patch
usb/usb-make-usb_storage_onetouch-available-with-pm.patch
usb/usb-usb-ohci-sm501-driver-use-the-conventional-convention-for-suspend-and-resume.patch
usb/usb-reorganize-code-in-hub.c.patch
usb/usb-ehci-carry-out-port-handover-during-each-root-hub-resume.patch
usb/usb-new-quirk-flag-to-avoid-set-interface.patch
usb/drivers-usb-core-devio.c-suppress-warning-with-64k-page_size.patch
usb/usb-make-usb-persist-work-after-every-system-sleep.patch
usb/usb-remove-config_usb_persist-setting.patch
usb/usb-check-serial-number-string-after-device-reset.patch
usb/usb-enable-usb-persist-by-default.patch
usb/usb-remove-dev-power.power_state.patch
usb/usb-isd200-fix-memory-leak-in-isd200_get_inquiry_data.patch
usb/usb-remove-experimental-tags-from-some-usb-gadget-kconfig-entries.patch
driver-core/pm-handle-device-registrations-during-suspend-resume.patch
driver-core/pm-convert-wakeup-flag-accessors-to-inline-functions.patch
driver-core/driver-core-call-device_pm_add-after-bus_add_device-in-device_add.patch
driver-core/pm-fix-misuse-of-wakeup-flag-accessors-in-serial-core.patch
driver-core/pm-make-wakeup-flags-available-whenever-config_pm-is-set.patch
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2008-03-20 23:24 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-03-11 23:55 [PATCH 0/3] PM core fixes Rafael J. Wysocki
2008-03-11 23:57 ` [PATCH 1/3] PM: Handle device registrations during suspend/resume Rafael J. Wysocki
2008-03-13 8:37 ` Pavel Machek
2008-03-13 20:54 ` patch pm-handle-device-registrations-during-suspend-resume.patch added to gregkh-2.6 tree gregkh
2008-03-11 23:59 ` [PATCH 2/3] Driver core: Call device_pm_add() after bus_add_device() in device_add() Rafael J. Wysocki
2008-03-13 9:30 ` Pavel Machek
2008-03-13 20:54 ` patch driver-core-call-device_pm_add-after-bus_add_device-in-device_add.patch added to gregkh-2.6 tree gregkh
2008-03-12 0:01 ` [PATCH 3/3] PM: make wakeup flags available whenever CONFIG_PM is set Rafael J. Wysocki
2008-03-13 9:31 ` Pavel Machek
2008-03-13 20:54 ` patch pm-make-wakeup-flags-available-whenever-config_pm-is-set.patch added to gregkh-2.6 tree gregkh
2008-03-19 21:37 [PATCH 2/3] PM: Make wakeup flags available whenever CONFIG_PM is set (ver 2) Rafael J. Wysocki
2008-03-20 23:23 ` patch pm-make-wakeup-flags-available-whenever-config_pm-is-set.patch added to gregkh-2.6 tree gregkh
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).