Commit c46ce3f5 authored by Len Brown's avatar Len Brown Committed by Len Brown

[ACPI] S3 resume using RTC

http://bugzilla.kernel.org/show_bug.cgi?id=1320

By: Patrick Mochel, Karol Kozimor, Shaohua Li
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 211001b9
...@@ -83,6 +83,7 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) ...@@ -83,6 +83,7 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
{ {
u32 sec, min, hr; u32 sec, min, hr;
u32 day, mo, yr; u32 day, mo, yr;
unsigned char rtc_control = 0;
ACPI_FUNCTION_TRACE("acpi_system_alarm_seq_show"); ACPI_FUNCTION_TRACE("acpi_system_alarm_seq_show");
...@@ -91,10 +92,12 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) ...@@ -91,10 +92,12 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
sec = CMOS_READ(RTC_SECONDS_ALARM); sec = CMOS_READ(RTC_SECONDS_ALARM);
min = CMOS_READ(RTC_MINUTES_ALARM); min = CMOS_READ(RTC_MINUTES_ALARM);
hr = CMOS_READ(RTC_HOURS_ALARM); hr = CMOS_READ(RTC_HOURS_ALARM);
rtc_control = CMOS_READ(RTC_CONTROL);
#if 0 /* If we ever get an FACP with proper values... */ /* If we ever get an FACP with proper values... */
if (acpi_gbl_FADT->day_alrm) if (acpi_gbl_FADT->day_alrm)
day = CMOS_READ(acpi_gbl_FADT->day_alrm); /* ACPI spec: only low 6 its should be cared */
day = CMOS_READ(acpi_gbl_FADT->day_alrm) & 0x3F;
else else
day = CMOS_READ(RTC_DAY_OF_MONTH); day = CMOS_READ(RTC_DAY_OF_MONTH);
if (acpi_gbl_FADT->mon_alrm) if (acpi_gbl_FADT->mon_alrm)
...@@ -105,24 +108,20 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) ...@@ -105,24 +108,20 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
yr = CMOS_READ(acpi_gbl_FADT->century) * 100 + CMOS_READ(RTC_YEAR); yr = CMOS_READ(acpi_gbl_FADT->century) * 100 + CMOS_READ(RTC_YEAR);
else else
yr = CMOS_READ(RTC_YEAR); yr = CMOS_READ(RTC_YEAR);
#else
day = CMOS_READ(RTC_DAY_OF_MONTH);
mo = CMOS_READ(RTC_MONTH);
yr = CMOS_READ(RTC_YEAR);
#endif
spin_unlock(&rtc_lock); spin_unlock(&rtc_lock);
BCD_TO_BIN(sec); if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
BCD_TO_BIN(min); BCD_TO_BIN(sec);
BCD_TO_BIN(hr); BCD_TO_BIN(min);
BCD_TO_BIN(day); BCD_TO_BIN(hr);
BCD_TO_BIN(mo); BCD_TO_BIN(day);
BCD_TO_BIN(yr); BCD_TO_BIN(mo);
BCD_TO_BIN(yr);
}
#if 0
/* we're trusting the FADT (see above)*/ /* we're trusting the FADT (see above)*/
#else if (!acpi_gbl_FADT->century)
/* If we're not trusting the FADT, we should at least make it /* If we're not trusting the FADT, we should at least make it
* right for _this_ century... ehm, what is _this_ century? * right for _this_ century... ehm, what is _this_ century?
* *
...@@ -141,8 +140,7 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) ...@@ -141,8 +140,7 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
* s/2000/2100 * s/2000/2100
* *
*/ */
yr += 2000; yr += 2000;
#endif
seq_printf(seq,"%4.4u-", yr); seq_printf(seq,"%4.4u-", yr);
(mo > 12) ? seq_puts(seq, "**-") : seq_printf(seq, "%2.2u-", mo); (mo > 12) ? seq_puts(seq, "**-") : seq_printf(seq, "%2.2u-", mo);
...@@ -316,6 +314,13 @@ acpi_system_write_alarm ( ...@@ -316,6 +314,13 @@ acpi_system_write_alarm (
} }
spin_lock_irq(&rtc_lock); spin_lock_irq(&rtc_lock);
/*
* Disable alarm interrupt before setting alarm timer or else
* when ACPI_EVENT_RTC is enabled, a spurious ACPI interrupt occurs
*/
rtc_control &= ~RTC_AIE;
CMOS_WRITE(rtc_control, RTC_CONTROL);
CMOS_READ(RTC_INTR_FLAGS);
/* write the fields the rtc knows about */ /* write the fields the rtc knows about */
CMOS_WRITE(hr, RTC_HOURS_ALARM); CMOS_WRITE(hr, RTC_HOURS_ALARM);
...@@ -327,24 +332,21 @@ acpi_system_write_alarm ( ...@@ -327,24 +332,21 @@ acpi_system_write_alarm (
* offsets into the CMOS RAM here -- which for some reason are pointing * offsets into the CMOS RAM here -- which for some reason are pointing
* to the RTC area of memory. * to the RTC area of memory.
*/ */
#if 0
if (acpi_gbl_FADT->day_alrm) if (acpi_gbl_FADT->day_alrm)
CMOS_WRITE(day, acpi_gbl_FADT->day_alrm); CMOS_WRITE(day, acpi_gbl_FADT->day_alrm);
if (acpi_gbl_FADT->mon_alrm) if (acpi_gbl_FADT->mon_alrm)
CMOS_WRITE(mo, acpi_gbl_FADT->mon_alrm); CMOS_WRITE(mo, acpi_gbl_FADT->mon_alrm);
if (acpi_gbl_FADT->century) if (acpi_gbl_FADT->century)
CMOS_WRITE(yr/100, acpi_gbl_FADT->century); CMOS_WRITE(yr/100, acpi_gbl_FADT->century);
#endif
/* enable the rtc alarm interrupt */ /* enable the rtc alarm interrupt */
if (!(rtc_control & RTC_AIE)) { rtc_control |= RTC_AIE;
rtc_control |= RTC_AIE; CMOS_WRITE(rtc_control, RTC_CONTROL);
CMOS_WRITE(rtc_control,RTC_CONTROL); CMOS_READ(RTC_INTR_FLAGS);
CMOS_READ(RTC_INTR_FLAGS);
}
spin_unlock_irq(&rtc_lock); spin_unlock_irq(&rtc_lock);
acpi_set_register(ACPI_BITREG_RT_CLOCK_ENABLE, 1, ACPI_MTX_LOCK); acpi_clear_event(ACPI_EVENT_RTC);
acpi_enable_event(ACPI_EVENT_RTC, 0);
*ppos += count; *ppos += count;
...@@ -449,6 +451,14 @@ static struct file_operations acpi_system_alarm_fops = { ...@@ -449,6 +451,14 @@ static struct file_operations acpi_system_alarm_fops = {
}; };
static u32 rtc_handler(void * context)
{
acpi_clear_event(ACPI_EVENT_RTC);
acpi_disable_event(ACPI_EVENT_RTC, 0);
return ACPI_INTERRUPT_HANDLED;
}
static int acpi_sleep_proc_init(void) static int acpi_sleep_proc_init(void)
{ {
struct proc_dir_entry *entry = NULL; struct proc_dir_entry *entry = NULL;
...@@ -474,6 +484,7 @@ static int acpi_sleep_proc_init(void) ...@@ -474,6 +484,7 @@ static int acpi_sleep_proc_init(void)
if (entry) if (entry)
entry->proc_fops = &acpi_system_wakeup_device_fops; entry->proc_fops = &acpi_system_wakeup_device_fops;
acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment