aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-09-16 17:11:43 -0400
committerDavid S. Miller <davem@davemloft.net>2008-09-16 17:11:43 -0400
commit2e57572a50a4de41c6cbc879a4866a312d4cd316 (patch)
treec4f58ec96c06642c4b415b881d3f0a3b673d5b44 /drivers/rtc
parent9b2e43ae4e9609f80034dfe8de895045cac52d77 (diff)
parentf948cc6ab9e61a8e88d70ee9aafc690e6d26f92c (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
Conflicts: arch/sparc64/kernel/pci_psycho.c
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/rtc-cmos.c38
-rw-r--r--drivers/rtc/rtc-lib.c5
2 files changed, 35 insertions, 8 deletions
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index 04ecfd2e7c88..b23af0c2a869 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -801,7 +801,6 @@ static void __exit cmos_do_remove(struct device *dev)
801static int cmos_suspend(struct device *dev, pm_message_t mesg) 801static int cmos_suspend(struct device *dev, pm_message_t mesg)
802{ 802{
803 struct cmos_rtc *cmos = dev_get_drvdata(dev); 803 struct cmos_rtc *cmos = dev_get_drvdata(dev);
804 int do_wake = device_may_wakeup(dev);
805 unsigned char tmp; 804 unsigned char tmp;
806 805
807 /* only the alarm might be a wakeup event source */ 806 /* only the alarm might be a wakeup event source */
@@ -810,7 +809,7 @@ static int cmos_suspend(struct device *dev, pm_message_t mesg)
810 if (tmp & (RTC_PIE|RTC_AIE|RTC_UIE)) { 809 if (tmp & (RTC_PIE|RTC_AIE|RTC_UIE)) {
811 unsigned char mask; 810 unsigned char mask;
812 811
813 if (do_wake) 812 if (device_may_wakeup(dev))
814 mask = RTC_IRQMASK & ~RTC_AIE; 813 mask = RTC_IRQMASK & ~RTC_AIE;
815 else 814 else
816 mask = RTC_IRQMASK; 815 mask = RTC_IRQMASK;
@@ -838,6 +837,17 @@ static int cmos_suspend(struct device *dev, pm_message_t mesg)
838 return 0; 837 return 0;
839} 838}
840 839
840/* We want RTC alarms to wake us from e.g. ACPI G2/S5 "soft off", even
841 * after a detour through G3 "mechanical off", although the ACPI spec
842 * says wakeup should only work from G1/S4 "hibernate". To most users,
843 * distinctions between S4 and S5 are pointless. So when the hardware
844 * allows, don't draw that distinction.
845 */
846static inline int cmos_poweroff(struct device *dev)
847{
848 return cmos_suspend(dev, PMSG_HIBERNATE);
849}
850
841static int cmos_resume(struct device *dev) 851static int cmos_resume(struct device *dev)
842{ 852{
843 struct cmos_rtc *cmos = dev_get_drvdata(dev); 853 struct cmos_rtc *cmos = dev_get_drvdata(dev);
@@ -885,6 +895,12 @@ static int cmos_resume(struct device *dev)
885#else 895#else
886#define cmos_suspend NULL 896#define cmos_suspend NULL
887#define cmos_resume NULL 897#define cmos_resume NULL
898
899static inline int cmos_poweroff(struct device *dev)
900{
901 return -ENOSYS;
902}
903
888#endif 904#endif
889 905
890/*----------------------------------------------------------------*/ 906/*----------------------------------------------------------------*/
@@ -904,10 +920,6 @@ static int cmos_resume(struct device *dev)
904static int __devinit 920static int __devinit
905cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) 921cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
906{ 922{
907 /* REVISIT paranoia argues for a shutdown notifier, since PNP
908 * drivers can't provide shutdown() methods to disable IRQs.
909 * Or better yet, fix PNP to allow those methods...
910 */
911 if (pnp_port_start(pnp,0) == 0x70 && !pnp_irq_valid(pnp,0)) 923 if (pnp_port_start(pnp,0) == 0x70 && !pnp_irq_valid(pnp,0))
912 /* Some machines contain a PNP entry for the RTC, but 924 /* Some machines contain a PNP entry for the RTC, but
913 * don't define the IRQ. It should always be safe to 925 * don't define the IRQ. It should always be safe to
@@ -943,6 +955,13 @@ static int cmos_pnp_resume(struct pnp_dev *pnp)
943#define cmos_pnp_resume NULL 955#define cmos_pnp_resume NULL
944#endif 956#endif
945 957
958static void cmos_pnp_shutdown(struct device *pdev)
959{
960 if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(pdev))
961 return;
962
963 cmos_do_shutdown();
964}
946 965
947static const struct pnp_device_id rtc_ids[] = { 966static const struct pnp_device_id rtc_ids[] = {
948 { .id = "PNP0b00", }, 967 { .id = "PNP0b00", },
@@ -962,6 +981,10 @@ static struct pnp_driver cmos_pnp_driver = {
962 .flags = PNP_DRIVER_RES_DO_NOT_CHANGE, 981 .flags = PNP_DRIVER_RES_DO_NOT_CHANGE,
963 .suspend = cmos_pnp_suspend, 982 .suspend = cmos_pnp_suspend,
964 .resume = cmos_pnp_resume, 983 .resume = cmos_pnp_resume,
984 .driver = {
985 .name = (char *)driver_name,
986 .shutdown = cmos_pnp_shutdown,
987 }
965}; 988};
966 989
967#endif /* CONFIG_PNP */ 990#endif /* CONFIG_PNP */
@@ -987,6 +1010,9 @@ static int __exit cmos_platform_remove(struct platform_device *pdev)
987 1010
988static void cmos_platform_shutdown(struct platform_device *pdev) 1011static void cmos_platform_shutdown(struct platform_device *pdev)
989{ 1012{
1013 if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(&pdev->dev))
1014 return;
1015
990 cmos_do_shutdown(); 1016 cmos_do_shutdown();
991} 1017}
992 1018
diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c
index 9f996ec881ce..dd70bf73ce9d 100644
--- a/drivers/rtc/rtc-lib.c
+++ b/drivers/rtc/rtc-lib.c
@@ -51,10 +51,11 @@ EXPORT_SYMBOL(rtc_year_days);
51 */ 51 */
52void rtc_time_to_tm(unsigned long time, struct rtc_time *tm) 52void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
53{ 53{
54 unsigned int days, month, year; 54 unsigned int month, year;
55 int days;
55 56
56 days = time / 86400; 57 days = time / 86400;
57 time -= days * 86400; 58 time -= (unsigned int) days * 86400;
58 59
59 /* day of the week, 1970-01-01 was a Thursday */ 60 /* day of the week, 1970-01-01 was a Thursday */
60 tm->tm_wday = (days + 4) % 7; 61 tm->tm_wday = (days + 4) % 7;