[PATCH 3.4 188/214] drivers/rtc/rtc-pl031.c: fix the missing operation on enable

Greg Kroah-Hartman
2014-06-05T04:30:16Z

From: Haojian Zhuang <haojian.zhuang@linaro.org>

commit e7e034e18a0ab6bafb2425c3242cac311164f4d6 upstream.

The RTC control register should be enabled in the process of
initializing.

Without this patch, I failed to enable RTC in Hisilicon Hi3620 SoC. The
register mapping section in RTC is always read as zero. So I doubt that
ST guys may already enable this register in bootloader. So they won't
meet this issue.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
Cc: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Cc: Qiang Huang <h.huangqiang@huawei.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
drivers/rtc/rtc-pl031.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)

--- a/drivers/rtc/rtc-pl031.c
+++ b/drivers/rtc/rtc-pl031.c
@@ -44,6 +44,7 @@
#define RTC_YMR 0x34 /* Year match register */
#define RTC_YLR 0x38 /* Year data load register */

+#define RTC_CR_EN (1 << 0) /* counter enable bit */
#define RTC_CR_CWEN (1 << 26) /* Clockwatch enable bit */

#define RTC_TCR_EN (1 << 1) /* Periodic timer enable bit */
@@ -312,7 +313,7 @@ static int pl031_probe(struct amba_devic
int ret;
struct pl031_local *ldata;
struct rtc_class_ops *ops = id->data;
- unsigned long time;
+ unsigned long time, data;

ret = amba_request_regions(adev, NULL);
if (ret)
@@ -339,10 +340,11 @@ static int pl031_probe(struct amba_devic
dev_dbg(&adev->dev, "designer ID = 0x%02x\n", ldata->hw_designer);
dev_dbg(&adev->dev, "revision = 0x%01x\n", ldata->hw_revision);

+ data = readl(ldata->base + RTC_CR);
/* Enable the clockwatch on ST Variants */
if (ldata->hw_designer == AMBA_VENDOR_ST)
- writel(readl(ldata->base + RTC_CR) | RTC_CR_CWEN,
- ldata->base + RTC_CR);
+ data |= RTC_CR_CWEN;
+ writel(data | RTC_CR_EN, ldata->base + RTC_CR);

/*
* On ST PL031 variants, the RTC reset value does not provide correct