Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 91397
b: refs/heads/master
c: 58aca23
h: refs/heads/master
i:
  91395: b311ffa
v: v3
  • Loading branch information
Rafael J. Wysocki authored and Greg Kroah-Hartman committed Apr 20, 2008
1 parent 7b299f7 commit 6828694
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 53 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6bcf19d02a5d7e627fa054f2f10e0a8d830df326
refs/heads/master: 58aca23226a19983571bd3b65167521fc64f5869
5 changes: 5 additions & 0 deletions trunk/Documentation/power/devices.txt
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,11 @@ its parent; and can't be removed or suspended after that parent.

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
Expand Down
6 changes: 5 additions & 1 deletion trunk/drivers/base/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -820,7 +820,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;
Expand Down
57 changes: 26 additions & 31 deletions trunk/drivers/base/power/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,22 +54,37 @@ 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);

/**
* 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;
}

/**
Expand Down Expand Up @@ -107,32 +122,6 @@ void device_pm_schedule_removal(struct device *dev)
}
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 -------------------------*/

/**
Expand Down Expand Up @@ -242,11 +231,13 @@ static int resume_device(struct device *dev)
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);
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -421,6 +411,9 @@ static int dpm_suspend(pm_message_t state)
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);
Expand All @@ -432,11 +425,14 @@ static int dpm_suspend(pm_message_t state)
(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;
Expand All @@ -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();
Expand Down
23 changes: 3 additions & 20 deletions trunk/drivers/base/power/power.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,13 @@ static inline struct device *to_device(struct list_head *entry)
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

Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/pm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 6828694

Please sign in to comment.