From patchwork Tue Mar 1 16:45:17 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Javier Martinez Canillas X-Patchwork-Id: 8467071 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.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 6B28CC0553 for ; Tue, 1 Mar 2016 16:48:02 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D07C3202FF for ; Tue, 1 Mar 2016 16:47:59 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5F30220251 for ; Tue, 1 Mar 2016 16:47:54 +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 1aanR4-0006fI-P0; Tue, 01 Mar 2016 16:46:10 +0000 Received: from lists.s-osg.org ([54.187.51.154]) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aanR1-0006Sq-Pk for linux-arm-kernel@lists.infradead.org; Tue, 01 Mar 2016 16:46:08 +0000 Received: from sauron.localdomain (unknown [200.3.249.195]) by lists.s-osg.org (Postfix) with ESMTPSA id 273A4462A0; Tue, 1 Mar 2016 08:45:41 -0800 (PST) From: Javier Martinez Canillas To: linux-kernel@vger.kernel.org Subject: [RFC PATCH] watchdog: s3c2410_wdt: Add max and min timeout values Date: Tue, 1 Mar 2016 13:45:17 -0300 Message-Id: <1456850717-3670-1-git-send-email-javier@osg.samsung.com> X-Mailer: git-send-email 2.5.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160301_084607_881491_A296FB2E X-CRM114-Status: GOOD ( 13.63 ) X-Spam-Score: -1.9 (-) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Krzysztof Kozlowski , linux-samsung-soc@vger.kernel.org, linux-watchdog@vger.kernel.org, Javier Martinez Canillas , Wim Van Sebroeck , Kukjin Kim , Guenter Roeck , linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The watchdog maximum timeout value is determined by the number of bits for the interval timer counter, its source clock frequency, the number of bits of the prescaler and maximum divider value. This can be calculated with the following equation: max_timeout = counter / (freq / (max_prescale + 1) / max_divider) Setting a maximum timeout value will allow the watchdog core to refuse user-space calls to the WDIOC_SETTIMEOUT ioctl that sets not supported timeout values. For example, systemd tries to set a timeout of 10 minutes on reboot to ensure that the machine will be rebooted even if a reboot failed. This leads to the following error message on an Exynos5422 Odroid XU4 board: [ 147.986045] s3c2410-wdt 101d0000.watchdog: timeout 600 too big Reported-by: Krzysztof Kozlowski Signed-off-by: Javier Martinez Canillas Reviewed-by: Krzysztof Kozlowski Reviewed-by: Guenter Roeck --- Hello, I'm sending this as an RFC because I don't have access to user manuals for all the Exynos SoCs that this driver supports. But at least in all the ones I have here, the maximum prescaler and divider values are the same and also all have a 16-bit interval timer counter. So this patch assumes that all IP blocks supported by this driver are the same on that regard, if that's not the case then we can move these values on a per IP block basis using struct of_device_id .data field. Best regards, Javier drivers/watchdog/s3c2410_wdt.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index 0093450441fe..f289c9fc353a 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c @@ -47,6 +47,8 @@ #define S3C2410_WTDAT 0x04 #define S3C2410_WTCNT 0x08 +#define S3C2410_WTCNT_MAXCNT 0xffff + #define S3C2410_WTCON_RSTEN (1 << 0) #define S3C2410_WTCON_INTEN (1 << 2) #define S3C2410_WTCON_ENABLE (1 << 5) @@ -56,8 +58,11 @@ #define S3C2410_WTCON_DIV64 (2 << 3) #define S3C2410_WTCON_DIV128 (3 << 3) +#define S3C2410_WTCON_MAXDIV 0x80 + #define S3C2410_WTCON_PRESCALE(x) ((x) << 8) #define S3C2410_WTCON_PRESCALE_MASK (0xff << 8) +#define S3C2410_WTCON_PRESCALE_MAX 0xff #define CONFIG_S3C2410_WATCHDOG_ATBOOT (0) #define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME (15) @@ -198,6 +203,14 @@ do { \ /* functions */ +static inline unsigned int s3c2410wdt_max_timeout(struct clk *clock) +{ + unsigned long freq = clk_get_rate(clock); + + return S3C2410_WTCNT_MAXCNT / (freq / (S3C2410_WTCON_PRESCALE_MAX + 1) + / S3C2410_WTCON_MAXDIV); +} + static inline struct s3c2410_wdt *freq_to_wdt(struct notifier_block *nb) { return container_of(nb, struct s3c2410_wdt, freq_transition); @@ -567,6 +580,9 @@ static int s3c2410wdt_probe(struct platform_device *pdev) return ret; } + wdt->wdt_device.min_timeout = 1; + wdt->wdt_device.max_timeout = s3c2410wdt_max_timeout(wdt->clock); + ret = s3c2410wdt_cpufreq_register(wdt); if (ret < 0) { dev_err(dev, "failed to register cpufreq\n");