diff options
Diffstat (limited to 'drivers/base/platform.c')
-rw-r--r-- | drivers/base/platform.c | 82 |
1 files changed, 37 insertions, 45 deletions
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 0b111e8e444f..0f7d434ce983 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/bootmem.h> | 17 | #include <linux/bootmem.h> |
18 | #include <linux/err.h> | 18 | #include <linux/err.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/pm_runtime.h> | ||
20 | 21 | ||
21 | #include "base.h" | 22 | #include "base.h" |
22 | 23 | ||
@@ -625,30 +626,6 @@ static int platform_legacy_suspend(struct device *dev, pm_message_t mesg) | |||
625 | return ret; | 626 | return ret; |
626 | } | 627 | } |
627 | 628 | ||
628 | static int platform_legacy_suspend_late(struct device *dev, pm_message_t mesg) | ||
629 | { | ||
630 | struct platform_driver *pdrv = to_platform_driver(dev->driver); | ||
631 | struct platform_device *pdev = to_platform_device(dev); | ||
632 | int ret = 0; | ||
633 | |||
634 | if (dev->driver && pdrv->suspend_late) | ||
635 | ret = pdrv->suspend_late(pdev, mesg); | ||
636 | |||
637 | return ret; | ||
638 | } | ||
639 | |||
640 | static int platform_legacy_resume_early(struct device *dev) | ||
641 | { | ||
642 | struct platform_driver *pdrv = to_platform_driver(dev->driver); | ||
643 | struct platform_device *pdev = to_platform_device(dev); | ||
644 | int ret = 0; | ||
645 | |||
646 | if (dev->driver && pdrv->resume_early) | ||
647 | ret = pdrv->resume_early(pdev); | ||
648 | |||
649 | return ret; | ||
650 | } | ||
651 | |||
652 | static int platform_legacy_resume(struct device *dev) | 629 | static int platform_legacy_resume(struct device *dev) |
653 | { | 630 | { |
654 | struct platform_driver *pdrv = to_platform_driver(dev->driver); | 631 | struct platform_driver *pdrv = to_platform_driver(dev->driver); |
@@ -680,6 +657,13 @@ static void platform_pm_complete(struct device *dev) | |||
680 | drv->pm->complete(dev); | 657 | drv->pm->complete(dev); |
681 | } | 658 | } |
682 | 659 | ||
660 | #else /* !CONFIG_PM_SLEEP */ | ||
661 | |||
662 | #define platform_pm_prepare NULL | ||
663 | #define platform_pm_complete NULL | ||
664 | |||
665 | #endif /* !CONFIG_PM_SLEEP */ | ||
666 | |||
683 | #ifdef CONFIG_SUSPEND | 667 | #ifdef CONFIG_SUSPEND |
684 | 668 | ||
685 | static int platform_pm_suspend(struct device *dev) | 669 | static int platform_pm_suspend(struct device *dev) |
@@ -711,8 +695,6 @@ static int platform_pm_suspend_noirq(struct device *dev) | |||
711 | if (drv->pm) { | 695 | if (drv->pm) { |
712 | if (drv->pm->suspend_noirq) | 696 | if (drv->pm->suspend_noirq) |
713 | ret = drv->pm->suspend_noirq(dev); | 697 | ret = drv->pm->suspend_noirq(dev); |
714 | } else { | ||
715 | ret = platform_legacy_suspend_late(dev, PMSG_SUSPEND); | ||
716 | } | 698 | } |
717 | 699 | ||
718 | return ret; | 700 | return ret; |
@@ -747,8 +729,6 @@ static int platform_pm_resume_noirq(struct device *dev) | |||
747 | if (drv->pm) { | 729 | if (drv->pm) { |
748 | if (drv->pm->resume_noirq) | 730 | if (drv->pm->resume_noirq) |
749 | ret = drv->pm->resume_noirq(dev); | 731 | ret = drv->pm->resume_noirq(dev); |
750 | } else { | ||
751 | ret = platform_legacy_resume_early(dev); | ||
752 | } | 732 | } |
753 | 733 | ||
754 | return ret; | 734 | return ret; |
@@ -794,8 +774,6 @@ static int platform_pm_freeze_noirq(struct device *dev) | |||
794 | if (drv->pm) { | 774 | if (drv->pm) { |
795 | if (drv->pm->freeze_noirq) | 775 | if (drv->pm->freeze_noirq) |
796 | ret = drv->pm->freeze_noirq(dev); | 776 | ret = drv->pm->freeze_noirq(dev); |
797 | } else { | ||
798 | ret = platform_legacy_suspend_late(dev, PMSG_FREEZE); | ||
799 | } | 777 | } |
800 | 778 | ||
801 | return ret; | 779 | return ret; |
@@ -830,8 +808,6 @@ static int platform_pm_thaw_noirq(struct device *dev) | |||
830 | if (drv->pm) { | 808 | if (drv->pm) { |
831 | if (drv->pm->thaw_noirq) | 809 | if (drv->pm->thaw_noirq) |
832 | ret = drv->pm->thaw_noirq(dev); | 810 | ret = drv->pm->thaw_noirq(dev); |
833 | } else { | ||
834 | ret = platform_legacy_resume_early(dev); | ||
835 | } | 811 | } |
836 | 812 | ||
837 | return ret; | 813 | return ret; |
@@ -866,8 +842,6 @@ static int platform_pm_poweroff_noirq(struct device *dev) | |||
866 | if (drv->pm) { | 842 | if (drv->pm) { |
867 | if (drv->pm->poweroff_noirq) | 843 | if (drv->pm->poweroff_noirq) |
868 | ret = drv->pm->poweroff_noirq(dev); | 844 | ret = drv->pm->poweroff_noirq(dev); |
869 | } else { | ||
870 | ret = platform_legacy_suspend_late(dev, PMSG_HIBERNATE); | ||
871 | } | 845 | } |
872 | 846 | ||
873 | return ret; | 847 | return ret; |
@@ -902,8 +876,6 @@ static int platform_pm_restore_noirq(struct device *dev) | |||
902 | if (drv->pm) { | 876 | if (drv->pm) { |
903 | if (drv->pm->restore_noirq) | 877 | if (drv->pm->restore_noirq) |
904 | ret = drv->pm->restore_noirq(dev); | 878 | ret = drv->pm->restore_noirq(dev); |
905 | } else { | ||
906 | ret = platform_legacy_resume_early(dev); | ||
907 | } | 879 | } |
908 | 880 | ||
909 | return ret; | 881 | return ret; |
@@ -922,6 +894,31 @@ static int platform_pm_restore_noirq(struct device *dev) | |||
922 | 894 | ||
923 | #endif /* !CONFIG_HIBERNATION */ | 895 | #endif /* !CONFIG_HIBERNATION */ |
924 | 896 | ||
897 | #ifdef CONFIG_PM_RUNTIME | ||
898 | |||
899 | int __weak platform_pm_runtime_suspend(struct device *dev) | ||
900 | { | ||
901 | return -ENOSYS; | ||
902 | }; | ||
903 | |||
904 | int __weak platform_pm_runtime_resume(struct device *dev) | ||
905 | { | ||
906 | return -ENOSYS; | ||
907 | }; | ||
908 | |||
909 | int __weak platform_pm_runtime_idle(struct device *dev) | ||
910 | { | ||
911 | return -ENOSYS; | ||
912 | }; | ||
913 | |||
914 | #else /* !CONFIG_PM_RUNTIME */ | ||
915 | |||
916 | #define platform_pm_runtime_suspend NULL | ||
917 | #define platform_pm_runtime_resume NULL | ||
918 | #define platform_pm_runtime_idle NULL | ||
919 | |||
920 | #endif /* !CONFIG_PM_RUNTIME */ | ||
921 | |||
925 | static const struct dev_pm_ops platform_dev_pm_ops = { | 922 | static const struct dev_pm_ops platform_dev_pm_ops = { |
926 | .prepare = platform_pm_prepare, | 923 | .prepare = platform_pm_prepare, |
927 | .complete = platform_pm_complete, | 924 | .complete = platform_pm_complete, |
@@ -937,22 +934,17 @@ static const struct dev_pm_ops platform_dev_pm_ops = { | |||
937 | .thaw_noirq = platform_pm_thaw_noirq, | 934 | .thaw_noirq = platform_pm_thaw_noirq, |
938 | .poweroff_noirq = platform_pm_poweroff_noirq, | 935 | .poweroff_noirq = platform_pm_poweroff_noirq, |
939 | .restore_noirq = platform_pm_restore_noirq, | 936 | .restore_noirq = platform_pm_restore_noirq, |
937 | .runtime_suspend = platform_pm_runtime_suspend, | ||
938 | .runtime_resume = platform_pm_runtime_resume, | ||
939 | .runtime_idle = platform_pm_runtime_idle, | ||
940 | }; | 940 | }; |
941 | 941 | ||
942 | #define PLATFORM_PM_OPS_PTR (&platform_dev_pm_ops) | ||
943 | |||
944 | #else /* !CONFIG_PM_SLEEP */ | ||
945 | |||
946 | #define PLATFORM_PM_OPS_PTR NULL | ||
947 | |||
948 | #endif /* !CONFIG_PM_SLEEP */ | ||
949 | |||
950 | struct bus_type platform_bus_type = { | 942 | struct bus_type platform_bus_type = { |
951 | .name = "platform", | 943 | .name = "platform", |
952 | .dev_attrs = platform_dev_attrs, | 944 | .dev_attrs = platform_dev_attrs, |
953 | .match = platform_match, | 945 | .match = platform_match, |
954 | .uevent = platform_uevent, | 946 | .uevent = platform_uevent, |
955 | .pm = PLATFORM_PM_OPS_PTR, | 947 | .pm = &platform_dev_pm_ops, |
956 | }; | 948 | }; |
957 | EXPORT_SYMBOL_GPL(platform_bus_type); | 949 | EXPORT_SYMBOL_GPL(platform_bus_type); |
958 | 950 | ||