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)
{
u32 sec, min, hr;
u32 day, mo, yr;
unsigned char rtc_control = 0;
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)
sec = CMOS_READ(RTC_SECONDS_ALARM);
min = CMOS_READ(RTC_MINUTES_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)
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
day = CMOS_READ(RTC_DAY_OF_MONTH);
if (acpi_gbl_FADT->mon_alrm)
......@@ -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);
else
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);
BCD_TO_BIN(sec);
BCD_TO_BIN(min);
BCD_TO_BIN(hr);
BCD_TO_BIN(day);
BCD_TO_BIN(mo);
BCD_TO_BIN(yr);
if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
BCD_TO_BIN(sec);
BCD_TO_BIN(min);
BCD_TO_BIN(hr);
BCD_TO_BIN(day);
BCD_TO_BIN(mo);
BCD_TO_BIN(yr);
}
#if 0
/* 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
* 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)
* s/2000/2100
*
*/
yr += 2000;
#endif
yr += 2000;
seq_printf(seq,"%4.4u-", yr);
(mo > 12) ? seq_puts(seq, "**-") : seq_printf(seq, "%2.2u-", mo);
......@@ -316,6 +314,13 @@ acpi_system_write_alarm (
}
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 */
CMOS_WRITE(hr, RTC_HOURS_ALARM);
......@@ -327,24 +332,21 @@ acpi_system_write_alarm (
* offsets into the CMOS RAM here -- which for some reason are pointing
* to the RTC area of memory.
*/
#if 0
if (acpi_gbl_FADT->day_alrm)
CMOS_WRITE(day, acpi_gbl_FADT->day_alrm);
if (acpi_gbl_FADT->mon_alrm)
CMOS_WRITE(mo, acpi_gbl_FADT->mon_alrm);
if (acpi_gbl_FADT->century)
CMOS_WRITE(yr/100, acpi_gbl_FADT->century);
#endif
/* enable the rtc alarm interrupt */
if (!(rtc_control & RTC_AIE)) {
rtc_control |= RTC_AIE;
CMOS_WRITE(rtc_control,RTC_CONTROL);
CMOS_READ(RTC_INTR_FLAGS);
}
rtc_control |= RTC_AIE;
CMOS_WRITE(rtc_control, RTC_CONTROL);
CMOS_READ(RTC_INTR_FLAGS);
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;
......@@ -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)
{
struct proc_dir_entry *entry = NULL;
......@@ -474,6 +484,7 @@ static int acpi_sleep_proc_init(void)
if (entry)
entry->proc_fops = &acpi_system_wakeup_device_fops;
acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL);
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