Commit 2fb08e6ca9f00d1aedb3964983e9c8f84b36b807
Committed by
Linus Torvalds
1 parent
19412ce9fc
Exists in
master
and in
7 other branches
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>
Showing 1 changed file with 9 additions and 7 deletions Side-by-side Diff
drivers/rtc/rtc-cmos.c
... | ... | @@ -36,6 +36,7 @@ |
36 | 36 | #include <linux/platform_device.h> |
37 | 37 | #include <linux/mod_devicetable.h> |
38 | 38 | #include <linux/log2.h> |
39 | +#include <linux/pm.h> | |
39 | 40 | |
40 | 41 | /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ |
41 | 42 | #include <asm-generic/rtc.h> |
... | ... | @@ -851,7 +852,7 @@ |
851 | 852 | |
852 | 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 | 857 | struct cmos_rtc *cmos = dev_get_drvdata(dev); |
857 | 858 | unsigned char tmp; |
... | ... | @@ -899,7 +900,7 @@ |
899 | 900 | */ |
900 | 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 | 906 | static int cmos_resume(struct device *dev) |
906 | 907 | |
... | ... | @@ -946,9 +947,9 @@ |
946 | 947 | return 0; |
947 | 948 | } |
948 | 949 | |
950 | +static SIMPLE_DEV_PM_OPS(cmos_pm_ops, cmos_suspend, cmos_resume); | |
951 | + | |
949 | 952 | #else |
950 | -#define cmos_suspend NULL | |
951 | -#define cmos_resume NULL | |
952 | 953 | |
953 | 954 | static inline int cmos_poweroff(struct device *dev) |
954 | 955 | { |
... | ... | @@ -1078,7 +1079,7 @@ |
1078 | 1079 | |
1079 | 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 | 1085 | static int cmos_pnp_resume(struct pnp_dev *pnp) |
... | ... | @@ -1158,8 +1159,9 @@ |
1158 | 1159 | .shutdown = cmos_platform_shutdown, |
1159 | 1160 | .driver = { |
1160 | 1161 | .name = (char *) driver_name, |
1161 | - .suspend = cmos_suspend, | |
1162 | - .resume = cmos_resume, | |
1162 | +#ifdef CONFIG_PM | |
1163 | + .pm = &cmos_pm_ops, | |
1164 | +#endif | |
1163 | 1165 | } |
1164 | 1166 | }; |
1165 | 1167 |