Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/rafael/suspend-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspend-2.6:
  PCI PM: Make pci_prepare_to_sleep() disable wake-up if needed
  radeonfb: Use __pci_complete_power_transition()
  PCI PM: Introduce __pci_[start|complete]_power_transition() (rev. 2)
  PCI PM: Restore config spaces of all devices during early resume
  PCI PM: Make pci_set_power_state() handle devices with no PM support
  PCI PM: Put devices into low power states during late suspend (rev. 2)
  PCI PM: Move pci_restore_standard_config to pci-driver.c
  PCI PM: Use pci_set_power_state during early resume
  PCI PM: Consistently use variable name "error" for pm call return values
  kexec: Change kexec jump code ordering
  PM: Change hibernation code ordering
  PM: Change suspend code ordering
  PM: Rework handling of interrupts during suspend-resume
  PM: Introduce functions for suspending and resuming device interrupts
  • Loading branch information
Linus Torvalds committed Mar 30, 2009
2 parents 93c36ed + 8efb8c7 commit 53d8f67
Show file tree
Hide file tree
Showing 18 changed files with 461 additions and 256 deletions.
15 changes: 11 additions & 4 deletions arch/x86/kernel/apm_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -1190,8 +1190,10 @@ static int suspend(int vetoable)
struct apm_user *as;

device_suspend(PMSG_SUSPEND);
local_irq_disable();

device_power_down(PMSG_SUSPEND);

local_irq_disable();
sysdev_suspend(PMSG_SUSPEND);

local_irq_enable();
Expand All @@ -1209,9 +1211,12 @@ static int suspend(int vetoable)
if (err != APM_SUCCESS)
apm_error("suspend", err);
err = (err == APM_SUCCESS) ? 0 : -EIO;

sysdev_resume();
device_power_up(PMSG_RESUME);
local_irq_enable();

device_power_up(PMSG_RESUME);

device_resume(PMSG_RESUME);
queue_event(APM_NORMAL_RESUME, NULL);
spin_lock(&user_list_lock);
Expand All @@ -1228,8 +1233,9 @@ static void standby(void)
{
int err;

local_irq_disable();
device_power_down(PMSG_SUSPEND);

local_irq_disable();
sysdev_suspend(PMSG_SUSPEND);
local_irq_enable();

Expand All @@ -1239,8 +1245,9 @@ static void standby(void)

local_irq_disable();
sysdev_resume();
device_power_up(PMSG_RESUME);
local_irq_enable();

device_power_up(PMSG_RESUME);
}

static apm_event_t get_event(void)
Expand Down
20 changes: 11 additions & 9 deletions drivers/base/power/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <linux/pm.h>
#include <linux/resume-trace.h>
#include <linux/rwsem.h>
#include <linux/interrupt.h>

#include "../base.h"
#include "power.h"
Expand Down Expand Up @@ -349,7 +350,8 @@ static int resume_device_noirq(struct device *dev, pm_message_t state)
* Execute the appropriate "noirq resume" callback for all devices marked
* as DPM_OFF_IRQ.
*
* Must be called with interrupts disabled and only one CPU running.
* Must be called under dpm_list_mtx. Device drivers should not receive
* interrupts while it's being executed.
*/
static void dpm_power_up(pm_message_t state)
{
Expand All @@ -370,14 +372,13 @@ static void dpm_power_up(pm_message_t state)
* device_power_up - Turn on all devices that need special attention.
* @state: PM transition of the system being carried out.
*
* Power on system devices, then devices that required we shut them down
* with interrupts disabled.
*
* Must be called with interrupts disabled.
* Call the "early" resume handlers and enable device drivers to receive
* interrupts.
*/
void device_power_up(pm_message_t state)
{
dpm_power_up(state);
resume_device_irqs();
}
EXPORT_SYMBOL_GPL(device_power_up);

Expand Down Expand Up @@ -602,16 +603,17 @@ static int suspend_device_noirq(struct device *dev, pm_message_t state)
* device_power_down - Shut down special devices.
* @state: PM transition of the system being carried out.
*
* Power down devices that require interrupts to be disabled.
* Then power down system devices.
* Prevent device drivers from receiving interrupts and call the "late"
* suspend handlers.
*
* Must be called with interrupts disabled and only one CPU running.
* Must be called under dpm_list_mtx.
*/
int device_power_down(pm_message_t state)
{
struct device *dev;
int error = 0;

suspend_device_irqs();
list_for_each_entry_reverse(dev, &dpm_list, power.entry) {
error = suspend_device_noirq(dev, state);
if (error) {
Expand All @@ -621,7 +623,7 @@ int device_power_down(pm_message_t state)
dev->power.status = DPM_OFF_IRQ;
}
if (error)
dpm_power_up(resume_event(state));
device_power_up(resume_event(state));
return error;
}
EXPORT_SYMBOL_GPL(device_power_down);
Expand Down
8 changes: 8 additions & 0 deletions drivers/base/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <linux/pm.h>
#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/interrupt.h>

#include "base.h"

Expand Down Expand Up @@ -369,6 +370,13 @@ int sysdev_suspend(pm_message_t state)
struct sysdev_driver *drv, *err_drv;
int ret;

pr_debug("Checking wake-up interrupts\n");

/* Return error code if there are any wake-up interrupts pending */
ret = check_wakeup_irqs();
if (ret)
return ret;

pr_debug("Suspending System Devices\n");

list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) {
Expand Down
Loading

0 comments on commit 53d8f67

Please sign in to comment.