Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755271AbcCCAVp (ORCPT ); Wed, 2 Mar 2016 19:21:45 -0500 Received: from mailout1.w1.samsung.com ([210.118.77.11]:49073 "EHLO mailout1.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752210AbcCCAVn (ORCPT ); Wed, 2 Mar 2016 19:21:43 -0500 X-AuditID: cbfec7f4-f79026d00000418a-38-56d783925218 Subject: Re: [RFC PATCH] watchdog: s3c2410_wdt: Add max and min timeout values To: Javier Martinez Canillas , linux-kernel@vger.kernel.org References: <1456850717-3670-1-git-send-email-javier@osg.samsung.com> <56D62979.5040009@samsung.com> <56D7233B.50907@osg.samsung.com> Cc: Guenter Roeck , Kukjin Kim , Wim Van Sebroeck , linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-watchdog@vger.kernel.org, Chanwoo Choi From: Krzysztof Kozlowski X-Enigmail-Draft-Status: N1110 Message-id: <56D7838D.4060602@samsung.com> Date: Thu, 03 Mar 2016 09:21:33 +0900 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.5.1 MIME-version: 1.0 In-reply-to: <56D7233B.50907@osg.samsung.com> Content-type: text/plain; charset=windows-1252 Content-transfer-encoding: 7bit X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrLLMWRmVeSWpSXmKPExsVy+t/xa7qTmq+HGeybr2Vx/ctzVos3b9cw Wbx+YWjR//g1s8Wmx9dYLS7vmsNmMeP8PiaLG+v2sVs8WXiGyeLWjBesDlwe1zaLeWxa1cnm sXlJvceW/rvsHju/N7B79G1ZxejxeZNcAHsUl01Kak5mWWqRvl0CV0bX6z6WgoOaFXufNLM2 MH5S6GLk5JAQMJE497SVDcIWk7hwbz2QzcUhJLCUUeL36ymMEM5TRom75xczgVQJC/hJrJ/c wgJiiwiESvy7eJsRxBYSaGeUmLvfD6SBWeAPo8SJV1+ZQRJsAsYSm5cvgVohJ9HbPQmsmVdA S2LPnx9gNouAqsSNL11gC0QFIiQOd3axQ9QISvyYfA+shlNAV2LJ5kagZRxAC/Qk7l/UAgkz C8hLbF7zlnkCo+AsJB2zEKpmIalawMi8ilE0tTS5oDgpPddQrzgxt7g0L10vOT93EyMkUr7s YFx8zOoQowAHoxIP742G62FCrIllxZW5hxglOJiVRHgVaoFCvCmJlVWpRfnxRaU5qcWHGKU5 WJTEeefueh8iJJCeWJKanZpakFoEk2Xi4JRqYIx49ezHLXuBgOg+Lpfb7xmNbW49u2grnb4u SVhx0hp3kw0BkTEvpLJ47woET22+z79848otVpmmnOKnl3FyPBA4rLdo/8c91te711jM/CFh +tnq2sEXVz96H9quwSj3zGV74IS2jZ+O5TT5TozqVz+grnLj56ebtXky3tMiA77PX33meOeN ncFKLMUZiYZazEXFiQDEEwrikAIAAA== Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5176 Lines: 137 On 03.03.2016 02:30, Javier Martinez Canillas wrote: > Hello Krzysztof, > > On 03/01/2016 08:44 PM, Krzysztof Kozlowski wrote: >> On 02.03.2016 01:45, Javier Martinez Canillas wrote: >>> 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 >>> >>> --- >>> 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. >> >> It looks correct at least for Exynos4210 and newer. >> > > Great, thanks a lot for the confirmation. > >>> >>> 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); >> >> Can the frequency of clock change? E.g. with devfreq? No problem if it >> goes lower but if it gets higher than initial, then the problem will >> appear again. >> > > That's a very good question. As Guenter said we will be in deep troubles > if that ever happens since the driver doesn't take that into account. > > The .set_timeout handler just sets the counter according to the current > frequency and that's never updated, unless a new timeout is set of course. > > So in other words, I just made the same assumptions that the driver is > currently doing. Not entirely. Change of clock frequency will affect currently set timeout. But the next timeout will be using new frequency. However you are setting the maximum timeout once. It will never change. > At least the Exynos SoCs manual don't mention frequency > scaling for the watchdog timer source clock and AFAICT none of the CLK_WDT > parents scale their frequencies but I don't know if that's true for all > the machines using this driver (i.e: out-of-tree boards). I looked at Exynos4 family because the devfreq was tested there. The WDT clock goes from ACLK100 (or ACLK66 on different socs). 1. Existing devfreq for Exynos4 does not change ACLK100 frequency. 2. New patches from Chanwoo (Cc) add scaling of ACLK100 also to 50 MHz: http://lkml.iu.edu/hypermail/linux/kernel/1512.1/04828.html The problem will be more severe if the watchdog got configured on 50 MHz and then devfreq bumps the clock to 100 MHz... Best regards, Krzysztof