Add the shutdown callback for cmos PNP device. At the same time when the system is poweroff, the RTC event will be enabled if RTC alarm is set. Signed-off-by : Rafael J. Wysocki Signed-off-by : Zhao Yakui Signed-off-by : Zhang Rui --- drivers/rtc/rtc-cmos.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) Index: linux-2.6/drivers/rtc/rtc-cmos.c =================================================================== --- linux-2.6.orig/drivers/rtc/rtc-cmos.c +++ linux-2.6/drivers/rtc/rtc-cmos.c @@ -800,7 +800,6 @@ static void __exit cmos_do_remove(struct static int cmos_suspend(struct device *dev, pm_message_t mesg) { struct cmos_rtc *cmos = dev_get_drvdata(dev); - int do_wake = device_may_wakeup(dev); unsigned char tmp; /* only the alarm might be a wakeup event source */ @@ -809,7 +808,7 @@ static int cmos_suspend(struct device *d if (tmp & (RTC_PIE|RTC_AIE|RTC_UIE)) { unsigned char mask; - if (do_wake) + if (device_may_wakeup(dev)) mask = RTC_IRQMASK & ~RTC_AIE; else mask = RTC_IRQMASK; @@ -837,6 +836,11 @@ static int cmos_suspend(struct device *d return 0; } +static inline int cmos_poweroff(struct device *dev) +{ + return cmos_suspend(dev, PMSG_HIBERNATE); +} + static int cmos_resume(struct device *dev) { struct cmos_rtc *cmos = dev_get_drvdata(dev); @@ -884,6 +888,8 @@ static int cmos_resume(struct device *de #else #define cmos_suspend NULL #define cmos_resume NULL + +static inline int cmos_poweroff(struct device *dev) { return -ENOSYS; } #endif /*----------------------------------------------------------------*/ @@ -942,6 +948,13 @@ static int cmos_pnp_resume(struct pnp_de #define cmos_pnp_resume NULL #endif +static void cmos_pnp_shutdown(struct device *pdev) +{ + if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(pdev)) + return; + + cmos_do_shutdown(); +} static const struct pnp_device_id rtc_ids[] = { { .id = "PNP0b00", }, @@ -961,6 +974,10 @@ static struct pnp_driver cmos_pnp_driver .flags = PNP_DRIVER_RES_DO_NOT_CHANGE, .suspend = cmos_pnp_suspend, .resume = cmos_pnp_resume, + .driver = { + .name = (char *)driver_name, + .shutdown = cmos_pnp_shutdown, + } }; #endif /* CONFIG_PNP */ @@ -986,6 +1003,9 @@ static int __exit cmos_platform_remove(s static void cmos_platform_shutdown(struct platform_device *pdev) { + if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(&pdev->dev)) + return; + cmos_do_shutdown(); }