[PATCH v3 1/2] watchdog: NXP LPC18xx Watchdog Timer Driver

Ariel D'Alessandro ariel at vanguardiasur.com.ar
Sun Jul 26 13:49:36 PDT 2015


Guenter,

El 24/07/15 a las 19:45, Guenter Roeck escibió:
> On 07/24/2015 01:57 PM, Ariel D'Alessandro wrote:
>>
>>
>> El 24/07/15 a las 11:04, Guenter Roeck escibió:
>>> On 07/24/2015 06:54 AM, Ariel D'Alessandro wrote:
>>>>
>>>>
>>>> El 23/07/15 a las 18:21, Guenter Roeck escibió:
>>>>> On 07/23/2015 01:38 PM, Ariel D'Alessandro wrote:
>>>>>> Hi Guenter,
>>>>>>
>>>>>> El 21/07/15 a las 21:51, Guenter Roeck escibió:
>>>>>>> On 07/14/2015 05:50 PM, Ariel D'Alessandro wrote:
>>>>>>>> This commit adds support for the watchdog timer found in NXP LPC
>>>>>>>> SoCs
>>>>>>>> family, which includes LPC18xx/LPC43xx. Other SoCs in that
>>>>>>>> family may
>>>>>>>> share the same watchdog hardware.
>>>>>>>>
>>>>>>>> Watchdog driver registers a restart handler that will restart the
>>>>>>>> system
>>>>>>>> by performing an incorrect feed after ensuring the watchdog is
>>>>>>>> enabled in
>>>>>>>> reset mode.
>>>>>>>>
>>>>>>>> As watchdog cannot be disabled in hardware, driver's stop routine
>>>>>>>> will
>>>>>>>> regularly send a keepalive ping using a timer.
>>>>>>>>
>>>>>>>> Signed-off-by: Ariel D'Alessandro <ariel at vanguardiasur.com.ar>
>>>>>>>
>>>>>>> Hi Ariel,
>>>>>>>
>>>>>>> sorry for the delayed response. Comments below.
>>>>>>>
>>>>>>> Guenter
>>>>>>>
>>>>>>>> ---
>>>>>>>>      drivers/watchdog/Kconfig       |  11 ++
>>>>>>>>      drivers/watchdog/Makefile      |   1 +
>>>>>>>>      drivers/watchdog/lpc18xx_wdt.c | 344
>>>>>>>> +++++++++++++++++++++++++++++++++++++++++
>>>>>>>>      3 files changed, 356 insertions(+)
>>>>>>>>      create mode 100644 drivers/watchdog/lpc18xx_wdt.c
>>>>>>>>
>>>>>>>> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
>>>>>>>> index 742fbbc..af5e2e3 100644
>>>>>>>> --- a/drivers/watchdog/Kconfig
>>>>>>>> +++ b/drivers/watchdog/Kconfig
>>>>>>>> @@ -547,6 +547,17 @@ config DIGICOLOR_WATCHDOG
>>>>>>>>            To compile this driver as a module, choose M here: the
>>>>>>>>            module will be called digicolor_wdt.
>>>>>>>>
>>>>>>>> +config LPC18XX_WATCHDOG
>>>>>>>> +    tristate "LPC18xx/43xx Watchdog"
>>>>>>>> +    depends on ARCH_LPC18XX || COMPILE_TEST
>>>>>>>> +    select WATCHDOG_CORE
>>>>>>>> +    help
>>>>>>>> +      Say Y here if to include support for the watchdog timer
>>>>>>>> +      in NXP LPC SoCs family, which includes LPC18xx/LPC43xx
>>>>>>>> +      processors.
>>>>>>>> +      To compile this driver as a module, choose M here: the
>>>>>>>> +      module will be called lpc18xx_wdt.
>>>>>>>> +
>>>>>>>>      # AVR32 Architecture
>>>>>>>>
>>>>>>>>      config AT32AP700X_WDT
>>>>>>>> diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
>>>>>>>> index 59ea9a1..1b0ef48 100644
>>>>>>>> --- a/drivers/watchdog/Makefile
>>>>>>>> +++ b/drivers/watchdog/Makefile
>>>>>>>> @@ -66,6 +66,7 @@ obj-$(CONFIG_TEGRA_WATCHDOG) += tegra_wdt.o
>>>>>>>>      obj-$(CONFIG_MESON_WATCHDOG) += meson_wdt.o
>>>>>>>>      obj-$(CONFIG_MEDIATEK_WATCHDOG) += mtk_wdt.o
>>>>>>>>      obj-$(CONFIG_DIGICOLOR_WATCHDOG) += digicolor_wdt.o
>>>>>>>> +obj-$(CONFIG_LPC18XX_WATCHDOG) += lpc18xx_wdt.o
>>>>>>>>
>>>>>>>>      # AVR32 Architecture
>>>>>>>>      obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
>>>>>>>> diff --git a/drivers/watchdog/lpc18xx_wdt.c
>>>>>>>> b/drivers/watchdog/lpc18xx_wdt.c
>>>>>>>> new file mode 100644
>>>>>>>> index 0000000..2b489fc
>>>>>>>> --- /dev/null
>>>>>>>> +++ b/drivers/watchdog/lpc18xx_wdt.c
>>>>>>>> @@ -0,0 +1,344 @@
>>>>>>>> +/*
>>>>>>>> + * NXP LPC18xx Watchdog Timer (WDT)
>>>>>>>> + *
>>>>>>>> + * Copyright (c) 2015 Ariel D'Alessandro <ariel at vanguardiasur.com>
>>>>>>>> + *
>>>>>>>> + * This program is free software; you can redistribute it and/or
>>>>>>>> modify it
>>>>>>>> + * under the terms of the GNU General Public License version 2 as
>>>>>>>> published by
>>>>>>>> + * the Free Software Foundation.
>>>>>>>> + *
>>>>>>>> + * Notes
>>>>>>>> + * -----
>>>>>>>> + * The Watchdog consists of a fixed divide-by-4 clock
>>>>>>>> pre-scaler and
>>>>>>>> a 24-bit
>>>>>>>> + * counter which decrements on every clock cycle.
>>>>>>>> + *
>>>>>>>> + */
>>>>>>>> +
>>>>>>>> +#include <linux/clk.h>
>>>>>>>> +#include <linux/io.h>
>>>>>>>> +#include <linux/module.h>
>>>>>>>> +#include <linux/of.h>
>>>>>>>> +#include <linux/platform_device.h>
>>>>>>>> +#include <linux/reboot.h>
>>>>>>>> +#include <linux/watchdog.h>
>>>>>>>> +
>>>>>>>> +/* Registers */
>>>>>>>> +#define LPC18XX_WDT_MOD            0x00
>>>>>>>> +#define LPC18XX_WDT_MOD_WDEN        BIT(0)
>>>>>>>> +#define LPC18XX_WDT_MOD_WDRESET        BIT(1)
>>>>>>>> +#define LPC18XX_WDT_MOD_WDTOF_MASK    0x04
>>>>>>>
>>>>>>> Not used.
>>>>>>
>>>>>> That's right. I'll remove it.
>>>>>>
>>>>>>>
>>>>>>>> +
>>>>>>>> +#define LPC18XX_WDT_TC            0x04
>>>>>>>> +#define LPC18XX_WDT_TC_MIN        0xff
>>>>>>>> +#define LPC18XX_WDT_TC_MAX        0xffffff
>>>>>>>> +
>>>>>>>> +#define LPC18XX_WDT_FEED        0x08
>>>>>>>> +#define LPC18XX_WDT_FEED_MAGIC1        0xaa
>>>>>>>> +#define LPC18XX_WDT_FEED_MAGIC2        0x55
>>>>>>>> +
>>>>>>>> +#define LPC18XX_WDT_TV            0x0c
>>>>>>>> +
>>>>>>>> +/* Clock pre-scaler */
>>>>>>>> +#define LPC18XX_WDT_CLK_DIV        4
>>>>>>>> +
>>>>>>>> +/* Timeout values in seconds */
>>>>>>>> +#define LPC18XX_WDT_DEF_TIMEOUT        5
>>>>>>>> +
>>>>>>>
>>>>>>> This is (still) really low for Linux. Something like min(30,
>>>>>>> max_timeout)
>>>>>>> might make more sense.
>>>>>>
>>>>>> Remember that hardware limits timeout to a maximum value of 5.
>>>>>>
>>>>>> As you said before we could use a soft timer, but I not sure that's a
>>>>>> good idea. As Ezequiel said [0], it might be adding bloat and we must
>>>>>> consider that this watchdog controller is included in cortex-M MCUs.
>>>>>>
>>>>>> [0] http://www.spinics.net/lists/linux-watchdog/msg06904.html
>>>>>>
>>>>>
>>>>> Further down you have
>>>>>       lpc18xx_wdt->wdt_dev.max_timeout = (LPC18XX_WDT_TC_MAX *
>>>>>                             LPC18XX_WDT_CLK_DIV) / clk_rate;
>>>>>
>>>>> which seems to contradict this statement. If the maximum timeout is 5
>>>>> seconds,
>>>>> why don't you set max_timeout to a fixed value of 5 seconds ?
>>>>
>>>> Well, I think that's the less hardcoded way. It might allow the driver
>>>> to be extended to another HW variant that configures the wdt clk rate.
>>>>
>>>> I see what's your point. As you proposed, using the same criterion I
>>>> should do this:
>>>>
>>>> #define LPC18XX_WDT_DEF_TIMEOUT         (unsigned int)30
>>>>
>>>> and further down, in probe function:
>>>>
>>>> lpc18xx_wdt->wdt_dev.timeout = min(LPC18XX_WDT_DEF_TIMEOUT,
>>>>                     lpc18xx_wdt->wdt_dev.max_timeout);
>>>>
>>>> Is this close enough to your solution?
>>>>
>>> Yes, but why the typecast for LPC18XX_WDT_DEF_TIMEOUT ?
>>>
>>
>> Otherwise the compiler will warn about a comparison of distinct pointer
>> types in expansion of the macro 'min'.
>>
>> Should it be casted when using it better than in definition?
>>
> Pointer types sounds odd. What exactly is the message ?

drivers/watchdog/lpc18xx_wdt.c: In function 'lpc18xx_wdt_probe':
include/linux/kernel.h:721:17: warning: comparison of distinct pointer
types lacks a cast [enabled by default]
  (void) (&_min1 == &_min2);  \
                 ^
drivers/watchdog/lpc18xx_wdt.c:262:33: note: in expansion of macro 'min'
  lpc18xx_wdt->wdt_dev.timeout = min(lpc18xx_wdt->wdt_dev.max_timeout,
                                 ^

> 
> How about using the following ?
> 
>     #define LPC18XX_WDT_DEF_TIMEOUT        30U

Yes, that's what I responded in another mail. Thanks for your
suggestions, I'm submitting v4 now with all the modifications you've
pointed out.



More information about the linux-arm-kernel mailing list