diff options
author | Paul Fox <pgf@laptop.org> | 2011-01-12 20:00:07 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-13 11:03:12 -0500 |
commit | 2fb08e6ca9f00d1aedb3964983e9c8f84b36b807 (patch) | |
tree | b1ef2c797899cedbf4ad2f6853b327ed7be17e29 /drivers/rtc | |
parent | 19412ce9fcc9ca2d0f5b62af15c63381f0ac9657 (diff) |
rtc-cmos: fix suspend/resume
rtc-cmos was setting suspend/resume hooks at the device_driver level.
However, the platform bus code (drivers/base/platform.c) only looks for
resume hooks at the dev_pm_ops level, or within the platform_driver.
Switch rtc_cmos to use dev_pm_ops so that suspend/resume code is executed
again.
Paul said:
: The user visible symptom in our (XO laptop) case was that rtcwake would
: fail to wake the laptop. The RTC alarm would expire, but the wakeup
: wasn't unmasked.
:
: As for severity, the impact may have been reduced because if I recall
: correctly, the bug only affected platforms with CONFIG_PNP disabled.
Signed-off-by: Paul Fox <pgf@laptop.org>
Signed-off-by: Daniel Drake <dsd@laptop.org>
Acked-by: Rafael J. Wysocki <rjw@sisk.pl>
Cc: <stable@kernel.org> [2.6.37.x]
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rtc')
-rw-r--r-- | drivers/rtc/rtc-cmos.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 7e6ce626b7f1..c7ff8df347e7 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/platform_device.h> | 36 | #include <linux/platform_device.h> |
37 | #include <linux/mod_devicetable.h> | 37 | #include <linux/mod_devicetable.h> |
38 | #include <linux/log2.h> | 38 | #include <linux/log2.h> |
39 | #include <linux/pm.h> | ||
39 | 40 | ||
40 | /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ | 41 | /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ |
41 | #include <asm-generic/rtc.h> | 42 | #include <asm-generic/rtc.h> |
@@ -851,7 +852,7 @@ static void __exit cmos_do_remove(struct device *dev) | |||
851 | 852 | ||
852 | #ifdef CONFIG_PM | 853 | #ifdef CONFIG_PM |
853 | 854 | ||
854 | static int cmos_suspend(struct device *dev, pm_message_t mesg) | 855 | static int cmos_suspend(struct device *dev) |
855 | { | 856 | { |
856 | struct cmos_rtc *cmos = dev_get_drvdata(dev); | 857 | struct cmos_rtc *cmos = dev_get_drvdata(dev); |
857 | unsigned char tmp; | 858 | unsigned char tmp; |
@@ -899,7 +900,7 @@ static int cmos_suspend(struct device *dev, pm_message_t mesg) | |||
899 | */ | 900 | */ |
900 | static inline int cmos_poweroff(struct device *dev) | 901 | static inline int cmos_poweroff(struct device *dev) |
901 | { | 902 | { |
902 | return cmos_suspend(dev, PMSG_HIBERNATE); | 903 | return cmos_suspend(dev); |
903 | } | 904 | } |
904 | 905 | ||
905 | static int cmos_resume(struct device *dev) | 906 | static int cmos_resume(struct device *dev) |
@@ -946,9 +947,9 @@ static int cmos_resume(struct device *dev) | |||
946 | return 0; | 947 | return 0; |
947 | } | 948 | } |
948 | 949 | ||
950 | static SIMPLE_DEV_PM_OPS(cmos_pm_ops, cmos_suspend, cmos_resume); | ||
951 | |||
949 | #else | 952 | #else |
950 | #define cmos_suspend NULL | ||
951 | #define cmos_resume NULL | ||
952 | 953 | ||
953 | static inline int cmos_poweroff(struct device *dev) | 954 | static inline int cmos_poweroff(struct device *dev) |
954 | { | 955 | { |
@@ -1078,7 +1079,7 @@ static void __exit cmos_pnp_remove(struct pnp_dev *pnp) | |||
1078 | 1079 | ||
1079 | static int cmos_pnp_suspend(struct pnp_dev *pnp, pm_message_t mesg) | 1080 | static int cmos_pnp_suspend(struct pnp_dev *pnp, pm_message_t mesg) |
1080 | { | 1081 | { |
1081 | return cmos_suspend(&pnp->dev, mesg); | 1082 | return cmos_suspend(&pnp->dev); |
1082 | } | 1083 | } |
1083 | 1084 | ||
1084 | static int cmos_pnp_resume(struct pnp_dev *pnp) | 1085 | static int cmos_pnp_resume(struct pnp_dev *pnp) |
@@ -1158,8 +1159,9 @@ static struct platform_driver cmos_platform_driver = { | |||
1158 | .shutdown = cmos_platform_shutdown, | 1159 | .shutdown = cmos_platform_shutdown, |
1159 | .driver = { | 1160 | .driver = { |
1160 | .name = (char *) driver_name, | 1161 | .name = (char *) driver_name, |
1161 | .suspend = cmos_suspend, | 1162 | #ifdef CONFIG_PM |
1162 | .resume = cmos_resume, | 1163 | .pm = &cmos_pm_ops, |
1164 | #endif | ||
1163 | } | 1165 | } |
1164 | }; | 1166 | }; |
1165 | 1167 | ||