git.openpandora.org
/
pandora-kernel.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
PM: Reset transition_started at dpm_resume_noirq
[pandora-kernel.git]
/
drivers
/
base
/
power
/
main.c
diff --git
a/drivers/base/power/main.c
b/drivers/base/power/main.c
index
58a3e57
..
e0dc407
100644
(file)
--- a/
drivers/base/power/main.c
+++ b/
drivers/base/power/main.c
@@
-21,6
+21,7
@@
#include <linux/kallsyms.h>
#include <linux/mutex.h>
#include <linux/pm.h>
#include <linux/kallsyms.h>
#include <linux/mutex.h>
#include <linux/pm.h>
+#include <linux/pm_runtime.h>
#include <linux/resume-trace.h>
#include <linux/rwsem.h>
#include <linux/interrupt.h>
#include <linux/resume-trace.h>
#include <linux/rwsem.h>
#include <linux/interrupt.h>
@@
-49,7
+50,17
@@
static DEFINE_MUTEX(dpm_list_mtx);
static bool transition_started;
/**
static bool transition_started;
/**
- * device_pm_lock - lock the list of active devices used by the PM core
+ * device_pm_init - Initialize the PM-related part of a device object.
+ * @dev: Device object being initialized.
+ */
+void device_pm_init(struct device *dev)
+{
+ dev->power.status = DPM_ON;
+ pm_runtime_init(dev);
+}
+
+/**
+ * device_pm_lock - Lock the list of active devices used by the PM core.
*/
void device_pm_lock(void)
{
*/
void device_pm_lock(void)
{
@@
-57,7
+68,7
@@
void device_pm_lock(void)
}
/**
}
/**
- *
device_pm_unlock - unlock the list of active devices used by the PM core
+ *
device_pm_unlock - Unlock the list of active devices used by the PM core.
*/
void device_pm_unlock(void)
{
*/
void device_pm_unlock(void)
{
@@
-65,8
+76,8
@@
void device_pm_unlock(void)
}
/**
}
/**
- *
device_pm_add - add a device to the list of active devices
- *
@dev: Device to be added to the list
+ *
device_pm_add - Add a device to the PM core's list of active devices.
+ *
@dev: Device to add to the list.
*/
void device_pm_add(struct device *dev)
{
*/
void device_pm_add(struct device *dev)
{
@@
-92,10
+103,8
@@
void device_pm_add(struct device *dev)
}
/**
}
/**
- * device_pm_remove - remove a device from the list of active devices
- * @dev: Device to be removed from the list
- *
- * This function also removes the device's PM-related sysfs attributes.
+ * device_pm_remove - Remove a device from the PM core's list of active devices.
+ * @dev: Device to be removed from the list.
*/
void device_pm_remove(struct device *dev)
{
*/
void device_pm_remove(struct device *dev)
{
@@
-105,12
+114,13
@@
void device_pm_remove(struct device *dev)
mutex_lock(&dpm_list_mtx);
list_del_init(&dev->power.entry);
mutex_unlock(&dpm_list_mtx);
mutex_lock(&dpm_list_mtx);
list_del_init(&dev->power.entry);
mutex_unlock(&dpm_list_mtx);
+ pm_runtime_remove(dev);
}
/**
}
/**
- *
device_pm_move_before - move device in dpm_list
- *
@deva: Device to move in dpm_list
- *
@devb: Device @deva should come before
+ *
device_pm_move_before - Move device in the PM core's list of active devices.
+ *
@deva: Device to move in dpm_list.
+ *
@devb: Device @deva should come before.
*/
void device_pm_move_before(struct device *deva, struct device *devb)
{
*/
void device_pm_move_before(struct device *deva, struct device *devb)
{
@@
-124,9
+134,9
@@
void device_pm_move_before(struct device *deva, struct device *devb)
}
/**
}
/**
- *
device_pm_move_after - move device in dpm_list
- *
@deva: Device to move in dpm_list
- *
@devb: Device @deva should come after
+ *
device_pm_move_after - Move device in the PM core's list of active devices.
+ *
@deva: Device to move in dpm_list.
+ *
@devb: Device @deva should come after.
*/
void device_pm_move_after(struct device *deva, struct device *devb)
{
*/
void device_pm_move_after(struct device *deva, struct device *devb)
{
@@
-140,8
+150,8
@@
void device_pm_move_after(struct device *deva, struct device *devb)
}
/**
}
/**
- *
device_pm_move_last - move device to end of dpm_list
- *
@dev: Device to move in dpm_list
+ *
device_pm_move_last - Move device to end of the PM core's list of devices.
+ *
@dev: Device to move in dpm_list.
*/
void device_pm_move_last(struct device *dev)
{
*/
void device_pm_move_last(struct device *dev)
{
@@
-152,13
+162,14
@@
void device_pm_move_last(struct device *dev)
}
/**
}
/**
- *
pm_op - execute the PM operation appropiate for given PM event
- *
@dev: Devic
e.
- *
@ops:
PM operations to choose from.
- *
@state: PM transition of the system being carried out.
+ *
pm_op - Execute the PM operation appropriate for given PM event.
+ *
@dev: Device to handl
e.
+ *
@ops:
PM operations to choose from.
+ * @state: PM transition of the system being carried out.
*/
*/
-static int pm_op(struct device *dev, struct dev_pm_ops *ops,
- pm_message_t state)
+static int pm_op(struct device *dev,
+ const struct dev_pm_ops *ops,
+ pm_message_t state)
{
int error = 0;
{
int error = 0;
@@
-212,15
+223,16
@@
static int pm_op(struct device *dev, struct dev_pm_ops *ops,
}
/**
}
/**
- *
pm_noirq_op - execute the PM operation appropiate for given PM event
- *
@dev: Devic
e.
- *
@ops:
PM operations to choose from.
- *
@state: PM transition of the system being carried out.
+ *
pm_noirq_op - Execute the PM operation appropriate for given PM event.
+ *
@dev: Device to handl
e.
+ *
@ops:
PM operations to choose from.
+ * @state: PM transition of the system being carried out.
*
*
- *
The operation is executed with interrupts disabled by the only remain
ing
- *
functional CPU in the system
.
+ *
The driver of @dev will not receive interrupts while this function is be
ing
+ *
executed
.
*/
*/
-static int pm_noirq_op(struct device *dev, struct dev_pm_ops *ops,
+static int pm_noirq_op(struct device *dev,
+ const struct dev_pm_ops *ops,
pm_message_t state)
{
int error = 0;
pm_message_t state)
{
int error = 0;
@@
-315,11
+327,12
@@
static void pm_dev_err(struct device *dev, pm_message_t state, char *info,
/*------------------------- Resume routines -------------------------*/
/**
/*------------------------- Resume routines -------------------------*/
/**
- *
device_resume_noirq - Power on one device (early resume)
.
- *
@dev: Devic
e.
- *
@state: PM transition of the system being carried out.
+ *
device_resume_noirq - Execute an "early resume" callback for given device
.
+ *
@dev: Device to handl
e.
+ * @state: PM transition of the system being carried out.
*
*
- * Must be called with interrupts disabled.
+ * The driver of @dev will not receive interrupts while this function is being
+ * executed.
*/
static int device_resume_noirq(struct device *dev, pm_message_t state)
{
*/
static int device_resume_noirq(struct device *dev, pm_message_t state)
{
@@
-341,20
+354,18
@@
static int device_resume_noirq(struct device *dev, pm_message_t state)
}
/**
}
/**
- * dpm_resume_noirq - Power on all regular (non-sysdev) devices.
- * @state: PM transition of the system being carried out.
- *
- * Call the "noirq" resume handlers for all devices marked as
- * DPM_OFF_IRQ and enable device drivers to receive interrupts.
+ * dpm_resume_noirq - Execute "early resume" callbacks for non-sysdev devices.
+ * @state: PM transition of the system being carried out.
*
*
- *
Must be called under dpm_list_mtx. Device drivers should not receive
- *
interrupts while it's being executed
.
+ *
Call the "noirq" resume handlers for all devices marked as DPM_OFF_IRQ and
+ *
enable device drivers to receive interrupts
.
*/
void dpm_resume_noirq(pm_message_t state)
{
struct device *dev;
mutex_lock(&dpm_list_mtx);
*/
void dpm_resume_noirq(pm_message_t state)
{
struct device *dev;
mutex_lock(&dpm_list_mtx);
+ transition_started = false;
list_for_each_entry(dev, &dpm_list, power.entry)
if (dev->power.status > DPM_OFF) {
int error;
list_for_each_entry(dev, &dpm_list, power.entry)
if (dev->power.status > DPM_OFF) {
int error;
@@
-370,9
+381,9
@@
void dpm_resume_noirq(pm_message_t state)
EXPORT_SYMBOL_GPL(dpm_resume_noirq);
/**
EXPORT_SYMBOL_GPL(dpm_resume_noirq);
/**
- *
device_resume - Restore state for one
device.
- *
@dev: Devic
e.
- *
@state: PM transition of the system being carried out.
+ *
device_resume - Execute "resume" callbacks for given
device.
+ *
@dev: Device to handl
e.
+ * @state: PM transition of the system being carried out.
*/
static int device_resume(struct device *dev, pm_message_t state)
{
*/
static int device_resume(struct device *dev, pm_message_t state)
{
@@
-421,11
+432,11
@@
static int device_resume(struct device *dev, pm_message_t state)
}
/**
}
/**
- *
dpm_resume - Resume every device
.
- *
@state: PM transition of the system being carried out.
+ *
dpm_resume - Execute "resume" callbacks for non-sysdev devices
.
+ * @state: PM transition of the system being carried out.
*
*
- *
Execute the appropriate "resume" callback for all devices the status of
- *
which indicates that they are inactive
.
+ *
Execute the appropriate "resume" callback for all devices whose status
+ *
indicates that they are suspended
.
*/
static void dpm_resume(pm_message_t state)
{
*/
static void dpm_resume(pm_message_t state)
{
@@
-433,7
+444,6
@@
static void dpm_resume(pm_message_t state)
INIT_LIST_HEAD(&list);
mutex_lock(&dpm_list_mtx);
INIT_LIST_HEAD(&list);
mutex_lock(&dpm_list_mtx);
- transition_started = false;
while (!list_empty(&dpm_list)) {
struct device *dev = to_device(dpm_list.next);
while (!list_empty(&dpm_list)) {
struct device *dev = to_device(dpm_list.next);
@@
-462,9
+472,9
@@
static void dpm_resume(pm_message_t state)
}
/**
}
/**
- *
device_complete - Complete a PM transition for given device
- *
@dev: Devic
e.
- *
@state: PM transition of the system being carried out.
+ *
device_complete - Complete a PM transition for given device.
+ *
@dev: Device to handl
e.
+ * @state: PM transition of the system being carried out.
*/
static void device_complete(struct device *dev, pm_message_t state)
{
*/
static void device_complete(struct device *dev, pm_message_t state)
{
@@
-489,11
+499,11
@@
static void device_complete(struct device *dev, pm_message_t state)
}
/**
}
/**
- *
dpm_complete - Complete a PM transition for all
devices.
- *
@state: PM transition of the system being carried out.
+ *
dpm_complete - Complete a PM transition for all non-sysdev
devices.
+ * @state: PM transition of the system being carried out.
*
*
- *
Execute the ->complete() callbacks for all devices that are not marked
- *
as DPM_ON
.
+ *
Execute the ->complete() callbacks for all devices whose PM status is not
+ *
DPM_ON (this allows new devices to be registered)
.
*/
static void dpm_complete(pm_message_t state)
{
*/
static void dpm_complete(pm_message_t state)
{
@@
-510,6
+520,7
@@
static void dpm_complete(pm_message_t state)
mutex_unlock(&dpm_list_mtx);
device_complete(dev, state);
mutex_unlock(&dpm_list_mtx);
device_complete(dev, state);
+ pm_runtime_put_noidle(dev);
mutex_lock(&dpm_list_mtx);
}
mutex_lock(&dpm_list_mtx);
}
@@
-522,11
+533,11
@@
static void dpm_complete(pm_message_t state)
}
/**
}
/**
- *
dpm_resume_end - Restore state of each device in system
.
- *
@state: PM transition of the system being carried out.
+ *
dpm_resume_end - Execute "resume" callbacks and complete system transition
.
+ * @state: PM transition of the system being carried out.
*
*
- *
Resume all the devices, unlock them all, and allow new
- *
devices to be registered once again
.
+ *
Execute "resume" callbacks for all devices and complete the PM transition of
+ *
the system
.
*/
void dpm_resume_end(pm_message_t state)
{
*/
void dpm_resume_end(pm_message_t state)
{
@@
-540,9
+551,11
@@
EXPORT_SYMBOL_GPL(dpm_resume_end);
/*------------------------- Suspend routines -------------------------*/
/**
/*------------------------- Suspend routines -------------------------*/
/**
- * resume_event - return a PM message representing the resume event
- * corresponding to given sleep state.
- * @sleep_state: PM message representing a sleep state.
+ * resume_event - Return a "resume" message for given "suspend" sleep state.
+ * @sleep_state: PM message representing a sleep state.
+ *
+ * Return a PM message representing the resume event corresponding to given
+ * sleep state.
*/
static pm_message_t resume_event(pm_message_t sleep_state)
{
*/
static pm_message_t resume_event(pm_message_t sleep_state)
{
@@
-559,11
+572,12
@@
static pm_message_t resume_event(pm_message_t sleep_state)
}
/**
}
/**
- *
device_suspend_noirq - Shut down one device (late suspend)
.
- *
@dev: Devic
e.
- *
@state: PM transition of the system being carried out.
+ *
device_suspend_noirq - Execute a "late suspend" callback for given device
.
+ *
@dev: Device to handl
e.
+ * @state: PM transition of the system being carried out.
*
*
- * This is called with interrupts off and only a single CPU running.
+ * The driver of @dev will not receive interrupts while this function is being
+ * executed.
*/
static int device_suspend_noirq(struct device *dev, pm_message_t state)
{
*/
static int device_suspend_noirq(struct device *dev, pm_message_t state)
{
@@
-580,13
+594,11
@@
static int device_suspend_noirq(struct device *dev, pm_message_t state)
}
/**
}
/**
- * dpm_suspend_noirq - Power down all regular (non-sysdev) devices.
- * @state: PM transition of the system being carried out.
- *
- * Prevent device drivers from receiving interrupts and call the "noirq"
- * suspend handlers.
+ * dpm_suspend_noirq - Execute "late suspend" callbacks for non-sysdev devices.
+ * @state: PM transition of the system being carried out.
*
*
- * Must be called under dpm_list_mtx.
+ * Prevent device drivers from receiving interrupts and call the "noirq" suspend
+ * handlers for all non-sysdev devices.
*/
int dpm_suspend_noirq(pm_message_t state)
{
*/
int dpm_suspend_noirq(pm_message_t state)
{
@@
-611,9
+623,9
@@
int dpm_suspend_noirq(pm_message_t state)
EXPORT_SYMBOL_GPL(dpm_suspend_noirq);
/**
EXPORT_SYMBOL_GPL(dpm_suspend_noirq);
/**
- *
device_suspend - Save state of one
device.
- *
@dev: Devic
e.
- *
@state: PM transition of the system being carried out.
+ *
device_suspend - Execute "suspend" callbacks for given
device.
+ *
@dev: Device to handl
e.
+ * @state: PM transition of the system being carried out.
*/
static int device_suspend(struct device *dev, pm_message_t state)
{
*/
static int device_suspend(struct device *dev, pm_message_t state)
{
@@
-660,10
+672,8
@@
static int device_suspend(struct device *dev, pm_message_t state)
}
/**
}
/**
- * dpm_suspend - Suspend every device.
- * @state: PM transition of the system being carried out.
- *
- * Execute the appropriate "suspend" callbacks for all devices.
+ * dpm_suspend - Execute "suspend" callbacks for all non-sysdev devices.
+ * @state: PM transition of the system being carried out.
*/
static int dpm_suspend(pm_message_t state)
{
*/
static int dpm_suspend(pm_message_t state)
{
@@
-697,9
+707,12
@@
static int dpm_suspend(pm_message_t state)
}
/**
}
/**
- * device_prepare - Execute the ->prepare() callback(s) for given device.
- * @dev: Device.
- * @state: PM transition of the system being carried out.
+ * device_prepare - Prepare a device for system power transition.
+ * @dev: Device to handle.
+ * @state: PM transition of the system being carried out.
+ *
+ * Execute the ->prepare() callback(s) for given device. No new children of the
+ * device may be registered after this function has returned.
*/
static int device_prepare(struct device *dev, pm_message_t state)
{
*/
static int device_prepare(struct device *dev, pm_message_t state)
{
@@
-735,10
+748,10
@@
static int device_prepare(struct device *dev, pm_message_t state)
}
/**
}
/**
- *
dpm_prepare - Prepare all devices for a
PM transition.
- *
@state: PM transition of the system being carried out.
+ *
dpm_prepare - Prepare all non-sysdev devices for a system
PM transition.
+ * @state: PM transition of the system being carried out.
*
*
- *
Execute the ->prepare() callback
for all devices.
+ *
Execute the ->prepare() callback(s)
for all devices.
*/
static int dpm_prepare(pm_message_t state)
{
*/
static int dpm_prepare(pm_message_t state)
{
@@
-755,7
+768,14
@@
static int dpm_prepare(pm_message_t state)
dev->power.status = DPM_PREPARING;
mutex_unlock(&dpm_list_mtx);
dev->power.status = DPM_PREPARING;
mutex_unlock(&dpm_list_mtx);
- error = device_prepare(dev, state);
+ pm_runtime_get_noresume(dev);
+ if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) {
+ /* Wake-up requested during system sleep transition. */
+ pm_runtime_put_noidle(dev);
+ error = -EBUSY;
+ } else {
+ error = device_prepare(dev, state);
+ }
mutex_lock(&dpm_list_mtx);
if (error) {
mutex_lock(&dpm_list_mtx);
if (error) {
@@
-782,10
+802,11
@@
static int dpm_prepare(pm_message_t state)
}
/**
}
/**
- *
dpm_suspend_start - Save state and stop all devices in syst
em.
- *
@state: PM transition of the system being carried out.
+ *
dpm_suspend_start - Prepare devices for PM transition and suspend th
em.
+ * @state: PM transition of the system being carried out.
*
*
- * Prepare and suspend all devices.
+ * Prepare all non-sysdev devices for system PM transition and execute "suspend"
+ * callbacks for them.
*/
int dpm_suspend_start(pm_message_t state)
{
*/
int dpm_suspend_start(pm_message_t state)
{