From patchwork Tue May 6 14:28:01 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris BREZILLON X-Patchwork-Id: 4122221 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 296A6BFF02 for ; Tue, 6 May 2014 14:31:01 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 4E5ED20218 for ; Tue, 6 May 2014 14:31:00 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B264520219 for ; Tue, 6 May 2014 14:30:58 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1WhgM9-00033b-Ta; Tue, 06 May 2014 14:28:29 +0000 Received: from top.free-electrons.com ([176.31.233.9] helo=mail.free-electrons.com) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1WhgM6-0002us-G8 for linux-arm-kernel@lists.infradead.org; Tue, 06 May 2014 14:28:27 +0000 Received: by mail.free-electrons.com (Postfix, from userid 106) id A29CD1240; Tue, 6 May 2014 16:28:02 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-2.5 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from localhost.localdomain (col31-4-88-188-83-94.fbx.proxad.net [88.188.83.94]) by mail.free-electrons.com (Postfix) with ESMTPSA id 0F22F123F; Tue, 6 May 2014 16:28:02 +0200 (CEST) From: Boris BREZILLON To: Bryan Evenson Subject: [PATCH] rtc: rtc-at91rm9200: fix infinite wait for ACKUPD irq Date: Tue, 6 May 2014 16:28:01 +0200 Message-Id: <1399386481-18643-1-git-send-email-boris.brezillon@free-electrons.com> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <94c06375c1b44c8eb5233b0ccf2e4b13@BY2PR05MB048.namprd05.prod.outlook.com> References: <94c06375c1b44c8eb5233b0ccf2e4b13@BY2PR05MB048.namprd05.prod.outlook.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140506_072826_854147_F3380F79 X-CRM114-Status: GOOD ( 15.82 ) X-Spam-Score: 0.3 (/) Cc: Alessandro Zummo , rtc-linux@googlegroups.com, Boris BREZILLON , Nicolas Ferre , linux-kernel@vger.kernel.org, Jean-Christophe Plagniol-Villard , Andrew Victor , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP The rtc user must wait at least 1 sec between each time/calandar update (see atmel's datasheet chapter "Updating Time/Calendar"). Use the 1Hz interrupt to update the at91_rtc_upd_rdy flag and wait for the at91_rtc_wait_upd_rdy event if the rtc is not ready. Signed-off-by: Boris BREZILLON Reported-by: Bryan Evenson --- Hello Bryan, I reproduced your bug (using your script) and this patch seems to fix the problem. Could you try it and let me know if it works for you ? Best Regards, Boris drivers/rtc/rtc-at91rm9200.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index 3281c90..e3fe54c 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c @@ -48,11 +48,13 @@ struct at91_rtc_config { static const struct at91_rtc_config *at91_rtc_config; static DECLARE_COMPLETION(at91_rtc_updated); +static DECLARE_COMPLETION(at91_rtc_wait_upd_rdy); static unsigned int at91_alarm_year = AT91_RTC_EPOCH; static void __iomem *at91_rtc_regs; static int irq; static DEFINE_SPINLOCK(at91_rtc_lock); static u32 at91_rtc_shadow_imr; +static bool at91_rtc_upd_rdy; static void at91_rtc_write_ier(u32 mask) { @@ -161,6 +163,8 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); + wait_for_completion(&at91_rtc_wait_upd_rdy); + /* Stop Time/Calendar from counting */ cr = at91_rtc_read(AT91_RTC_CR); at91_rtc_write(AT91_RTC_CR, cr | AT91_RTC_UPDCAL | AT91_RTC_UPDTIM); @@ -183,6 +187,7 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) /* Restart Time/Calendar */ cr = at91_rtc_read(AT91_RTC_CR); + at91_rtc_upd_rdy = 0; at91_rtc_write(AT91_RTC_CR, cr & ~(AT91_RTC_UPDCAL | AT91_RTC_UPDTIM)); return 0; @@ -290,8 +295,13 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) if (rtsr) { /* this interrupt is shared! Is it ours? */ if (rtsr & AT91_RTC_ALARM) events |= (RTC_AF | RTC_IRQF); - if (rtsr & AT91_RTC_SECEV) + if (rtsr & AT91_RTC_SECEV) { events |= (RTC_UF | RTC_IRQF); + if (!at91_rtc_upd_rdy) { + at91_rtc_upd_rdy = 1; + complete(&at91_rtc_wait_upd_rdy); + } + } if (rtsr & AT91_RTC_ACKUPD) complete(&at91_rtc_updated); @@ -413,6 +423,8 @@ static int __init at91_rtc_probe(struct platform_device *pdev) return PTR_ERR(rtc); platform_set_drvdata(pdev, rtc); + /* Enable 1Hz events */ + at91_rtc_write_ier(AT91_RTC_SECEV); dev_info(&pdev->dev, "AT91 Real Time Clock driver.\n"); return 0; }