diff options
| -rw-r--r-- | drivers/acpi/proc.c | 53 |
1 files changed, 32 insertions, 21 deletions
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c index 1c4851ff2657..428c911dba08 100644 --- a/drivers/acpi/proc.c +++ b/drivers/acpi/proc.c | |||
| @@ -84,47 +84,44 @@ acpi_system_write_sleep(struct file *file, | |||
| 84 | 84 | ||
| 85 | #ifdef HAVE_ACPI_LEGACY_ALARM | 85 | #ifdef HAVE_ACPI_LEGACY_ALARM |
| 86 | 86 | ||
| 87 | static u32 cmos_bcd_read(int offset, int rtc_control); | ||
| 88 | |||
| 87 | static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) | 89 | static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) |
| 88 | { | 90 | { |
| 89 | u32 sec, min, hr; | 91 | u32 sec, min, hr; |
| 90 | u32 day, mo, yr, cent = 0; | 92 | u32 day, mo, yr, cent = 0; |
| 93 | u32 today = 0; | ||
| 91 | unsigned char rtc_control = 0; | 94 | unsigned char rtc_control = 0; |
| 92 | unsigned long flags; | 95 | unsigned long flags; |
| 93 | 96 | ||
| 94 | spin_lock_irqsave(&rtc_lock, flags); | 97 | spin_lock_irqsave(&rtc_lock, flags); |
| 95 | 98 | ||
| 96 | sec = CMOS_READ(RTC_SECONDS_ALARM); | ||
| 97 | min = CMOS_READ(RTC_MINUTES_ALARM); | ||
| 98 | hr = CMOS_READ(RTC_HOURS_ALARM); | ||
| 99 | rtc_control = CMOS_READ(RTC_CONTROL); | 99 | rtc_control = CMOS_READ(RTC_CONTROL); |
| 100 | sec = cmos_bcd_read(RTC_SECONDS_ALARM, rtc_control); | ||
| 101 | min = cmos_bcd_read(RTC_MINUTES_ALARM, rtc_control); | ||
| 102 | hr = cmos_bcd_read(RTC_HOURS_ALARM, rtc_control); | ||
| 100 | 103 | ||
| 101 | /* If we ever get an FACP with proper values... */ | 104 | /* If we ever get an FACP with proper values... */ |
| 102 | if (acpi_gbl_FADT.day_alarm) | 105 | if (acpi_gbl_FADT.day_alarm) { |
| 103 | /* ACPI spec: only low 6 its should be cared */ | 106 | /* ACPI spec: only low 6 its should be cared */ |
| 104 | day = CMOS_READ(acpi_gbl_FADT.day_alarm) & 0x3F; | 107 | day = CMOS_READ(acpi_gbl_FADT.day_alarm) & 0x3F; |
| 105 | else | 108 | if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) |
| 106 | day = CMOS_READ(RTC_DAY_OF_MONTH); | 109 | day = bcd2bin(day); |
| 110 | } else | ||
| 111 | day = cmos_bcd_read(RTC_DAY_OF_MONTH, rtc_control); | ||
| 107 | if (acpi_gbl_FADT.month_alarm) | 112 | if (acpi_gbl_FADT.month_alarm) |
| 108 | mo = CMOS_READ(acpi_gbl_FADT.month_alarm); | 113 | mo = cmos_bcd_read(acpi_gbl_FADT.month_alarm, rtc_control); |
| 109 | else | 114 | else { |
| 110 | mo = CMOS_READ(RTC_MONTH); | 115 | mo = cmos_bcd_read(RTC_MONTH, rtc_control); |
| 116 | today = cmos_bcd_read(RTC_DAY_OF_MONTH, rtc_control); | ||
| 117 | } | ||
| 111 | if (acpi_gbl_FADT.century) | 118 | if (acpi_gbl_FADT.century) |
| 112 | cent = CMOS_READ(acpi_gbl_FADT.century); | 119 | cent = cmos_bcd_read(acpi_gbl_FADT.century, rtc_control); |
| 113 | 120 | ||
| 114 | yr = CMOS_READ(RTC_YEAR); | 121 | yr = cmos_bcd_read(RTC_YEAR, rtc_control); |
| 115 | 122 | ||
| 116 | spin_unlock_irqrestore(&rtc_lock, flags); | 123 | spin_unlock_irqrestore(&rtc_lock, flags); |
| 117 | 124 | ||
| 118 | if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { | ||
| 119 | sec = bcd2bin(sec); | ||
| 120 | min = bcd2bin(min); | ||
| 121 | hr = bcd2bin(hr); | ||
| 122 | day = bcd2bin(day); | ||
| 123 | mo = bcd2bin(mo); | ||
| 124 | yr = bcd2bin(yr); | ||
| 125 | cent = bcd2bin(cent); | ||
| 126 | } | ||
| 127 | |||
| 128 | /* we're trusting the FADT (see above) */ | 125 | /* we're trusting the FADT (see above) */ |
| 129 | if (!acpi_gbl_FADT.century) | 126 | if (!acpi_gbl_FADT.century) |
| 130 | /* If we're not trusting the FADT, we should at least make it | 127 | /* If we're not trusting the FADT, we should at least make it |
| @@ -149,6 +146,20 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) | |||
| 149 | else | 146 | else |
| 150 | yr += cent * 100; | 147 | yr += cent * 100; |
| 151 | 148 | ||
| 149 | /* | ||
| 150 | * Show correct dates for alarms up to a month into the future. | ||
| 151 | * This solves issues for nearly all situations with the common | ||
| 152 | * 30-day alarm clocks in PC hardware. | ||
| 153 | */ | ||
| 154 | if (day < today) { | ||
| 155 | if (mo < 12) { | ||
| 156 | mo += 1; | ||
| 157 | } else { | ||
| 158 | mo = 1; | ||
| 159 | yr += 1; | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 152 | seq_printf(seq, "%4.4u-", yr); | 163 | seq_printf(seq, "%4.4u-", yr); |
| 153 | (mo > 12) ? seq_puts(seq, "**-") : seq_printf(seq, "%2.2u-", mo); | 164 | (mo > 12) ? seq_puts(seq, "**-") : seq_printf(seq, "%2.2u-", mo); |
| 154 | (day > 31) ? seq_puts(seq, "** ") : seq_printf(seq, "%2.2u ", day); | 165 | (day > 31) ? seq_puts(seq, "** ") : seq_printf(seq, "%2.2u ", day); |
