aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/power/main.c20
-rw-r--r--drivers/base/sys.c8
2 files changed, 19 insertions, 9 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index e255341682c8..69b4ddb7de3b 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -23,6 +23,7 @@
23#include <linux/pm.h> 23#include <linux/pm.h>
24#include <linux/resume-trace.h> 24#include <linux/resume-trace.h>
25#include <linux/rwsem.h> 25#include <linux/rwsem.h>
26#include <linux/interrupt.h>
26 27
27#include "../base.h" 28#include "../base.h"
28#include "power.h" 29#include "power.h"
@@ -349,7 +350,8 @@ static int resume_device_noirq(struct device *dev, pm_message_t state)
349 * Execute the appropriate "noirq resume" callback for all devices marked 350 * Execute the appropriate "noirq resume" callback for all devices marked
350 * as DPM_OFF_IRQ. 351 * as DPM_OFF_IRQ.
351 * 352 *
352 * Must be called with interrupts disabled and only one CPU running. 353 * Must be called under dpm_list_mtx. Device drivers should not receive
354 * interrupts while it's being executed.
353 */ 355 */
354static void dpm_power_up(pm_message_t state) 356static void dpm_power_up(pm_message_t state)
355{ 357{
@@ -370,14 +372,13 @@ static void dpm_power_up(pm_message_t state)
370 * device_power_up - Turn on all devices that need special attention. 372 * device_power_up - Turn on all devices that need special attention.
371 * @state: PM transition of the system being carried out. 373 * @state: PM transition of the system being carried out.
372 * 374 *
373 * Power on system devices, then devices that required we shut them down 375 * Call the "early" resume handlers and enable device drivers to receive
374 * with interrupts disabled. 376 * interrupts.
375 *
376 * Must be called with interrupts disabled.
377 */ 377 */
378void device_power_up(pm_message_t state) 378void device_power_up(pm_message_t state)
379{ 379{
380 dpm_power_up(state); 380 dpm_power_up(state);
381 resume_device_irqs();
381} 382}
382EXPORT_SYMBOL_GPL(device_power_up); 383EXPORT_SYMBOL_GPL(device_power_up);
383 384
@@ -602,16 +603,17 @@ static int suspend_device_noirq(struct device *dev, pm_message_t state)
602 * device_power_down - Shut down special devices. 603 * device_power_down - Shut down special devices.
603 * @state: PM transition of the system being carried out. 604 * @state: PM transition of the system being carried out.
604 * 605 *
605 * Power down devices that require interrupts to be disabled. 606 * Prevent device drivers from receiving interrupts and call the "late"
606 * Then power down system devices. 607 * suspend handlers.
607 * 608 *
608 * Must be called with interrupts disabled and only one CPU running. 609 * Must be called under dpm_list_mtx.
609 */ 610 */
610int device_power_down(pm_message_t state) 611int device_power_down(pm_message_t state)
611{ 612{
612 struct device *dev; 613 struct device *dev;
613 int error = 0; 614 int error = 0;
614 615
616 suspend_device_irqs();
615 list_for_each_entry_reverse(dev, &dpm_list, power.entry) { 617 list_for_each_entry_reverse(dev, &dpm_list, power.entry) {
616 error = suspend_device_noirq(dev, state); 618 error = suspend_device_noirq(dev, state);
617 if (error) { 619 if (error) {
@@ -621,7 +623,7 @@ int device_power_down(pm_message_t state)
621 dev->power.status = DPM_OFF_IRQ; 623 dev->power.status = DPM_OFF_IRQ;
622 } 624 }
623 if (error) 625 if (error)
624 dpm_power_up(resume_event(state)); 626 device_power_up(resume_event(state));
625 return error; 627 return error;
626} 628}
627EXPORT_SYMBOL_GPL(device_power_down); 629EXPORT_SYMBOL_GPL(device_power_down);
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
index cbd36cf59a0f..76ce75bad91e 100644
--- a/drivers/base/sys.c
+++ b/drivers/base/sys.c
@@ -22,6 +22,7 @@
22#include <linux/pm.h> 22#include <linux/pm.h>
23#include <linux/device.h> 23#include <linux/device.h>
24#include <linux/mutex.h> 24#include <linux/mutex.h>
25#include <linux/interrupt.h>
25 26
26#include "base.h" 27#include "base.h"
27 28
@@ -369,6 +370,13 @@ int sysdev_suspend(pm_message_t state)
369 struct sysdev_driver *drv, *err_drv; 370 struct sysdev_driver *drv, *err_drv;
370 int ret; 371 int ret;
371 372
373 pr_debug("Checking wake-up interrupts\n");
374
375 /* Return error code if there are any wake-up interrupts pending */
376 ret = check_wakeup_irqs();
377 if (ret)
378 return ret;
379
372 pr_debug("Suspending System Devices\n"); 380 pr_debug("Suspending System Devices\n");
373 381
374 list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) { 382 list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) {