aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
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 /drivers/base
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>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/platform.c115
-rw-r--r--drivers/base/power/main.c19
2 files changed, 70 insertions, 64 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 }