[ 105/117] drivers/rtc/rtc-pl031.c: configure correct wday for 2000-01-01
From: Ben Hutchings
Date: Sun May 27 2012 - 23:31:05 EST
3.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rajkumar Kasirajan <rajkumar.kasirajan@xxxxxxxxxxxxxx>
commit c0a5f4a05af588a0f9951f8d24e2564b09501918 upstream.
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.
Signed-off-by: Rajkumar Kasirajan <rajkumar.kasirajan@xxxxxxxxxxxxxx>
Signed-off-by: Linus Walleij <linus.walleij@xxxxxxxxxx>
Cc: Mattias Wallin <mattias.wallin@xxxxxxxxxxxxxx>
Cc: Alessandro Zummo <a.zummo@xxxxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
Signed-off-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
Signed-off-by: Ben Hutchings <ben@xxxxxxxxxxxxxxx>
---
drivers/rtc/rtc-pl031.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
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)) {
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/