diff options
author | James Morris <james.l.morris@oracle.com> | 2012-06-10 22:52:10 +1000 |
---|---|---|
committer | James Morris <james.l.morris@oracle.com> | 2012-06-10 22:52:10 +1000 |
commit | 66dd07b88a1c9d446f32253da606b87324fa620e (patch) | |
tree | 4e0971bdd543585c7ab46716ae808a7fd82f9c35 /drivers/rtc/rtc-pl031.c | |
parent | f52c44cd27b4a0be37ef97f0466e4095ebebef3f (diff) | |
parent | cfaf025112d3856637ff34a767ef785ef5cf2ca9 (diff) |
Merge commit 'v3.5-rc2' into next
Diffstat (limited to 'drivers/rtc/rtc-pl031.c')
-rw-r--r-- | drivers/rtc/rtc-pl031.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index 684ef4bbfce4..cc0533994f6e 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c @@ -220,17 +220,9 @@ static irqreturn_t pl031_interrupt(int irq, void *dev_id) unsigned long events = 0; rtcmis = readl(ldata->base + RTC_MIS); - if (rtcmis) { - writel(rtcmis, ldata->base + RTC_ICR); - - if (rtcmis & RTC_BIT_AI) - events |= (RTC_AF | RTC_IRQF); - - /* Timer interrupt is only available in ST variants */ - if ((rtcmis & RTC_BIT_PI) && - (ldata->hw_designer == AMBA_VENDOR_ST)) - events |= (RTC_PF | RTC_IRQF); - + if (rtcmis & RTC_BIT_AI) { + writel(RTC_BIT_AI, ldata->base + RTC_ICR); + events |= (RTC_AF | RTC_IRQF); rtc_update_irq(ldata->rtc, 1, events); return IRQ_HANDLED; @@ -312,6 +304,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 +336,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)) { |