All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mark Lord <lkml@rtr.ca>
To: Len Brown <lenb@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	David Brownell <david-b@pacbell.net>,
	lkml <linux-kernel@vger.kernel.org>,
	rtc-linux@googlegroups.com, linux-acpi@vger.kernel.org
Subject: [PATCH] /proc/acpi/alarm: handle day-of-month wraparound on readback
Date: Tue, 09 Dec 2008 10:46:30 -0500	[thread overview]
Message-ID: <493E92D6.8090104@rtr.ca> (raw)
In-Reply-To: <4934619A.10809@rtr.ca>

(repost)

Fix month wrap issue with readback from /proc/acpi/alarm
This bug has been around *forever*.

  $ echo '2008-12-01 10:36:20' > /proc/acpi/alarm
  $ cat /proc/acpi/alarm
  2008-11-01 10:36:20

Note how the readback above shows the month incorrectly
when the alarm is set in the *next* calendar month.
But with this patch applied, it shows the correct month (12).

This patch applies/works on 2.6.28-rc6.
Probably best to queue it up for the next major cycle.

Signed-off-by: Mark Lord <mlord@pobox.com>

--- old/drivers/acpi/sleep/proc.c	2008-11-20 18:19:22.000000000 -0500
+++ rc6/drivers/acpi/sleep/proc.c	2008-12-01 17:07:51.000000000 -0500
@@ -84,12 +84,15 @@
 #define	HAVE_ACPI_LEGACY_ALARM
 #endif
 
+static u32 cmos_bcd_read(int offset, int rtc_control);
+
 #ifdef	HAVE_ACPI_LEGACY_ALARM
 
 static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
 {
 	u32 sec, min, hr;
 	u32 day, mo, yr, cent = 0;
+	u32 today = 0;
 	unsigned char rtc_control = 0;
 	unsigned long flags;
 
@@ -97,38 +100,32 @@
 
 	spin_lock_irqsave(&rtc_lock, flags);
 
-	sec = CMOS_READ(RTC_SECONDS_ALARM);
-	min = CMOS_READ(RTC_MINUTES_ALARM);
-	hr = CMOS_READ(RTC_HOURS_ALARM);
 	rtc_control = CMOS_READ(RTC_CONTROL);
+	sec = cmos_bcd_read(RTC_SECONDS_ALARM, rtc_control);
+	min = cmos_bcd_read(RTC_MINUTES_ALARM, rtc_control);
+	hr = cmos_bcd_read(RTC_HOURS_ALARM, rtc_control);
 
 	/* If we ever get an FACP with proper values... */
-	if (acpi_gbl_FADT.day_alarm)
+	if (acpi_gbl_FADT.day_alarm) {
 		/* ACPI spec: only low 6 its should be cared */
 		day = CMOS_READ(acpi_gbl_FADT.day_alarm) & 0x3F;
-	else
-		day = CMOS_READ(RTC_DAY_OF_MONTH);
+		if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
+			day = bcd2bin(day);
+	} else
+		day = cmos_bcd_read(RTC_DAY_OF_MONTH, rtc_control);
 	if (acpi_gbl_FADT.month_alarm)
-		mo = CMOS_READ(acpi_gbl_FADT.month_alarm);
-	else
-		mo = CMOS_READ(RTC_MONTH);
+		mo = cmos_bcd_read(acpi_gbl_FADT.month_alarm, rtc_control);
+	else {
+		mo = cmos_bcd_read(RTC_MONTH, rtc_control);
+		today = cmos_bcd_read(RTC_DAY_OF_MONTH, rtc_control);
+	}
 	if (acpi_gbl_FADT.century)
-		cent = CMOS_READ(acpi_gbl_FADT.century);
+		cent = cmos_bcd_read(acpi_gbl_FADT.century, rtc_control);
 
-	yr = CMOS_READ(RTC_YEAR);
+	yr = cmos_bcd_read(RTC_YEAR, rtc_control);
 
 	spin_unlock_irqrestore(&rtc_lock, flags);
 
-	if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-		sec = bcd2bin(sec);
-		min = bcd2bin(min);
-		hr = bcd2bin(hr);
-		day = bcd2bin(day);
-		mo = bcd2bin(mo);
-		yr = bcd2bin(yr);
-		cent = bcd2bin(cent);
-	}
-
 	/* we're trusting the FADT (see above) */
 	if (!acpi_gbl_FADT.century)
 		/* If we're not trusting the FADT, we should at least make it
@@ -153,6 +150,20 @@
 	else
 		yr += cent * 100;
 
+	/*
+	 * Show correct dates for alarms up to a month into the future.
+	 * This solves issues for nearly all situations with the common
+	 * 30-day alarm clocks in PC hardware.
+	 */
+	if (day < today) {
+		if (mo < 12) {
+			mo += 1;
+		} else {
+			mo = 1;
+			yr += 1;
+		}
+	}
+
 	seq_printf(seq, "%4.4u-", yr);
 	(mo > 12) ? seq_puts(seq, "**-") : seq_printf(seq, "%2.2u-", mo);
 	(day > 31) ? seq_puts(seq, "** ") : seq_printf(seq, "%2.2u ", day);

  reply	other threads:[~2008-12-09 15:45 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-06-23  3:42 [patch 2.6.26-rc7] rtc_read_alarm() handles wraparound David Brownell
2008-06-25  8:59 ` [rtc-linux] " Alessandro Zummo
2008-12-01 16:57 ` PATCH: /proc/acpi/alarm: handle day-of-month wraparound on readback Mark Lord
2008-12-01 17:02   ` Mark Lord
2008-12-02 10:29     ` Tino Keitel
2008-12-02 18:54       ` Mark Lord
2008-12-02 18:54         ` Mark Lord
2008-12-01 18:18   ` Len Brown
2008-12-01 22:13     ` Mark Lord
2008-12-09 15:46       ` Mark Lord [this message]
2008-12-10  5:35         ` [PATCH] " Len Brown
2008-12-01 22:15     ` PATCH: " Mark Lord
2008-12-01 22:32       ` [rtc-linux] " Alessandro Zummo
2008-12-02 18:57         ` Mark Lord

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=493E92D6.8090104@rtr.ca \
    --to=lkml@rtr.ca \
    --cc=akpm@linux-foundation.org \
    --cc=david-b@pacbell.net \
    --cc=lenb@kernel.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rtc-linux@googlegroups.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.