Patchwork [1/2] RTC: pl031: configured correct wday for 2000-01-01

login
register
mail settings
Submitter Linus Walleij
Date May 14, 2012, 9:16 a.m.
Message ID <1336987007-19027-1-git-send-email-linus.walleij@stericsson.com>
Download mbox | patch
Permalink /patch/158957/
State New
Headers show

Comments

Linus Walleij - May 14, 2012, 9:16 a.m.
From: Rajkumar Kasirajan <rajkumar.kasirajan@stericsson.com>

The reset date of the ST Micro version of PL031 is
2000-01-01. The correct weekday for 2000-01-01 is saturday, but pl031
is initialized to sunday. This may lead to alarm malfunction, so
configure the correct wday if RTC_DR indicates reset.

Cc: Mattias Wallin <mattias.wallin@stericsson.com>
Signed-off-by: Rajkumar Kasirajan <rajkumar.kasirajan@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/rtc/rtc-pl031.c |   18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

Patch

diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c
index 684ef4b..f027c06 100644
--- a/drivers/rtc/rtc-pl031.c
+++ b/drivers/rtc/rtc-pl031.c
@@ -312,6 +312,7 @@  static int pl031_probe(struct amba_device *adev, const struct amba_id *id)
 	int ret;
 	struct pl031_local *ldata;
 	struct rtc_class_ops *ops = id->data;
+	unsigned long time;
 
 	ret = amba_request_regions(adev, NULL);
 	if (ret)
@@ -343,6 +344,23 @@  static int pl031_probe(struct amba_device *adev, const struct amba_id *id)
 		writel(readl(ldata->base + RTC_CR) | RTC_CR_CWEN,
 		       ldata->base + RTC_CR);
 
+	/*
+	 * On ST PL031 variants, the RTC reset value does not provide correct
+	 * weekday for 2000-01-01. Correct the erroneous sunday to saturday.
+	 */
+	if (ldata->hw_designer == AMBA_VENDOR_ST) {
+		if (readl(ldata->base + RTC_YDR) == 0x2000) {
+			time = readl(ldata->base + RTC_DR);
+			if ((time &
+			     (RTC_MON_MASK | RTC_MDAY_MASK | RTC_WDAY_MASK))
+			    == 0x02120000) {
+				time = time | (0x7 << RTC_WDAY_SHIFT);
+				writel(0x2000, ldata->base + RTC_YLR);
+				writel(time, ldata->base + RTC_LR);
+			}
+		}
+	}
+
 	ldata->rtc = rtc_device_register("pl031", &adev->dev, ops,
 					THIS_MODULE);
 	if (IS_ERR(ldata->rtc)) {