aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2008-10-06 16:46:05 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-01-06 13:44:29 -0500
commitadf094931ffb25ef4b381559918f1a34181a5273 (patch)
treebd343d4c15b21dff6a73359fd2d82ff77e30e0d4
parent238c6d54830c624f34ac9cf123ac04aebfca5013 (diff)
PM: Simplify the new suspend/hibernation framework for devices
PM: Simplify the new suspend/hibernation framework for devices Following the discussion at the Kernel Summit, simplify the new device PM framework by merging 'struct pm_ops' and 'struct pm_ext_ops' and removing pointers to 'struct pm_ext_ops' from 'struct platform_driver' and 'struct pci_driver'. After this change, the suspend/hibernation callbacks will only reside in 'struct device_driver' as well as at the bus type/ device class/device type level. Accordingly, PCI and platform device drivers are now expected to put their suspend/hibernation callbacks into the 'struct device_driver' embedded in 'struct pci_driver' or 'struct platform_driver', respectively. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Acked-by: Pavel Machek <pavel@suse.cz> Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/base/platform.c115
-rw-r--r--drivers/base/power/main.c19
-rw-r--r--drivers/pci/pci-driver.c46
-rw-r--r--drivers/usb/core/usb.c4
-rw-r--r--include/linux/device.h8
-rw-r--r--include/linux/pci.h1
-rw-r--r--include/linux/platform_device.h1
-rw-r--r--include/linux/pm.h76
8 files changed, 119 insertions, 151 deletions
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index dfcbfe504867..6c743b6008d9 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -503,8 +503,6 @@ int platform_driver_register(struct platform_driver *drv)
503 drv->driver.suspend = platform_drv_suspend; 503 drv->driver.suspend = platform_drv_suspend;
504 if (drv->resume) 504 if (drv->resume)
505 drv->driver.resume = platform_drv_resume; 505 drv->driver.resume = platform_drv_resume;
506 if (drv->pm)
507 drv->driver.pm = &drv->pm->base;
508 return driver_register(&drv->driver); 506 return driver_register(&drv->driver);
509} 507}
510EXPORT_SYMBOL_GPL(platform_driver_register); 508EXPORT_SYMBOL_GPL(platform_driver_register);
@@ -686,7 +684,10 @@ static int platform_pm_suspend(struct device *dev)
686 struct device_driver *drv = dev->driver; 684 struct device_driver *drv = dev->driver;
687 int ret = 0; 685 int ret = 0;
688 686
689 if (drv && drv->pm) { 687 if (!drv)
688 return 0;
689
690 if (drv->pm) {
690 if (drv->pm->suspend) 691 if (drv->pm->suspend)
691 ret = drv->pm->suspend(dev); 692 ret = drv->pm->suspend(dev);
692 } else { 693 } else {
@@ -698,16 +699,15 @@ static int platform_pm_suspend(struct device *dev)
698 699
699static int platform_pm_suspend_noirq(struct device *dev) 700static int platform_pm_suspend_noirq(struct device *dev)
700{ 701{
701 struct platform_driver *pdrv; 702 struct device_driver *drv = dev->driver;
702 int ret = 0; 703 int ret = 0;
703 704
704 if (!dev->driver) 705 if (!drv)
705 return 0; 706 return 0;
706 707
707 pdrv = to_platform_driver(dev->driver); 708 if (drv->pm) {
708 if (pdrv->pm) { 709 if (drv->pm->suspend_noirq)
709 if (pdrv->pm->suspend_noirq) 710 ret = drv->pm->suspend_noirq(dev);
710 ret = pdrv->pm->suspend_noirq(dev);
711 } else { 711 } else {
712 ret = platform_legacy_suspend_late(dev, PMSG_SUSPEND); 712 ret = platform_legacy_suspend_late(dev, PMSG_SUSPEND);
713 } 713 }
@@ -720,7 +720,10 @@ static int platform_pm_resume(struct device *dev)
720 struct device_driver *drv = dev->driver; 720 struct device_driver *drv = dev->driver;
721 int ret = 0; 721 int ret = 0;
722 722
723 if (drv && drv->pm) { 723 if (!drv)
724 return 0;
725
726 if (drv->pm) {
724 if (drv->pm->resume) 727 if (drv->pm->resume)
725 ret = drv->pm->resume(dev); 728 ret = drv->pm->resume(dev);
726 } else { 729 } else {
@@ -732,16 +735,15 @@ static int platform_pm_resume(struct device *dev)
732 735
733static int platform_pm_resume_noirq(struct device *dev) 736static int platform_pm_resume_noirq(struct device *dev)
734{ 737{
735 struct platform_driver *pdrv; 738 struct device_driver *drv = dev->driver;
736 int ret = 0; 739 int ret = 0;
737 740
738 if (!dev->driver) 741 if (!drv)
739 return 0; 742 return 0;
740 743
741 pdrv = to_platform_driver(dev->driver); 744 if (drv->pm) {
742 if (pdrv->pm) { 745 if (drv->pm->resume_noirq)
743 if (pdrv->pm->resume_noirq) 746 ret = drv->pm->resume_noirq(dev);
744 ret = pdrv->pm->resume_noirq(dev);
745 } else { 747 } else {
746 ret = platform_legacy_resume_early(dev); 748 ret = platform_legacy_resume_early(dev);
747 } 749 }
@@ -780,16 +782,15 @@ static int platform_pm_freeze(struct device *dev)
780 782
781static int platform_pm_freeze_noirq(struct device *dev) 783static int platform_pm_freeze_noirq(struct device *dev)
782{ 784{
783 struct platform_driver *pdrv; 785 struct device_driver *drv = dev->driver;
784 int ret = 0; 786 int ret = 0;
785 787
786 if (!dev->driver) 788 if (!drv)
787 return 0; 789 return 0;
788 790
789 pdrv = to_platform_driver(dev->driver); 791 if (drv->pm) {
790 if (pdrv->pm) { 792 if (drv->pm->freeze_noirq)
791 if (pdrv->pm->freeze_noirq) 793 ret = drv->pm->freeze_noirq(dev);
792 ret = pdrv->pm->freeze_noirq(dev);
793 } else { 794 } else {
794 ret = platform_legacy_suspend_late(dev, PMSG_FREEZE); 795 ret = platform_legacy_suspend_late(dev, PMSG_FREEZE);
795 } 796 }
@@ -802,7 +803,10 @@ static int platform_pm_thaw(struct device *dev)
802 struct device_driver *drv = dev->driver; 803 struct device_driver *drv = dev->driver;
803 int ret = 0; 804 int ret = 0;
804 805
805 if (drv && drv->pm) { 806 if (!drv)
807 return 0;
808
809 if (drv->pm) {
806 if (drv->pm->thaw) 810 if (drv->pm->thaw)
807 ret = drv->pm->thaw(dev); 811 ret = drv->pm->thaw(dev);
808 } else { 812 } else {
@@ -814,16 +818,15 @@ static int platform_pm_thaw(struct device *dev)
814 818
815static int platform_pm_thaw_noirq(struct device *dev) 819static int platform_pm_thaw_noirq(struct device *dev)
816{ 820{
817 struct platform_driver *pdrv; 821 struct device_driver *drv = dev->driver;
818 int ret = 0; 822 int ret = 0;
819 823
820 if (!dev->driver) 824 if (!drv)
821 return 0; 825 return 0;
822 826
823 pdrv = to_platform_driver(dev->driver); 827 if (drv->pm) {
824 if (pdrv->pm) { 828 if (drv->pm->thaw_noirq)
825 if (pdrv->pm->thaw_noirq) 829 ret = drv->pm->thaw_noirq(dev);
826 ret = pdrv->pm->thaw_noirq(dev);
827 } else { 830 } else {
828 ret = platform_legacy_resume_early(dev); 831 ret = platform_legacy_resume_early(dev);
829 } 832 }
@@ -836,7 +839,10 @@ static int platform_pm_poweroff(struct device *dev)
836 struct device_driver *drv = dev->driver; 839 struct device_driver *drv = dev->driver;
837 int ret = 0; 840 int ret = 0;
838 841
839 if (drv && drv->pm) { 842 if (!drv)
843 return 0;
844
845 if (drv->pm) {
840 if (drv->pm->poweroff) 846 if (drv->pm->poweroff)
841 ret = drv->pm->poweroff(dev); 847 ret = drv->pm->poweroff(dev);
842 } else { 848 } else {
@@ -848,16 +854,15 @@ static int platform_pm_poweroff(struct device *dev)
848 854
849static int platform_pm_poweroff_noirq(struct device *dev) 855static int platform_pm_poweroff_noirq(struct device *dev)
850{ 856{
851 struct platform_driver *pdrv; 857 struct device_driver *drv = dev->driver;
852 int ret = 0; 858 int ret = 0;
853 859
854 if (!dev->driver) 860 if (!drv)
855 return 0; 861 return 0;
856 862
857 pdrv = to_platform_driver(dev->driver); 863 if (drv->pm) {
858 if (pdrv->pm) { 864 if (drv->pm->poweroff_noirq)
859 if (pdrv->pm->poweroff_noirq) 865 ret = drv->pm->poweroff_noirq(dev);
860 ret = pdrv->pm->poweroff_noirq(dev);
861 } else { 866 } else {
862 ret = platform_legacy_suspend_late(dev, PMSG_HIBERNATE); 867 ret = platform_legacy_suspend_late(dev, PMSG_HIBERNATE);
863 } 868 }
@@ -870,7 +875,10 @@ static int platform_pm_restore(struct device *dev)
870 struct device_driver *drv = dev->driver; 875 struct device_driver *drv = dev->driver;
871 int ret = 0; 876 int ret = 0;
872 877
873 if (drv && drv->pm) { 878 if (!drv)
879 return 0;
880
881 if (drv->pm) {
874 if (drv->pm->restore) 882 if (drv->pm->restore)
875 ret = drv->pm->restore(dev); 883 ret = drv->pm->restore(dev);
876 } else { 884 } else {
@@ -882,16 +890,15 @@ static int platform_pm_restore(struct device *dev)
882 890
883static int platform_pm_restore_noirq(struct device *dev) 891static int platform_pm_restore_noirq(struct device *dev)
884{ 892{
885 struct platform_driver *pdrv; 893 struct device_driver *drv = dev->driver;
886 int ret = 0; 894 int ret = 0;
887 895
888 if (!dev->driver) 896 if (!drv)
889 return 0; 897 return 0;
890 898
891 pdrv = to_platform_driver(dev->driver); 899 if (drv->pm) {
892 if (pdrv->pm) { 900 if (drv->pm->restore_noirq)
893 if (pdrv->pm->restore_noirq) 901 ret = drv->pm->restore_noirq(dev);
894 ret = pdrv->pm->restore_noirq(dev);
895 } else { 902 } else {
896 ret = platform_legacy_resume_early(dev); 903 ret = platform_legacy_resume_early(dev);
897 } 904 }
@@ -912,17 +919,15 @@ static int platform_pm_restore_noirq(struct device *dev)
912 919
913#endif /* !CONFIG_HIBERNATION */ 920#endif /* !CONFIG_HIBERNATION */
914 921
915static struct pm_ext_ops platform_pm_ops = { 922static struct dev_pm_ops platform_dev_pm_ops = {
916 .base = { 923 .prepare = platform_pm_prepare,
917 .prepare = platform_pm_prepare, 924 .complete = platform_pm_complete,
918 .complete = platform_pm_complete, 925 .suspend = platform_pm_suspend,
919 .suspend = platform_pm_suspend, 926 .resume = platform_pm_resume,
920 .resume = platform_pm_resume, 927 .freeze = platform_pm_freeze,
921 .freeze = platform_pm_freeze, 928 .thaw = platform_pm_thaw,
922 .thaw = platform_pm_thaw, 929 .poweroff = platform_pm_poweroff,
923 .poweroff = platform_pm_poweroff, 930 .restore = platform_pm_restore,
924 .restore = platform_pm_restore,
925 },
926 .suspend_noirq = platform_pm_suspend_noirq, 931 .suspend_noirq = platform_pm_suspend_noirq,
927 .resume_noirq = platform_pm_resume_noirq, 932 .resume_noirq = platform_pm_resume_noirq,
928 .freeze_noirq = platform_pm_freeze_noirq, 933 .freeze_noirq = platform_pm_freeze_noirq,
@@ -931,7 +936,7 @@ static struct pm_ext_ops platform_pm_ops = {
931 .restore_noirq = platform_pm_restore_noirq, 936 .restore_noirq = platform_pm_restore_noirq,
932}; 937};
933 938
934#define PLATFORM_PM_OPS_PTR &platform_pm_ops 939#define PLATFORM_PM_OPS_PTR (&platform_dev_pm_ops)
935 940
936#else /* !CONFIG_PM_SLEEP */ 941#else /* !CONFIG_PM_SLEEP */
937 942
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 692c20ba5144..a8e4dcbcaf7a 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -112,7 +112,8 @@ void device_pm_remove(struct device *dev)
112 * @ops: PM operations to choose from. 112 * @ops: PM operations to choose from.
113 * @state: PM transition of the system being carried out. 113 * @state: PM transition of the system being carried out.
114 */ 114 */
115static int pm_op(struct device *dev, struct pm_ops *ops, pm_message_t state) 115static int pm_op(struct device *dev, struct dev_pm_ops *ops,
116 pm_message_t state)
116{ 117{
117 int error = 0; 118 int error = 0;
118 119
@@ -174,7 +175,7 @@ static int pm_op(struct device *dev, struct pm_ops *ops, pm_message_t state)
174 * The operation is executed with interrupts disabled by the only remaining 175 * The operation is executed with interrupts disabled by the only remaining
175 * functional CPU in the system. 176 * functional CPU in the system.
176 */ 177 */
177static int pm_noirq_op(struct device *dev, struct pm_ext_ops *ops, 178static int pm_noirq_op(struct device *dev, struct dev_pm_ops *ops,
178 pm_message_t state) 179 pm_message_t state)
179{ 180{
180 int error = 0; 181 int error = 0;
@@ -354,7 +355,7 @@ static int resume_device(struct device *dev, pm_message_t state)
354 if (dev->bus) { 355 if (dev->bus) {
355 if (dev->bus->pm) { 356 if (dev->bus->pm) {
356 pm_dev_dbg(dev, state, ""); 357 pm_dev_dbg(dev, state, "");
357 error = pm_op(dev, &dev->bus->pm->base, state); 358 error = pm_op(dev, dev->bus->pm, state);
358 } else if (dev->bus->resume) { 359 } else if (dev->bus->resume) {
359 pm_dev_dbg(dev, state, "legacy "); 360 pm_dev_dbg(dev, state, "legacy ");
360 error = dev->bus->resume(dev); 361 error = dev->bus->resume(dev);
@@ -451,9 +452,9 @@ static void complete_device(struct device *dev, pm_message_t state)
451 dev->type->pm->complete(dev); 452 dev->type->pm->complete(dev);
452 } 453 }
453 454
454 if (dev->bus && dev->bus->pm && dev->bus->pm->base.complete) { 455 if (dev->bus && dev->bus->pm && dev->bus->pm->complete) {
455 pm_dev_dbg(dev, state, "completing "); 456 pm_dev_dbg(dev, state, "completing ");
456 dev->bus->pm->base.complete(dev); 457 dev->bus->pm->complete(dev);
457 } 458 }
458 459
459 up(&dev->sem); 460 up(&dev->sem);
@@ -624,7 +625,7 @@ static int suspend_device(struct device *dev, pm_message_t state)
624 if (dev->bus) { 625 if (dev->bus) {
625 if (dev->bus->pm) { 626 if (dev->bus->pm) {
626 pm_dev_dbg(dev, state, ""); 627 pm_dev_dbg(dev, state, "");
627 error = pm_op(dev, &dev->bus->pm->base, state); 628 error = pm_op(dev, dev->bus->pm, state);
628 } else if (dev->bus->suspend) { 629 } else if (dev->bus->suspend) {
629 pm_dev_dbg(dev, state, "legacy "); 630 pm_dev_dbg(dev, state, "legacy ");
630 error = dev->bus->suspend(dev, state); 631 error = dev->bus->suspend(dev, state);
@@ -685,10 +686,10 @@ static int prepare_device(struct device *dev, pm_message_t state)
685 686
686 down(&dev->sem); 687 down(&dev->sem);
687 688
688 if (dev->bus && dev->bus->pm && dev->bus->pm->base.prepare) { 689 if (dev->bus && dev->bus->pm && dev->bus->pm->prepare) {
689 pm_dev_dbg(dev, state, "preparing "); 690 pm_dev_dbg(dev, state, "preparing ");
690 error = dev->bus->pm->base.prepare(dev); 691 error = dev->bus->pm->prepare(dev);
691 suspend_report_result(dev->bus->pm->base.prepare, error); 692 suspend_report_result(dev->bus->pm->prepare, error);
692 if (error) 693 if (error)
693 goto End; 694 goto End;
694 } 695 }
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index b4cdd690ae71..4042d211c3e5 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -433,8 +433,7 @@ static int pci_pm_suspend(struct device *dev)
433 433
434static int pci_pm_suspend_noirq(struct device *dev) 434static int pci_pm_suspend_noirq(struct device *dev)
435{ 435{
436 struct pci_dev *pci_dev = to_pci_dev(dev); 436 struct device_driver *drv = dev->driver;
437 struct pci_driver *drv = pci_dev->driver;
438 int error = 0; 437 int error = 0;
439 438
440 if (drv && drv->pm) { 439 if (drv && drv->pm) {
@@ -469,11 +468,10 @@ static int pci_pm_resume(struct device *dev)
469 468
470static int pci_pm_resume_noirq(struct device *dev) 469static int pci_pm_resume_noirq(struct device *dev)
471{ 470{
472 struct pci_dev *pci_dev = to_pci_dev(dev); 471 struct device_driver *drv = dev->driver;
473 struct pci_driver *drv = pci_dev->driver;
474 int error = 0; 472 int error = 0;
475 473
476 pci_fixup_device(pci_fixup_resume_early, pci_dev); 474 pci_fixup_device(pci_fixup_resume_early, to_pci_dev(dev));
477 475
478 if (drv && drv->pm) { 476 if (drv && drv->pm) {
479 if (drv->pm->resume_noirq) 477 if (drv->pm->resume_noirq)
@@ -519,8 +517,7 @@ static int pci_pm_freeze(struct device *dev)
519 517
520static int pci_pm_freeze_noirq(struct device *dev) 518static int pci_pm_freeze_noirq(struct device *dev)
521{ 519{
522 struct pci_dev *pci_dev = to_pci_dev(dev); 520 struct device_driver *drv = dev->driver;
523 struct pci_driver *drv = pci_dev->driver;
524 int error = 0; 521 int error = 0;
525 522
526 if (drv && drv->pm) { 523 if (drv && drv->pm) {
@@ -553,15 +550,14 @@ static int pci_pm_thaw(struct device *dev)
553 550
554static int pci_pm_thaw_noirq(struct device *dev) 551static int pci_pm_thaw_noirq(struct device *dev)
555{ 552{
556 struct pci_dev *pci_dev = to_pci_dev(dev); 553 struct device_driver *drv = dev->driver;
557 struct pci_driver *drv = pci_dev->driver;
558 int error = 0; 554 int error = 0;
559 555
560 if (drv && drv->pm) { 556 if (drv && drv->pm) {
561 if (drv->pm->thaw_noirq) 557 if (drv->pm->thaw_noirq)
562 error = drv->pm->thaw_noirq(dev); 558 error = drv->pm->thaw_noirq(dev);
563 } else { 559 } else {
564 pci_fixup_device(pci_fixup_resume_early, pci_dev); 560 pci_fixup_device(pci_fixup_resume_early, to_pci_dev(dev));
565 error = pci_legacy_resume_early(dev); 561 error = pci_legacy_resume_early(dev);
566 } 562 }
567 563
@@ -589,8 +585,7 @@ static int pci_pm_poweroff(struct device *dev)
589 585
590static int pci_pm_poweroff_noirq(struct device *dev) 586static int pci_pm_poweroff_noirq(struct device *dev)
591{ 587{
592 struct pci_dev *pci_dev = to_pci_dev(dev); 588 struct device_driver *drv = dev->driver;
593 struct pci_driver *drv = pci_dev->driver;
594 int error = 0; 589 int error = 0;
595 590
596 if (drv && drv->pm) { 591 if (drv && drv->pm) {
@@ -625,7 +620,7 @@ static int pci_pm_restore(struct device *dev)
625static int pci_pm_restore_noirq(struct device *dev) 620static int pci_pm_restore_noirq(struct device *dev)
626{ 621{
627 struct pci_dev *pci_dev = to_pci_dev(dev); 622 struct pci_dev *pci_dev = to_pci_dev(dev);
628 struct pci_driver *drv = pci_dev->driver; 623 struct device_driver *drv = dev->driver;
629 int error = 0; 624 int error = 0;
630 625
631 pci_fixup_device(pci_fixup_resume, pci_dev); 626 pci_fixup_device(pci_fixup_resume, pci_dev);
@@ -654,17 +649,15 @@ static int pci_pm_restore_noirq(struct device *dev)
654 649
655#endif /* !CONFIG_HIBERNATION */ 650#endif /* !CONFIG_HIBERNATION */
656 651
657struct pm_ext_ops pci_pm_ops = { 652struct dev_pm_ops pci_dev_pm_ops = {
658 .base = { 653 .prepare = pci_pm_prepare,
659 .prepare = pci_pm_prepare, 654 .complete = pci_pm_complete,
660 .complete = pci_pm_complete, 655 .suspend = pci_pm_suspend,
661 .suspend = pci_pm_suspend, 656 .resume = pci_pm_resume,
662 .resume = pci_pm_resume, 657 .freeze = pci_pm_freeze,
663 .freeze = pci_pm_freeze, 658 .thaw = pci_pm_thaw,
664 .thaw = pci_pm_thaw, 659 .poweroff = pci_pm_poweroff,
665 .poweroff = pci_pm_poweroff, 660 .restore = pci_pm_restore,
666 .restore = pci_pm_restore,
667 },
668 .suspend_noirq = pci_pm_suspend_noirq, 661 .suspend_noirq = pci_pm_suspend_noirq,
669 .resume_noirq = pci_pm_resume_noirq, 662 .resume_noirq = pci_pm_resume_noirq,
670 .freeze_noirq = pci_pm_freeze_noirq, 663 .freeze_noirq = pci_pm_freeze_noirq,
@@ -673,7 +666,7 @@ struct pm_ext_ops pci_pm_ops = {
673 .restore_noirq = pci_pm_restore_noirq, 666 .restore_noirq = pci_pm_restore_noirq,
674}; 667};
675 668
676#define PCI_PM_OPS_PTR &pci_pm_ops 669#define PCI_PM_OPS_PTR (&pci_dev_pm_ops)
677 670
678#else /* !CONFIG_PM_SLEEP */ 671#else /* !CONFIG_PM_SLEEP */
679 672
@@ -703,9 +696,6 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner,
703 drv->driver.owner = owner; 696 drv->driver.owner = owner;
704 drv->driver.mod_name = mod_name; 697 drv->driver.mod_name = mod_name;
705 698
706 if (drv->pm)
707 drv->driver.pm = &drv->pm->base;
708
709 spin_lock_init(&drv->dynids.lock); 699 spin_lock_init(&drv->dynids.lock);
710 INIT_LIST_HEAD(&drv->dynids.list); 700 INIT_LIST_HEAD(&drv->dynids.list);
711 701
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index be1fa0723f2c..399e15fc5052 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -286,7 +286,7 @@ static int usb_dev_restore(struct device *dev)
286 return usb_resume(dev); 286 return usb_resume(dev);
287} 287}
288 288
289static struct pm_ops usb_device_pm_ops = { 289static struct dev_pm_ops usb_device_pm_ops = {
290 .prepare = usb_dev_prepare, 290 .prepare = usb_dev_prepare,
291 .complete = usb_dev_complete, 291 .complete = usb_dev_complete,
292 .suspend = usb_dev_suspend, 292 .suspend = usb_dev_suspend,
@@ -301,7 +301,7 @@ static struct pm_ops usb_device_pm_ops = {
301 301
302#define ksuspend_usb_init() 0 302#define ksuspend_usb_init() 0
303#define ksuspend_usb_cleanup() do {} while (0) 303#define ksuspend_usb_cleanup() do {} while (0)
304#define usb_device_pm_ops (*(struct pm_ops *)0) 304#define usb_device_pm_ops (*(struct dev_pm_ops *)0)
305 305
306#endif /* CONFIG_PM */ 306#endif /* CONFIG_PM */
307 307
diff --git a/include/linux/device.h b/include/linux/device.h
index 1a3686d15f98..4a520051c315 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -65,7 +65,7 @@ struct bus_type {
65 int (*resume_early)(struct device *dev); 65 int (*resume_early)(struct device *dev);
66 int (*resume)(struct device *dev); 66 int (*resume)(struct device *dev);
67 67
68 struct pm_ext_ops *pm; 68 struct dev_pm_ops *pm;
69 69
70 struct bus_type_private *p; 70 struct bus_type_private *p;
71}; 71};
@@ -133,7 +133,7 @@ struct device_driver {
133 int (*resume) (struct device *dev); 133 int (*resume) (struct device *dev);
134 struct attribute_group **groups; 134 struct attribute_group **groups;
135 135
136 struct pm_ops *pm; 136 struct dev_pm_ops *pm;
137 137
138 struct driver_private *p; 138 struct driver_private *p;
139}; 139};
@@ -198,7 +198,7 @@ struct class {
198 int (*suspend)(struct device *dev, pm_message_t state); 198 int (*suspend)(struct device *dev, pm_message_t state);
199 int (*resume)(struct device *dev); 199 int (*resume)(struct device *dev);
200 200
201 struct pm_ops *pm; 201 struct dev_pm_ops *pm;
202 struct class_private *p; 202 struct class_private *p;
203}; 203};
204 204
@@ -291,7 +291,7 @@ struct device_type {
291 int (*suspend)(struct device *dev, pm_message_t state); 291 int (*suspend)(struct device *dev, pm_message_t state);
292 int (*resume)(struct device *dev); 292 int (*resume)(struct device *dev);
293 293
294 struct pm_ops *pm; 294 struct dev_pm_ops *pm;
295}; 295};
296 296
297/* interface for exporting device attributes */ 297/* interface for exporting device attributes */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 03b0b8c3c81b..4bb156ba854a 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -421,7 +421,6 @@ struct pci_driver {
421 int (*resume_early) (struct pci_dev *dev); 421 int (*resume_early) (struct pci_dev *dev);
422 int (*resume) (struct pci_dev *dev); /* Device woken up */ 422 int (*resume) (struct pci_dev *dev); /* Device woken up */
423 void (*shutdown) (struct pci_dev *dev); 423 void (*shutdown) (struct pci_dev *dev);
424 struct pm_ext_ops *pm;
425 struct pci_error_handlers *err_handler; 424 struct pci_error_handlers *err_handler;
426 struct device_driver driver; 425 struct device_driver driver;
427 struct pci_dynids dynids; 426 struct pci_dynids dynids;
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 4b8cc6a32479..9a342699c607 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -55,7 +55,6 @@ struct platform_driver {
55 int (*suspend_late)(struct platform_device *, pm_message_t state); 55 int (*suspend_late)(struct platform_device *, pm_message_t state);
56 int (*resume_early)(struct platform_device *); 56 int (*resume_early)(struct platform_device *);
57 int (*resume)(struct platform_device *); 57 int (*resume)(struct platform_device *);
58 struct pm_ext_ops *pm;
59 struct device_driver driver; 58 struct device_driver driver;
60}; 59};
61 60
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 42de4003c4ee..5785666d0cc4 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -41,7 +41,7 @@ typedef struct pm_message {
41} pm_message_t; 41} pm_message_t;
42 42
43/** 43/**
44 * struct pm_ops - device PM callbacks 44 * struct dev_pm_ops - device PM callbacks
45 * 45 *
46 * Several driver power state transitions are externally visible, affecting 46 * Several driver power state transitions are externally visible, affecting
47 * the state of pending I/O queues and (for drivers that touch hardware) 47 * the state of pending I/O queues and (for drivers that touch hardware)
@@ -126,46 +126,6 @@ typedef struct pm_message {
126 * On most platforms, there are no restrictions on availability of 126 * On most platforms, there are no restrictions on availability of
127 * resources like clocks during @restore(). 127 * resources like clocks during @restore().
128 * 128 *
129 * All of the above callbacks, except for @complete(), return error codes.
130 * However, the error codes returned by the resume operations, @resume(),
131 * @thaw(), and @restore(), do not cause the PM core to abort the resume
132 * transition during which they are returned. The error codes returned in
133 * that cases are only printed by the PM core to the system logs for debugging
134 * purposes. Still, it is recommended that drivers only return error codes
135 * from their resume methods in case of an unrecoverable failure (i.e. when the
136 * device being handled refuses to resume and becomes unusable) to allow us to
137 * modify the PM core in the future, so that it can avoid attempting to handle
138 * devices that failed to resume and their children.
139 *
140 * It is allowed to unregister devices while the above callbacks are being
141 * executed. However, it is not allowed to unregister a device from within any
142 * of its own callbacks.
143 */
144
145struct pm_ops {
146 int (*prepare)(struct device *dev);
147 void (*complete)(struct device *dev);
148 int (*suspend)(struct device *dev);
149 int (*resume)(struct device *dev);
150 int (*freeze)(struct device *dev);
151 int (*thaw)(struct device *dev);
152 int (*poweroff)(struct device *dev);
153 int (*restore)(struct device *dev);
154};
155
156/**
157 * struct pm_ext_ops - extended device PM callbacks
158 *
159 * Some devices require certain operations related to suspend and hibernation
160 * to be carried out with interrupts disabled. Thus, 'struct pm_ext_ops' below
161 * is defined, adding callbacks to be executed with interrupts disabled to
162 * 'struct pm_ops'.
163 *
164 * The following callbacks included in 'struct pm_ext_ops' are executed with
165 * the nonboot CPUs switched off and with interrupts disabled on the only
166 * functional CPU. They also are executed with the PM core list of devices
167 * locked, so they must NOT unregister any devices.
168 *
169 * @suspend_noirq: Complete the operations of ->suspend() by carrying out any 129 * @suspend_noirq: Complete the operations of ->suspend() by carrying out any
170 * actions required for suspending the device that need interrupts to be 130 * actions required for suspending the device that need interrupts to be
171 * disabled 131 * disabled
@@ -190,18 +150,32 @@ struct pm_ops {
190 * actions required for restoring the operations of the device that need 150 * actions required for restoring the operations of the device that need
191 * interrupts to be disabled 151 * interrupts to be disabled
192 * 152 *
193 * All of the above callbacks return error codes, but the error codes returned 153 * All of the above callbacks, except for @complete(), return error codes.
194 * by the resume operations, @resume_noirq(), @thaw_noirq(), and 154 * However, the error codes returned by the resume operations, @resume(),
195 * @restore_noirq(), do not cause the PM core to abort the resume transition 155 * @thaw(), @restore(), @resume_noirq(), @thaw_noirq(), and @restore_noirq() do
196 * during which they are returned. The error codes returned in that cases are 156 * not cause the PM core to abort the resume transition during which they are
197 * only printed by the PM core to the system logs for debugging purposes. 157 * returned. The error codes returned in that cases are only printed by the PM
198 * Still, as stated above, it is recommended that drivers only return error 158 * core to the system logs for debugging purposes. Still, it is recommended
199 * codes from their resume methods if the device being handled fails to resume 159 * that drivers only return error codes from their resume methods in case of an
200 * and is not usable any more. 160 * unrecoverable failure (i.e. when the device being handled refuses to resume
161 * and becomes unusable) to allow us to modify the PM core in the future, so
162 * that it can avoid attempting to handle devices that failed to resume and
163 * their children.
164 *
165 * It is allowed to unregister devices while the above callbacks are being
166 * executed. However, it is not allowed to unregister a device from within any
167 * of its own callbacks.
201 */ 168 */
202 169
203struct pm_ext_ops { 170struct dev_pm_ops {
204 struct pm_ops base; 171 int (*prepare)(struct device *dev);
172 void (*complete)(struct device *dev);
173 int (*suspend)(struct device *dev);
174 int (*resume)(struct device *dev);
175 int (*freeze)(struct device *dev);
176 int (*thaw)(struct device *dev);
177 int (*poweroff)(struct device *dev);
178 int (*restore)(struct device *dev);
205 int (*suspend_noirq)(struct device *dev); 179 int (*suspend_noirq)(struct device *dev);
206 int (*resume_noirq)(struct device *dev); 180 int (*resume_noirq)(struct device *dev);
207 int (*freeze_noirq)(struct device *dev); 181 int (*freeze_noirq)(struct device *dev);