From patchwork Wed Jul 31 14:29:01 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Lothar_Wa=C3=9Fmann?= X-Patchwork-Id: 263717 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from mail-la0-x239.google.com (mail-la0-x239.google.com [IPv6:2a00:1450:4010:c03::239]) (using TLSv1 with cipher ECDHE-RSA-RC4-SHA (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 480782C00C7 for ; Thu, 1 Aug 2013 00:29:30 +1000 (EST) Received: by mail-la0-f57.google.com with SMTP id el20sf124760lab.22 for ; Wed, 31 Jul 2013 07:29:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlegroups.com; s=20120806; h=x-beenthere:from:to:cc:subject:date:message-id:x-mailer :mime-version:x-original-sender:x-original-authentication-results :reply-to:precedence:mailing-list:list-id:x-google-group-id :list-post:list-help:list-archive:sender:list-subscribe :list-unsubscribe:content-type:content-transfer-encoding; bh=3VZ8XBB5rpGhEHFcJTq8Z4Xf4X4CE1XfyliQlcOUfAU=; b=dOptcDM9TvxTxz4rmS6Uu/8tyWi+0Rd8VIbsrYkyu4aYkw9qmsLBWlzCudxpx6HsfL daNS4fWumcgvriAcBBzgoWHfkwkeiU2XtLoUnhwpdhSt6iJLK/DYmNO7czhjbM9zIrhj UJ9np49GyGouYC5k82PCXp9sBlvLgn0IBbSbNxLn3rBKkZqnTgnYr2OyH3BFrfWRmawk 6dPf/HjUqDTDq8nz0QgZESb6ryQ3A3FdUearhcIWdfFSpZuWTC5DHZPCqNXfBwbxmSBB sH2fOWUu7pWqkIJ9eTI6NpBOre6VOrUWJlO+TpfNPAfYFN75+QcviqdUSBKMn7Rf1p4s y+Kg== X-Received: by 10.180.9.35 with SMTP id w3mr287113wia.9.1375280964820; Wed, 31 Jul 2013 07:29:24 -0700 (PDT) X-BeenThere: rtc-linux@googlegroups.com Received: by 10.180.73.79 with SMTP id j15ls403296wiv.5.gmail; Wed, 31 Jul 2013 07:29:23 -0700 (PDT) X-Received: by 10.180.205.240 with SMTP id lj16mr2513114wic.6.1375280963973; Wed, 31 Jul 2013 07:29:23 -0700 (PDT) Received: from mail.karo-electronics.de (mail.karo-electronics.de. [81.173.242.67]) by gmr-mx.google.com with ESMTPS id ev4si716962wib.0.2013.07.31.07.29.22 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Wed, 31 Jul 2013 07:29:23 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of LW@karo-electronics.de designates 81.173.242.67 as permitted sender) client-ip=81.173.242.67; From: =?UTF-8?q?Lothar=20Wa=C3=9Fmann?= To: Alessandro Zummo Cc: rtc-linux@googlegroups.com, Wolfram Sang , linux-kernel@vger.kernel.org, =?UTF-8?q?Lothar=20Wa=C3=9Fmann?= Subject: [rtc-linux] [PATCH] rtc: rtc-stmp3xxx: provide timeout for potentially endless loop polling a HW bit Date: Wed, 31 Jul 2013 16:29:01 +0200 Message-Id: <1375280941-22657-1-git-send-email-LW@KARO-electronics.de> X-Mailer: git-send-email 1.7.2.5 MIME-Version: 1.0 X-Original-Sender: lw@karo-electronics.de X-Original-Authentication-Results: gmr-mx.google.com; spf=pass (google.com: best guess record for domain of LW@karo-electronics.de designates 81.173.242.67 as permitted sender) smtp.mail=LW@karo-electronics.de Reply-To: rtc-linux@googlegroups.com Precedence: list Mailing-list: list rtc-linux@googlegroups.com; contact rtc-linux+owners@googlegroups.com List-ID: X-Google-Group-Id: 712029733259 List-Post: , List-Help: , List-Archive: Sender: rtc-linux@googlegroups.com List-Subscribe: , List-Unsubscribe: , It's always a bad idea to poll on HW bits without a timeout. The i.MX28 RTC can be easily brought into a state in which the RTC is not running (until after a power-on-reset) and thus the status bits which are polled in the driver won't ever change. This patch prevents the kernel from getting stuck in this case. Signed-off-by: Lothar Waßmann Acked-by: Wolfram Sang --- drivers/rtc/rtc-stmp3xxx.c | 35 +++++++++++++++++++++++++---------- 1 files changed, 25 insertions(+), 10 deletions(-) diff --git a/drivers/rtc/rtc-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c index 767fee2..2601953 100644 --- a/drivers/rtc/rtc-stmp3xxx.c +++ b/drivers/rtc/rtc-stmp3xxx.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -119,24 +120,39 @@ static void stmp3xxx_wdt_register(struct platform_device *rtc_pdev) } #endif /* CONFIG_STMP3XXX_RTC_WATCHDOG */ -static void stmp3xxx_wait_time(struct stmp3xxx_rtc_data *rtc_data) +static int stmp3xxx_wait_time(struct stmp3xxx_rtc_data *rtc_data) { + int timeout = 5000; /* 3ms according to i.MX28 Ref Manual */ /* - * The datasheet doesn't say which way round the - * NEW_REGS/STALE_REGS bitfields go. In fact it's 0x1=P0, - * 0x2=P1, .., 0x20=P5, 0x40=ALARM, 0x80=SECONDS + * The i.MX28 Applications Processor Reference Manual, Rev. 1, 2010 + * states: + * | The order in which registers are updated is + * | Persistent 0, 1, 2, 3, 4, 5, Alarm, Seconds. + * | (This list is in bitfield order, from LSB to MSB, as they would + * | appear in the STALE_REGS and NEW_REGS bitfields of the HW_RTC_STAT + * | register. For example, the Seconds register corresponds to + * | STALE_REGS or NEW_REGS containing 0x80.) */ - while (readl(rtc_data->io + STMP3XXX_RTC_STAT) & - (0x80 << STMP3XXX_RTC_STAT_STALE_SHIFT)) - cpu_relax(); + do { + if (!(readl(rtc_data->io + STMP3XXX_RTC_STAT) & + (0x80 << STMP3XXX_RTC_STAT_STALE_SHIFT))) + return 0; + udelay(1); + } while (--timeout > 0); + return (readl(rtc_data->io + STMP3XXX_RTC_STAT) & + (0x80 << STMP3XXX_RTC_STAT_STALE_SHIFT)) ? -ETIME : 0; } /* Time read/write */ static int stmp3xxx_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) { + int ret; struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); - stmp3xxx_wait_time(rtc_data); + ret = stmp3xxx_wait_time(rtc_data); + if (ret) + return ret; + rtc_time_to_tm(readl(rtc_data->io + STMP3XXX_RTC_SECONDS), rtc_tm); return 0; } @@ -146,8 +162,7 @@ static int stmp3xxx_rtc_set_mmss(struct device *dev, unsigned long t) struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); writel(t, rtc_data->io + STMP3XXX_RTC_SECONDS); - stmp3xxx_wait_time(rtc_data); - return 0; + return stmp3xxx_wait_time(rtc_data); } /* interrupt(s) handler */