aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-03-30 18:12:14 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-03-30 18:12:14 -0400
commit53d8f67082c9b86699dd88b7f9e667e245193f21 (patch)
tree0e888713ee7a1a53b05852839aeb724fabe80490 /drivers
parent93c36ed8348934b462044d2d60ab345055318933 (diff)
parent8efb8c76fcdccf5050c0ea059dac392789baaff2 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/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
Diffstat (limited to 'drivers')
-rw-r--r--drivers/base/power/main.c20
-rw-r--r--drivers/base/sys.c8
-rw-r--r--drivers/pci/pci-driver.c177
-rw-r--r--drivers/pci/pci.c142
-rw-r--r--drivers/pci/pci.h1
-rw-r--r--drivers/video/aty/radeon_pm.c2
-rw-r--r--drivers/xen/manage.c16
7 files changed, 206 insertions, 160 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) {
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 93eac1423585..267de88551c9 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -352,53 +352,60 @@ static int pci_legacy_suspend(struct device *dev, pm_message_t state)
352{ 352{
353 struct pci_dev * pci_dev = to_pci_dev(dev); 353 struct pci_dev * pci_dev = to_pci_dev(dev);
354 struct pci_driver * drv = pci_dev->driver; 354 struct pci_driver * drv = pci_dev->driver;
355 int i = 0; 355
356 pci_dev->state_saved = false;
356 357
357 if (drv && drv->suspend) { 358 if (drv && drv->suspend) {
358 pci_power_t prev = pci_dev->current_state; 359 pci_power_t prev = pci_dev->current_state;
360 int error;
359 361
360 pci_dev->state_saved = false; 362 error = drv->suspend(pci_dev, state);
361 363 suspend_report_result(drv->suspend, error);
362 i = drv->suspend(pci_dev, state); 364 if (error)
363 suspend_report_result(drv->suspend, i); 365 return error;
364 if (i)
365 return i;
366
367 if (pci_dev->state_saved)
368 goto Fixup;
369 366
370 if (pci_dev->current_state != PCI_D0 367 if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
371 && pci_dev->current_state != PCI_UNKNOWN) { 368 && pci_dev->current_state != PCI_UNKNOWN) {
372 WARN_ONCE(pci_dev->current_state != prev, 369 WARN_ONCE(pci_dev->current_state != prev,
373 "PCI PM: Device state not saved by %pF\n", 370 "PCI PM: Device state not saved by %pF\n",
374 drv->suspend); 371 drv->suspend);
375 goto Fixup;
376 } 372 }
377 } 373 }
378 374
379 pci_save_state(pci_dev);
380 /*
381 * This is for compatibility with existing code with legacy PM support.
382 */
383 pci_pm_set_unknown_state(pci_dev);
384
385 Fixup:
386 pci_fixup_device(pci_fixup_suspend, pci_dev); 375 pci_fixup_device(pci_fixup_suspend, pci_dev);
387 376
388 return i; 377 return 0;
389} 378}
390 379
391static int pci_legacy_suspend_late(struct device *dev, pm_message_t state) 380static int pci_legacy_suspend_late(struct device *dev, pm_message_t state)
392{ 381{
393 struct pci_dev * pci_dev = to_pci_dev(dev); 382 struct pci_dev * pci_dev = to_pci_dev(dev);
394 struct pci_driver * drv = pci_dev->driver; 383 struct pci_driver * drv = pci_dev->driver;
395 int i = 0;
396 384
397 if (drv && drv->suspend_late) { 385 if (drv && drv->suspend_late) {
398 i = drv->suspend_late(pci_dev, state); 386 pci_power_t prev = pci_dev->current_state;
399 suspend_report_result(drv->suspend_late, i); 387 int error;
388
389 error = drv->suspend_late(pci_dev, state);
390 suspend_report_result(drv->suspend_late, error);
391 if (error)
392 return error;
393
394 if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
395 && pci_dev->current_state != PCI_UNKNOWN) {
396 WARN_ONCE(pci_dev->current_state != prev,
397 "PCI PM: Device state not saved by %pF\n",
398 drv->suspend_late);
399 return 0;
400 }
400 } 401 }
401 return i; 402
403 if (!pci_dev->state_saved)
404 pci_save_state(pci_dev);
405
406 pci_pm_set_unknown_state(pci_dev);
407
408 return 0;
402} 409}
403 410
404static int pci_legacy_resume_early(struct device *dev) 411static int pci_legacy_resume_early(struct device *dev)
@@ -423,6 +430,23 @@ static int pci_legacy_resume(struct device *dev)
423 430
424/* Auxiliary functions used by the new power management framework */ 431/* Auxiliary functions used by the new power management framework */
425 432
433/**
434 * pci_restore_standard_config - restore standard config registers of PCI device
435 * @pci_dev: PCI device to handle
436 */
437static int pci_restore_standard_config(struct pci_dev *pci_dev)
438{
439 pci_update_current_state(pci_dev, PCI_UNKNOWN);
440
441 if (pci_dev->current_state != PCI_D0) {
442 int error = pci_set_power_state(pci_dev, PCI_D0);
443 if (error)
444 return error;
445 }
446
447 return pci_dev->state_saved ? pci_restore_state(pci_dev) : 0;
448}
449
426static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev) 450static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev)
427{ 451{
428 pci_restore_standard_config(pci_dev); 452 pci_restore_standard_config(pci_dev);
@@ -443,7 +467,6 @@ static void pci_pm_default_suspend(struct pci_dev *pci_dev)
443 /* Disable non-bridge devices without PM support */ 467 /* Disable non-bridge devices without PM support */
444 if (!pci_is_bridge(pci_dev)) 468 if (!pci_is_bridge(pci_dev))
445 pci_disable_enabled_device(pci_dev); 469 pci_disable_enabled_device(pci_dev);
446 pci_save_state(pci_dev);
447} 470}
448 471
449static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev) 472static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev)
@@ -493,13 +516,13 @@ static int pci_pm_suspend(struct device *dev)
493 if (pci_has_legacy_pm_support(pci_dev)) 516 if (pci_has_legacy_pm_support(pci_dev))
494 return pci_legacy_suspend(dev, PMSG_SUSPEND); 517 return pci_legacy_suspend(dev, PMSG_SUSPEND);
495 518
519 pci_dev->state_saved = false;
520
496 if (!pm) { 521 if (!pm) {
497 pci_pm_default_suspend(pci_dev); 522 pci_pm_default_suspend(pci_dev);
498 goto Fixup; 523 goto Fixup;
499 } 524 }
500 525
501 pci_dev->state_saved = false;
502
503 if (pm->suspend) { 526 if (pm->suspend) {
504 pci_power_t prev = pci_dev->current_state; 527 pci_power_t prev = pci_dev->current_state;
505 int error; 528 int error;
@@ -509,24 +532,14 @@ static int pci_pm_suspend(struct device *dev)
509 if (error) 532 if (error)
510 return error; 533 return error;
511 534
512 if (pci_dev->state_saved) 535 if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
513 goto Fixup;
514
515 if (pci_dev->current_state != PCI_D0
516 && pci_dev->current_state != PCI_UNKNOWN) { 536 && pci_dev->current_state != PCI_UNKNOWN) {
517 WARN_ONCE(pci_dev->current_state != prev, 537 WARN_ONCE(pci_dev->current_state != prev,
518 "PCI PM: State of device not saved by %pF\n", 538 "PCI PM: State of device not saved by %pF\n",
519 pm->suspend); 539 pm->suspend);
520 goto Fixup;
521 } 540 }
522 } 541 }
523 542
524 if (!pci_dev->state_saved) {
525 pci_save_state(pci_dev);
526 if (!pci_is_bridge(pci_dev))
527 pci_prepare_to_sleep(pci_dev);
528 }
529
530 Fixup: 543 Fixup:
531 pci_fixup_device(pci_fixup_suspend, pci_dev); 544 pci_fixup_device(pci_fixup_suspend, pci_dev);
532 545
@@ -536,21 +549,43 @@ static int pci_pm_suspend(struct device *dev)
536static int pci_pm_suspend_noirq(struct device *dev) 549static int pci_pm_suspend_noirq(struct device *dev)
537{ 550{
538 struct pci_dev *pci_dev = to_pci_dev(dev); 551 struct pci_dev *pci_dev = to_pci_dev(dev);
539 struct device_driver *drv = dev->driver; 552 struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
540 int error = 0;
541 553
542 if (pci_has_legacy_pm_support(pci_dev)) 554 if (pci_has_legacy_pm_support(pci_dev))
543 return pci_legacy_suspend_late(dev, PMSG_SUSPEND); 555 return pci_legacy_suspend_late(dev, PMSG_SUSPEND);
544 556
545 if (drv && drv->pm && drv->pm->suspend_noirq) { 557 if (!pm) {
546 error = drv->pm->suspend_noirq(dev); 558 pci_save_state(pci_dev);
547 suspend_report_result(drv->pm->suspend_noirq, error); 559 return 0;
548 } 560 }
549 561
550 if (!error) 562 if (pm->suspend_noirq) {
551 pci_pm_set_unknown_state(pci_dev); 563 pci_power_t prev = pci_dev->current_state;
564 int error;
552 565
553 return error; 566 error = pm->suspend_noirq(dev);
567 suspend_report_result(pm->suspend_noirq, error);
568 if (error)
569 return error;
570
571 if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
572 && pci_dev->current_state != PCI_UNKNOWN) {
573 WARN_ONCE(pci_dev->current_state != prev,
574 "PCI PM: State of device not saved by %pF\n",
575 pm->suspend_noirq);
576 return 0;
577 }
578 }
579
580 if (!pci_dev->state_saved) {
581 pci_save_state(pci_dev);
582 if (!pci_is_bridge(pci_dev))
583 pci_prepare_to_sleep(pci_dev);
584 }
585
586 pci_pm_set_unknown_state(pci_dev);
587
588 return 0;
554} 589}
555 590
556static int pci_pm_resume_noirq(struct device *dev) 591static int pci_pm_resume_noirq(struct device *dev)
@@ -617,13 +652,13 @@ static int pci_pm_freeze(struct device *dev)
617 if (pci_has_legacy_pm_support(pci_dev)) 652 if (pci_has_legacy_pm_support(pci_dev))
618 return pci_legacy_suspend(dev, PMSG_FREEZE); 653 return pci_legacy_suspend(dev, PMSG_FREEZE);
619 654
655 pci_dev->state_saved = false;
656
620 if (!pm) { 657 if (!pm) {
621 pci_pm_default_suspend(pci_dev); 658 pci_pm_default_suspend(pci_dev);
622 return 0; 659 return 0;
623 } 660 }
624 661
625 pci_dev->state_saved = false;
626
627 if (pm->freeze) { 662 if (pm->freeze) {
628 int error; 663 int error;
629 664
@@ -633,9 +668,6 @@ static int pci_pm_freeze(struct device *dev)
633 return error; 668 return error;
634 } 669 }
635 670
636 if (!pci_dev->state_saved)
637 pci_save_state(pci_dev);
638
639 return 0; 671 return 0;
640} 672}
641 673
@@ -643,20 +675,25 @@ static int pci_pm_freeze_noirq(struct device *dev)
643{ 675{
644 struct pci_dev *pci_dev = to_pci_dev(dev); 676 struct pci_dev *pci_dev = to_pci_dev(dev);
645 struct device_driver *drv = dev->driver; 677 struct device_driver *drv = dev->driver;
646 int error = 0;
647 678
648 if (pci_has_legacy_pm_support(pci_dev)) 679 if (pci_has_legacy_pm_support(pci_dev))
649 return pci_legacy_suspend_late(dev, PMSG_FREEZE); 680 return pci_legacy_suspend_late(dev, PMSG_FREEZE);
650 681
651 if (drv && drv->pm && drv->pm->freeze_noirq) { 682 if (drv && drv->pm && drv->pm->freeze_noirq) {
683 int error;
684
652 error = drv->pm->freeze_noirq(dev); 685 error = drv->pm->freeze_noirq(dev);
653 suspend_report_result(drv->pm->freeze_noirq, error); 686 suspend_report_result(drv->pm->freeze_noirq, error);
687 if (error)
688 return error;
654 } 689 }
655 690
656 if (!error) 691 if (!pci_dev->state_saved)
657 pci_pm_set_unknown_state(pci_dev); 692 pci_save_state(pci_dev);
658 693
659 return error; 694 pci_pm_set_unknown_state(pci_dev);
695
696 return 0;
660} 697}
661 698
662static int pci_pm_thaw_noirq(struct device *dev) 699static int pci_pm_thaw_noirq(struct device *dev)
@@ -699,46 +736,56 @@ static int pci_pm_poweroff(struct device *dev)
699{ 736{
700 struct pci_dev *pci_dev = to_pci_dev(dev); 737 struct pci_dev *pci_dev = to_pci_dev(dev);
701 struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 738 struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
702 int error = 0;
703 739
704 if (pci_has_legacy_pm_support(pci_dev)) 740 if (pci_has_legacy_pm_support(pci_dev))
705 return pci_legacy_suspend(dev, PMSG_HIBERNATE); 741 return pci_legacy_suspend(dev, PMSG_HIBERNATE);
706 742
743 pci_dev->state_saved = false;
744
707 if (!pm) { 745 if (!pm) {
708 pci_pm_default_suspend(pci_dev); 746 pci_pm_default_suspend(pci_dev);
709 goto Fixup; 747 goto Fixup;
710 } 748 }
711 749
712 pci_dev->state_saved = false;
713
714 if (pm->poweroff) { 750 if (pm->poweroff) {
751 int error;
752
715 error = pm->poweroff(dev); 753 error = pm->poweroff(dev);
716 suspend_report_result(pm->poweroff, error); 754 suspend_report_result(pm->poweroff, error);
755 if (error)
756 return error;
717 } 757 }
718 758
719 if (!pci_dev->state_saved && !pci_is_bridge(pci_dev))
720 pci_prepare_to_sleep(pci_dev);
721
722 Fixup: 759 Fixup:
723 pci_fixup_device(pci_fixup_suspend, pci_dev); 760 pci_fixup_device(pci_fixup_suspend, pci_dev);
724 761
725 return error; 762 return 0;
726} 763}
727 764
728static int pci_pm_poweroff_noirq(struct device *dev) 765static int pci_pm_poweroff_noirq(struct device *dev)
729{ 766{
767 struct pci_dev *pci_dev = to_pci_dev(dev);
730 struct device_driver *drv = dev->driver; 768 struct device_driver *drv = dev->driver;
731 int error = 0;
732 769
733 if (pci_has_legacy_pm_support(to_pci_dev(dev))) 770 if (pci_has_legacy_pm_support(to_pci_dev(dev)))
734 return pci_legacy_suspend_late(dev, PMSG_HIBERNATE); 771 return pci_legacy_suspend_late(dev, PMSG_HIBERNATE);
735 772
736 if (drv && drv->pm && drv->pm->poweroff_noirq) { 773 if (!drv || !drv->pm)
774 return 0;
775
776 if (drv->pm->poweroff_noirq) {
777 int error;
778
737 error = drv->pm->poweroff_noirq(dev); 779 error = drv->pm->poweroff_noirq(dev);
738 suspend_report_result(drv->pm->poweroff_noirq, error); 780 suspend_report_result(drv->pm->poweroff_noirq, error);
781 if (error)
782 return error;
739 } 783 }
740 784
741 return error; 785 if (!pci_dev->state_saved && !pci_is_bridge(pci_dev))
786 pci_prepare_to_sleep(pci_dev);
787
788 return 0;
742} 789}
743 790
744static int pci_pm_restore_noirq(struct device *dev) 791static int pci_pm_restore_noirq(struct device *dev)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 6d6120007af4..0195066251e5 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -426,7 +426,6 @@ static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable)
426 * given PCI device 426 * given PCI device
427 * @dev: PCI device to handle. 427 * @dev: PCI device to handle.
428 * @state: PCI power state (D0, D1, D2, D3hot) to put the device into. 428 * @state: PCI power state (D0, D1, D2, D3hot) to put the device into.
429 * @wait: If 'true', wait for the device to change its power state
430 * 429 *
431 * RETURN VALUE: 430 * RETURN VALUE:
432 * -EINVAL if the requested state is invalid. 431 * -EINVAL if the requested state is invalid.
@@ -435,12 +434,15 @@ static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable)
435 * 0 if device already is in the requested state. 434 * 0 if device already is in the requested state.
436 * 0 if device's power state has been successfully changed. 435 * 0 if device's power state has been successfully changed.
437 */ 436 */
438static int 437static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state)
439pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state, bool wait)
440{ 438{
441 u16 pmcsr; 439 u16 pmcsr;
442 bool need_restore = false; 440 bool need_restore = false;
443 441
442 /* Check if we're already there */
443 if (dev->current_state == state)
444 return 0;
445
444 if (!dev->pm_cap) 446 if (!dev->pm_cap)
445 return -EIO; 447 return -EIO;
446 448
@@ -451,10 +453,7 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state, bool wait)
451 * Can enter D0 from any state, but if we can only go deeper 453 * Can enter D0 from any state, but if we can only go deeper
452 * to sleep if we're already in a low power state 454 * to sleep if we're already in a low power state
453 */ 455 */
454 if (dev->current_state == state) { 456 if (state != PCI_D0 && dev->current_state <= PCI_D3cold
455 /* we're already there */
456 return 0;
457 } else if (state != PCI_D0 && dev->current_state <= PCI_D3cold
458 && dev->current_state > state) { 457 && dev->current_state > state) {
459 dev_err(&dev->dev, "invalid power transition " 458 dev_err(&dev->dev, "invalid power transition "
460 "(from state %d to %d)\n", dev->current_state, state); 459 "(from state %d to %d)\n", dev->current_state, state);
@@ -481,10 +480,8 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state, bool wait)
481 break; 480 break;
482 case PCI_UNKNOWN: /* Boot-up */ 481 case PCI_UNKNOWN: /* Boot-up */
483 if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot 482 if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot
484 && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET)) { 483 && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET))
485 need_restore = true; 484 need_restore = true;
486 wait = true;
487 }
488 /* Fall-through: force to D0 */ 485 /* Fall-through: force to D0 */
489 default: 486 default:
490 pmcsr = 0; 487 pmcsr = 0;
@@ -494,9 +491,6 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state, bool wait)
494 /* enter specified state */ 491 /* enter specified state */
495 pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr); 492 pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr);
496 493
497 if (!wait)
498 return 0;
499
500 /* Mandatory power management transition delays */ 494 /* Mandatory power management transition delays */
501 /* see PCI PM 1.1 5.6.1 table 18 */ 495 /* see PCI PM 1.1 5.6.1 table 18 */
502 if (state == PCI_D3hot || dev->current_state == PCI_D3hot) 496 if (state == PCI_D3hot || dev->current_state == PCI_D3hot)
@@ -521,7 +515,7 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state, bool wait)
521 if (need_restore) 515 if (need_restore)
522 pci_restore_bars(dev); 516 pci_restore_bars(dev);
523 517
524 if (wait && dev->bus->self) 518 if (dev->bus->self)
525 pcie_aspm_pm_state_change(dev->bus->self); 519 pcie_aspm_pm_state_change(dev->bus->self);
526 520
527 return 0; 521 return 0;
@@ -546,6 +540,53 @@ void pci_update_current_state(struct pci_dev *dev, pci_power_t state)
546} 540}
547 541
548/** 542/**
543 * pci_platform_power_transition - Use platform to change device power state
544 * @dev: PCI device to handle.
545 * @state: State to put the device into.
546 */
547static int pci_platform_power_transition(struct pci_dev *dev, pci_power_t state)
548{
549 int error;
550
551 if (platform_pci_power_manageable(dev)) {
552 error = platform_pci_set_power_state(dev, state);
553 if (!error)
554 pci_update_current_state(dev, state);
555 } else {
556 error = -ENODEV;
557 /* Fall back to PCI_D0 if native PM is not supported */
558 pci_update_current_state(dev, PCI_D0);
559 }
560
561 return error;
562}
563
564/**
565 * __pci_start_power_transition - Start power transition of a PCI device
566 * @dev: PCI device to handle.
567 * @state: State to put the device into.
568 */
569static void __pci_start_power_transition(struct pci_dev *dev, pci_power_t state)
570{
571 if (state == PCI_D0)
572 pci_platform_power_transition(dev, PCI_D0);
573}
574
575/**
576 * __pci_complete_power_transition - Complete power transition of a PCI device
577 * @dev: PCI device to handle.
578 * @state: State to put the device into.
579 *
580 * This function should not be called directly by device drivers.
581 */
582int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state)
583{
584 return state > PCI_D0 ?
585 pci_platform_power_transition(dev, state) : -EINVAL;
586}
587EXPORT_SYMBOL_GPL(__pci_complete_power_transition);
588
589/**
549 * pci_set_power_state - Set the power state of a PCI device 590 * pci_set_power_state - Set the power state of a PCI device
550 * @dev: PCI device to handle. 591 * @dev: PCI device to handle.
551 * @state: PCI power state (D0, D1, D2, D3hot) to put the device into. 592 * @state: PCI power state (D0, D1, D2, D3hot) to put the device into.
@@ -577,30 +618,21 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state)
577 */ 618 */
578 return 0; 619 return 0;
579 620
580 if (state == PCI_D0 && platform_pci_power_manageable(dev)) { 621 /* Check if we're already there */
581 /* 622 if (dev->current_state == state)
582 * Allow the platform to change the state, for example via ACPI 623 return 0;
583 * _PR0, _PS0 and some such, but do not trust it. 624
584 */ 625 __pci_start_power_transition(dev, state);
585 int ret = platform_pci_set_power_state(dev, PCI_D0); 626
586 if (!ret)
587 pci_update_current_state(dev, PCI_D0);
588 }
589 /* This device is quirked not to be put into D3, so 627 /* This device is quirked not to be put into D3, so
590 don't put it in D3 */ 628 don't put it in D3 */
591 if (state == PCI_D3hot && (dev->dev_flags & PCI_DEV_FLAGS_NO_D3)) 629 if (state == PCI_D3hot && (dev->dev_flags & PCI_DEV_FLAGS_NO_D3))
592 return 0; 630 return 0;
593 631
594 error = pci_raw_set_power_state(dev, state, true); 632 error = pci_raw_set_power_state(dev, state);
595 633
596 if (state > PCI_D0 && platform_pci_power_manageable(dev)) { 634 if (!__pci_complete_power_transition(dev, state))
597 /* Allow the platform to finalize the transition */ 635 error = 0;
598 int ret = platform_pci_set_power_state(dev, state);
599 if (!ret) {
600 pci_update_current_state(dev, state);
601 error = 0;
602 }
603 }
604 636
605 return error; 637 return error;
606} 638}
@@ -1231,7 +1263,7 @@ int pci_prepare_to_sleep(struct pci_dev *dev)
1231 if (target_state == PCI_POWER_ERROR) 1263 if (target_state == PCI_POWER_ERROR)
1232 return -EIO; 1264 return -EIO;
1233 1265
1234 pci_enable_wake(dev, target_state, true); 1266 pci_enable_wake(dev, target_state, device_may_wakeup(&dev->dev));
1235 1267
1236 error = pci_set_power_state(dev, target_state); 1268 error = pci_set_power_state(dev, target_state);
1237 1269
@@ -1381,50 +1413,6 @@ void pci_allocate_cap_save_buffers(struct pci_dev *dev)
1381} 1413}
1382 1414
1383/** 1415/**
1384 * pci_restore_standard_config - restore standard config registers of PCI device
1385 * @dev: PCI device to handle
1386 *
1387 * This function assumes that the device's configuration space is accessible.
1388 * If the device needs to be powered up, the function will wait for it to
1389 * change the state.
1390 */
1391int pci_restore_standard_config(struct pci_dev *dev)
1392{
1393 pci_power_t prev_state;
1394 int error;
1395
1396 pci_update_current_state(dev, PCI_D0);
1397
1398 prev_state = dev->current_state;
1399 if (prev_state == PCI_D0)
1400 goto Restore;
1401
1402 error = pci_raw_set_power_state(dev, PCI_D0, false);
1403 if (error)
1404 return error;
1405
1406 /*
1407 * This assumes that we won't get a bus in B2 or B3 from the BIOS, but
1408 * we've made this assumption forever and it appears to be universally
1409 * satisfied.
1410 */
1411 switch(prev_state) {
1412 case PCI_D3cold:
1413 case PCI_D3hot:
1414 mdelay(pci_pm_d3_delay);
1415 break;
1416 case PCI_D2:
1417 udelay(PCI_PM_D2_DELAY);
1418 break;
1419 }
1420
1421 pci_update_current_state(dev, PCI_D0);
1422
1423 Restore:
1424 return dev->state_saved ? pci_restore_state(dev) : 0;
1425}
1426
1427/**
1428 * pci_enable_ari - enable ARI forwarding if hardware support it 1416 * pci_enable_ari - enable ARI forwarding if hardware support it
1429 * @dev: the PCI device 1417 * @dev: the PCI device
1430 */ 1418 */
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 07c0aa5275e6..149fff65891f 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -49,7 +49,6 @@ extern void pci_disable_enabled_device(struct pci_dev *dev);
49extern void pci_pm_init(struct pci_dev *dev); 49extern void pci_pm_init(struct pci_dev *dev);
50extern void platform_pci_wakeup_init(struct pci_dev *dev); 50extern void platform_pci_wakeup_init(struct pci_dev *dev);
51extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); 51extern void pci_allocate_cap_save_buffers(struct pci_dev *dev);
52extern int pci_restore_standard_config(struct pci_dev *dev);
53 52
54static inline bool pci_is_bridge(struct pci_dev *pci_dev) 53static inline bool pci_is_bridge(struct pci_dev *pci_dev)
55{ 54{
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c
index c6d7cc76516f..1de0c0032468 100644
--- a/drivers/video/aty/radeon_pm.c
+++ b/drivers/video/aty/radeon_pm.c
@@ -2582,7 +2582,7 @@ static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
2582 * calling pci_set_power_state() 2582 * calling pci_set_power_state()
2583 */ 2583 */
2584 radeonfb_whack_power_state(rinfo, PCI_D2); 2584 radeonfb_whack_power_state(rinfo, PCI_D2);
2585 pci_set_power_state(rinfo->pdev, PCI_D2); 2585 __pci_complete_power_transition(rinfo->pdev, PCI_D2);
2586 } else { 2586 } else {
2587 printk(KERN_DEBUG "radeonfb (%s): switching to D0 state...\n", 2587 printk(KERN_DEBUG "radeonfb (%s): switching to D0 state...\n",
2588 pci_name(rinfo->pdev)); 2588 pci_name(rinfo->pdev));
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index 3ccd348d112d..0d61db1e7b49 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -39,12 +39,6 @@ static int xen_suspend(void *data)
39 39
40 BUG_ON(!irqs_disabled()); 40 BUG_ON(!irqs_disabled());
41 41
42 err = device_power_down(PMSG_SUSPEND);
43 if (err) {
44 printk(KERN_ERR "xen_suspend: device_power_down failed: %d\n",
45 err);
46 return err;
47 }
48 err = sysdev_suspend(PMSG_SUSPEND); 42 err = sysdev_suspend(PMSG_SUSPEND);
49 if (err) { 43 if (err) {
50 printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n", 44 printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n",
@@ -69,7 +63,6 @@ static int xen_suspend(void *data)
69 xen_mm_unpin_all(); 63 xen_mm_unpin_all();
70 64
71 sysdev_resume(); 65 sysdev_resume();
72 device_power_up(PMSG_RESUME);
73 66
74 if (!*cancelled) { 67 if (!*cancelled) {
75 xen_irq_resume(); 68 xen_irq_resume();
@@ -108,6 +101,12 @@ static void do_suspend(void)
108 /* XXX use normal device tree? */ 101 /* XXX use normal device tree? */
109 xenbus_suspend(); 102 xenbus_suspend();
110 103
104 err = device_power_down(PMSG_SUSPEND);
105 if (err) {
106 printk(KERN_ERR "device_power_down failed: %d\n", err);
107 goto resume_devices;
108 }
109
111 err = stop_machine(xen_suspend, &cancelled, cpumask_of(0)); 110 err = stop_machine(xen_suspend, &cancelled, cpumask_of(0));
112 if (err) { 111 if (err) {
113 printk(KERN_ERR "failed to start xen_suspend: %d\n", err); 112 printk(KERN_ERR "failed to start xen_suspend: %d\n", err);
@@ -120,6 +119,9 @@ static void do_suspend(void)
120 } else 119 } else
121 xenbus_suspend_cancel(); 120 xenbus_suspend_cancel();
122 121
122 device_power_up(PMSG_RESUME);
123
124resume_devices:
123 device_resume(PMSG_RESUME); 125 device_resume(PMSG_RESUME);
124 126
125 /* Make sure timer events get retriggered on all CPUs */ 127 /* Make sure timer events get retriggered on all CPUs */