48
48
/* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */
49
49
#include <linux/mc146818rtc.h>
50
50
51
+ /*
52
+ * Use ACPI SCI to replace HPET interrupt for RTC Alarm event
53
+ *
54
+ * If cleared, ACPI SCI is only used to wake up the system from suspend
55
+ *
56
+ * If set, ACPI SCI is used to handle UIE/AIE and system wakeup
57
+ */
58
+
59
+ static bool use_acpi_alarm ;
60
+ module_param (use_acpi_alarm , bool , 0444 );
61
+
51
62
struct cmos_rtc {
52
63
struct rtc_device * rtc ;
53
64
struct device * dev ;
@@ -153,6 +164,12 @@ static inline int hpet_unregister_irq_handler(irq_handler_t handler)
153
164
154
165
#endif
155
166
167
+ /* Don't use HPET for RTC Alarm event if ACPI Fixed event is used */
168
+ static int use_hpet_alarm (void )
169
+ {
170
+ return is_hpet_enabled () && !use_acpi_alarm ;
171
+ }
172
+
156
173
/*----------------------------------------------------------------*/
157
174
158
175
#ifdef RTC_PORT
@@ -298,7 +315,7 @@ static void cmos_checkintr(struct cmos_rtc *cmos, unsigned char rtc_control)
298
315
*/
299
316
rtc_intr = CMOS_READ (RTC_INTR_FLAGS );
300
317
301
- if (is_hpet_enabled ())
318
+ if (use_hpet_alarm ())
302
319
return ;
303
320
304
321
rtc_intr &= (rtc_control & RTC_IRQMASK ) | RTC_IRQF ;
@@ -318,7 +335,13 @@ static void cmos_irq_enable(struct cmos_rtc *cmos, unsigned char mask)
318
335
319
336
rtc_control |= mask ;
320
337
CMOS_WRITE (rtc_control , RTC_CONTROL );
321
- hpet_set_rtc_irq_bit (mask );
338
+ if (use_hpet_alarm ())
339
+ hpet_set_rtc_irq_bit (mask );
340
+
341
+ if ((mask & RTC_AIE ) && use_acpi_alarm ) {
342
+ if (cmos -> wake_on )
343
+ cmos -> wake_on (cmos -> dev );
344
+ }
322
345
323
346
cmos_checkintr (cmos , rtc_control );
324
347
}
@@ -330,7 +353,13 @@ static void cmos_irq_disable(struct cmos_rtc *cmos, unsigned char mask)
330
353
rtc_control = CMOS_READ (RTC_CONTROL );
331
354
rtc_control &= ~mask ;
332
355
CMOS_WRITE (rtc_control , RTC_CONTROL );
333
- hpet_mask_rtc_irq_bit (mask );
356
+ if (use_hpet_alarm ())
357
+ hpet_mask_rtc_irq_bit (mask );
358
+
359
+ if ((mask & RTC_AIE ) && use_acpi_alarm ) {
360
+ if (cmos -> wake_off )
361
+ cmos -> wake_off (cmos -> dev );
362
+ }
334
363
335
364
cmos_checkintr (cmos , rtc_control );
336
365
}
@@ -448,10 +477,14 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)
448
477
CMOS_WRITE (mon , cmos -> mon_alrm );
449
478
}
450
479
451
- /* FIXME the HPET alarm glue currently ignores day_alrm
452
- * and mon_alrm ...
453
- */
454
- hpet_set_alarm_time (t -> time .tm_hour , t -> time .tm_min , t -> time .tm_sec );
480
+ if (use_hpet_alarm ()) {
481
+ /*
482
+ * FIXME the HPET alarm glue currently ignores day_alrm
483
+ * and mon_alrm ...
484
+ */
485
+ hpet_set_alarm_time (t -> time .tm_hour , t -> time .tm_min ,
486
+ t -> time .tm_sec );
487
+ }
455
488
456
489
if (t -> enabled )
457
490
cmos_irq_enable (cmos , RTC_AIE );
@@ -508,7 +541,7 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq)
508
541
"batt_status\t: %s\n" ,
509
542
(rtc_control & RTC_PIE ) ? "yes" : "no" ,
510
543
(rtc_control & RTC_UIE ) ? "yes" : "no" ,
511
- is_hpet_enabled () ? "yes" : "no" ,
544
+ use_hpet_alarm () ? "yes" : "no" ,
512
545
// (rtc_control & RTC_SQWE) ? "yes" : "no",
513
546
(rtc_control & RTC_DM_BINARY ) ? "no" : "yes" ,
514
547
(rtc_control & RTC_DST_EN ) ? "yes" : "no" ,
@@ -614,7 +647,7 @@ static irqreturn_t cmos_interrupt(int irq, void *p)
614
647
*/
615
648
irqstat = CMOS_READ (RTC_INTR_FLAGS );
616
649
rtc_control = CMOS_READ (RTC_CONTROL );
617
- if (is_hpet_enabled ())
650
+ if (use_hpet_alarm ())
618
651
irqstat = (unsigned long )irq & 0xF0 ;
619
652
620
653
/* If we were suspended, RTC_CONTROL may not be accurate since the
@@ -633,7 +666,8 @@ static irqreturn_t cmos_interrupt(int irq, void *p)
633
666
cmos_rtc .suspend_ctrl &= ~RTC_AIE ;
634
667
rtc_control &= ~RTC_AIE ;
635
668
CMOS_WRITE (rtc_control , RTC_CONTROL );
636
- hpet_mask_rtc_irq_bit (RTC_AIE );
669
+ if (use_hpet_alarm ())
670
+ hpet_mask_rtc_irq_bit (RTC_AIE );
637
671
CMOS_READ (RTC_INTR_FLAGS );
638
672
}
639
673
spin_unlock (& rtc_lock );
@@ -762,7 +796,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
762
796
* need to do something about other clock frequencies.
763
797
*/
764
798
cmos_rtc .rtc -> irq_freq = 1024 ;
765
- hpet_set_periodic_freq (cmos_rtc .rtc -> irq_freq );
799
+ if (use_hpet_alarm ())
800
+ hpet_set_periodic_freq (cmos_rtc .rtc -> irq_freq );
766
801
CMOS_WRITE (RTC_REF_CLCK_32KHZ | 0x06 , RTC_FREQ_SELECT );
767
802
}
768
803
@@ -780,12 +815,13 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
780
815
goto cleanup1 ;
781
816
}
782
817
783
- hpet_rtc_timer_init ();
818
+ if (use_hpet_alarm ())
819
+ hpet_rtc_timer_init ();
784
820
785
821
if (is_valid_irq (rtc_irq )) {
786
822
irq_handler_t rtc_cmos_int_handler ;
787
823
788
- if (is_hpet_enabled ()) {
824
+ if (use_hpet_alarm ()) {
789
825
rtc_cmos_int_handler = hpet_rtc_interrupt ;
790
826
retval = hpet_register_irq_handler (cmos_interrupt );
791
827
if (retval ) {
@@ -824,7 +860,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
824
860
"alarms up to one day" ,
825
861
cmos_rtc .century ? ", y3k" : "" ,
826
862
nvmem_cfg .size ,
827
- is_hpet_enabled () ? ", hpet irqs" : "" );
863
+ use_hpet_alarm () ? ", hpet irqs" : "" );
828
864
829
865
return 0 ;
830
866
@@ -858,7 +894,8 @@ static void cmos_do_remove(struct device *dev)
858
894
859
895
if (is_valid_irq (cmos -> irq )) {
860
896
free_irq (cmos -> irq , cmos -> rtc );
861
- hpet_unregister_irq_handler (cmos_interrupt );
897
+ if (use_hpet_alarm ())
898
+ hpet_unregister_irq_handler (cmos_interrupt );
862
899
}
863
900
864
901
cmos -> rtc = NULL ;
@@ -935,13 +972,13 @@ static int cmos_suspend(struct device *dev)
935
972
mask = RTC_IRQMASK ;
936
973
tmp &= ~mask ;
937
974
CMOS_WRITE (tmp , RTC_CONTROL );
938
- hpet_mask_rtc_irq_bit ( mask );
939
-
975
+ if ( use_hpet_alarm ())
976
+ hpet_mask_rtc_irq_bit ( mask );
940
977
cmos_checkintr (cmos , tmp );
941
978
}
942
979
spin_unlock_irq (& rtc_lock );
943
980
944
- if (tmp & RTC_AIE ) {
981
+ if (( tmp & RTC_AIE ) && ! use_acpi_alarm ) {
945
982
cmos -> enabled_wake = 1 ;
946
983
if (cmos -> wake_on )
947
984
cmos -> wake_on (dev );
@@ -996,7 +1033,7 @@ static int __maybe_unused cmos_resume(struct device *dev)
996
1033
struct cmos_rtc * cmos = dev_get_drvdata (dev );
997
1034
unsigned char tmp ;
998
1035
999
- if (cmos -> enabled_wake ) {
1036
+ if (cmos -> enabled_wake && ! use_acpi_alarm ) {
1000
1037
if (cmos -> wake_off )
1001
1038
cmos -> wake_off (dev );
1002
1039
else
@@ -1014,16 +1051,17 @@ static int __maybe_unused cmos_resume(struct device *dev)
1014
1051
if (tmp & RTC_IRQMASK ) {
1015
1052
unsigned char mask ;
1016
1053
1017
- if (device_may_wakeup (dev ))
1054
+ if (device_may_wakeup (dev ) && use_hpet_alarm () )
1018
1055
hpet_rtc_timer_init ();
1019
1056
1020
1057
do {
1021
1058
CMOS_WRITE (tmp , RTC_CONTROL );
1022
- hpet_set_rtc_irq_bit (tmp & RTC_IRQMASK );
1059
+ if (use_hpet_alarm ())
1060
+ hpet_set_rtc_irq_bit (tmp & RTC_IRQMASK );
1023
1061
1024
1062
mask = CMOS_READ (RTC_INTR_FLAGS );
1025
1063
mask &= (tmp & RTC_IRQMASK ) | RTC_IRQF ;
1026
- if (!is_hpet_enabled () || !is_intr (mask ))
1064
+ if (!use_hpet_alarm () || !is_intr (mask ))
1027
1065
break ;
1028
1066
1029
1067
/* force one-shot behavior if HPET blocked
@@ -1068,16 +1106,27 @@ static u32 rtc_handler(void *context)
1068
1106
unsigned char rtc_intr ;
1069
1107
unsigned long flags ;
1070
1108
1071
- spin_lock_irqsave (& rtc_lock , flags );
1072
- if (cmos_rtc .suspend_ctrl )
1073
- rtc_control = CMOS_READ (RTC_CONTROL );
1074
- if (rtc_control & RTC_AIE ) {
1075
- cmos_rtc .suspend_ctrl &= ~RTC_AIE ;
1076
- CMOS_WRITE (rtc_control , RTC_CONTROL );
1077
- rtc_intr = CMOS_READ (RTC_INTR_FLAGS );
1078
- rtc_update_irq (cmos -> rtc , 1 , rtc_intr );
1109
+
1110
+ /*
1111
+ * Always update rtc irq when ACPI is used as RTC Alarm.
1112
+ * Or else, ACPI SCI is enabled during suspend/resume only,
1113
+ * update rtc irq in that case.
1114
+ */
1115
+ if (use_acpi_alarm )
1116
+ cmos_interrupt (0 , (void * )cmos -> rtc );
1117
+ else {
1118
+ /* Fix me: can we use cmos_interrupt() here as well? */
1119
+ spin_lock_irqsave (& rtc_lock , flags );
1120
+ if (cmos_rtc .suspend_ctrl )
1121
+ rtc_control = CMOS_READ (RTC_CONTROL );
1122
+ if (rtc_control & RTC_AIE ) {
1123
+ cmos_rtc .suspend_ctrl &= ~RTC_AIE ;
1124
+ CMOS_WRITE (rtc_control , RTC_CONTROL );
1125
+ rtc_intr = CMOS_READ (RTC_INTR_FLAGS );
1126
+ rtc_update_irq (cmos -> rtc , 1 , rtc_intr );
1127
+ }
1128
+ spin_unlock_irqrestore (& rtc_lock , flags );
1079
1129
}
1080
- spin_unlock_irqrestore (& rtc_lock , flags );
1081
1130
1082
1131
pm_wakeup_hard_event (dev );
1083
1132
acpi_clear_event (ACPI_EVENT_RTC );
0 commit comments