Re: [PATCH 2/2] watchdog: intel: Watchdog timer support on Lightning Mountain

From: Guenter Roeck
Date: Tue Jun 09 2020 - 09:43:50 EST


On 6/9/20 1:57 AM, Dilip Kota wrote:
>
> On 6/8/2020 9:36 PM, Guenter Roeck wrote:
>> On 6/7/20 10:49 PM, Dilip Kota wrote:
>>> On Intel Lightning Mountain SoC, General Purpose Timer Counter(GPTC)
>>> programmable as clocksource, real time clock or watchdog timer.
>>>
>>> This driver configures GPTC as Watchdog timer and triggers reset signal
>>> to CPU on timeout.
>>>
>>> Signed-off-by: Dilip Kota <eswara.kota@xxxxxxxxxxxxxxx>
>>> ---
>>> Â drivers/watchdog/KconfigÂÂÂÂÂÂÂÂÂÂÂÂÂ |Â 13 ++
>>> Â drivers/watchdog/MakefileÂÂÂÂÂÂÂÂÂÂÂÂ |ÂÂ 1 +
>>> Â drivers/watchdog/intel_lgm_gptc_wdt.c | 420 ++++++++++++++++++++++++++++++++++
>>> Â 3 files changed, 434 insertions(+)
>>> Â create mode 100644 drivers/watchdog/intel_lgm_gptc_wdt.c
>>>
>>> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
>>> index 0663c604bd642..8009c11e75dda 100644
>>> --- a/drivers/watchdog/Kconfig
>>> +++ b/drivers/watchdog/Kconfig
>>> @@ -1789,6 +1789,19 @@ config IMGPDC_WDT
>>> ÂÂÂÂÂÂÂ To compile this driver as a loadable module, choose M here.
>>> ÂÂÂÂÂÂÂ The module will be called imgpdc_wdt.
>>> Â +config INTEL_LGM_GPTC_WDT
>>> +ÂÂÂ tristate "INTEL LGM SoC Watchdog"
>>> +ÂÂÂ depends on X86 || COMPILE_TEST
>>> +ÂÂÂ depends on OF && HAS_IOMEM
>>> +ÂÂÂ select REGMAP
>>> +ÂÂÂ select MFD_SYSCON
>>> +ÂÂÂ select WATCHDOG_CORE
>>> +ÂÂÂ help
>>> +ÂÂÂÂÂ Driver for Watchdog Timer on Intel Lightning Mountain SoC.
>>> +
>>> +ÂÂÂÂÂ To compile this driver as a loadable module, choose M here.
>>> +ÂÂÂÂÂ The module will be called intel_lgm_gptc_wdt.
>>> +
>>> Â config LANTIQ_WDT
>>> ÂÂÂÂÂ tristate "Lantiq SoC watchdog"
>>> ÂÂÂÂÂ depends on LANTIQ
>>> diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
>>> index 6de2e4ceef190..92c99e4c46eb7 100644
>>> --- a/drivers/watchdog/Makefile
>>> +++ b/drivers/watchdog/Makefile
>>> @@ -166,6 +166,7 @@ obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
>>> Â obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o
>>> Â octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o
>>> Â obj-$(CONFIG_LANTIQ_WDT) += lantiq_wdt.o
>>> +obj-$(CONFIG_INTEL_LGM_GPTC_WDT) += intel_lgm_gptc_wdt.o
>>> Â obj-$(CONFIG_LOONGSON1_WDT) += loongson1_wdt.o
>>> Â obj-$(CONFIG_RALINK_WDT) += rt2880_wdt.o
>>> Â obj-$(CONFIG_IMGPDC_WDT) += imgpdc_wdt.o
>>> diff --git a/drivers/watchdog/intel_lgm_gptc_wdt.c b/drivers/watchdog/intel_lgm_gptc_wdt.c
>>> new file mode 100644
>>> index 0000000000000..52be7cc194f8f
>>> --- /dev/null
>>> +++ b/drivers/watchdog/intel_lgm_gptc_wdt.c
>>> @@ -0,0 +1,420 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +/*
>>> + * Copyright (C) 2020 Intel Corporation.
>>> + */
>>> +
>>> +#include <linux/bitfield.h>
>>> +#include <linux/clk.h>
>>> +#include <linux/cpu.h>
>>> +#include <linux/io.h>
>>> +#include <linux/kernel.h>
>>> +#include <linux/mfd/syscon.h>
>>> +#include <linux/module.h>
>>> +#include <linux/of_device.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/regmap.h>
>>> +#include <linux/watchdog.h>
>>> +
>>> +#define GPTC_CLCÂÂÂÂÂÂÂ 0x00
>>> +#define GPTC_CLC_SUSPENDÂÂÂ BIT(4)
>>> +#define GPTC_CLC_RMCÂÂÂÂÂÂÂ GENMASK(15, 8)
>>> +
>>> +/* divider 10 to produce 200 / 10 = 20 MHz clock */
>>> +#define CLC_RMC_DIVÂÂÂÂÂÂÂ 10
>>> +
>>> +#define GPTC_CON(X)ÂÂÂÂÂÂÂ (0x10 + (X) * 0x20)
>>> +#define GPTC_CON_CNT_UPÂÂÂÂÂÂÂ BIT(1)
>>> +#define GPTC_CON_ONESHOTÂÂÂ BIT(3)
>>> +#define GPTC_CON_EXTÂÂÂÂÂÂÂ BIT(4)
>>> +
>>> +#define GPTC_RUN(X)ÂÂÂÂÂÂÂ (0x18 + (X) * 0x20)
>>> +#define GPTC_RUN_ENÂÂÂÂÂÂÂ BIT(0)
>>> +#define GPTC_RUN_STOPÂÂÂÂÂÂÂ BIT(1)
>>> +#define GPTC_RUN_RELOADÂÂÂÂÂÂÂ BIT(2)
>>> +
>>> +#define GPTC_RLD(X)ÂÂÂÂÂÂÂ (0x20 + (X) * 0x20)
>>> +#define GPTC_CNT(X)ÂÂÂÂÂÂÂ (0x28 + (X) * 0x20)
>>> +
>>> +#define GPTC_IRNENCLRÂÂÂÂÂÂÂ 0xF0
>>> +#define GPTC_IRNENÂÂÂÂÂÂÂ 0xF4
>>> +#define GPTC_IRNCRÂÂÂÂÂÂÂ 0xFC
>>> +
>>> +/* Watchdog Timeout Reset register offset and bitfeilds */
>>> +#define BIA_WDT_RST_ENÂÂÂÂÂÂÂ 0x1E0
>>> +#define BIA_WDTÂÂÂÂÂÂÂÂÂÂÂ BIT(6)
>>> +
>>> +#define MAX_TIMERIDÂÂÂÂÂÂÂ 2
>>> +#define MAX_CPUIDÂÂÂÂÂÂÂ 3
>>> +#define TIMER_MARGIN_SECÂÂÂ 300
>>> +
>>> +static bool nowayout = WATCHDOG_NOWAYOUT;
>>> +module_param(nowayout, bool, 0);
>>> +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started\n"
>>> +ÂÂÂ " (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
>>> +
>>> +struct lgm_gptc_timer {
>>> +ÂÂÂ struct lgm_gptc_wdtÂÂÂ *wdt_node;
>>> +ÂÂÂ struct watchdog_deviceÂÂÂ wdd;
>>> +ÂÂÂ unsigned intÂÂÂÂÂÂÂ tid;
>>> +ÂÂÂ unsigned intÂÂÂÂÂÂÂ cpuid;
>>> +ÂÂÂ unsigned intÂÂÂÂÂÂÂ frequency;
>>> +ÂÂÂ unsigned intÂÂÂÂÂÂÂ cycles;
>>> +ÂÂÂ boolÂÂÂÂÂÂÂÂÂÂÂ enable;
>>> +};
>>> +
>>> +struct lgm_gptc_wdt {
>>> +ÂÂÂ struct deviceÂÂÂÂÂÂÂ *dev;
>>> +ÂÂÂ void __iomemÂÂÂÂÂÂÂ *gptc_base;
>>> +ÂÂÂ struct regmapÂÂÂÂÂÂÂ *rst_hndl;
>>> +ÂÂÂ struct clkÂÂÂÂÂÂÂ *freqclk;
>>> +ÂÂÂ struct clkÂÂÂÂÂÂÂ *gateclk;
>>> +ÂÂÂ unsigned intÂÂÂÂÂÂÂ fpifreq;
>>> +ÂÂÂ enum cpuhp_stateÂÂÂ state;
>>> +};
>>> +
>>> +DEFINE_PER_CPU(struct lgm_gptc_timer, lgm_timer_per_cpu);
>>> +
>> This is unusual. You'll have to provide a very detailed explanation
>> why this is needed.
> Sure will add it.
> It is required for the hotplug cpu support, and hotplug cpu is added because, the cpus on Lightning Mountain SoC can be online and offline dynamically.
> If CPUs come to online after the watchdog driver probe, hotplug CPU support helps to configure watchdog timer once CPU is online.
>

There is another watchdog in the system monitoring individual CPUs.
The watchdog subsystem monitors the system, not individual CPUs.
Individual CUPs are monitored with kernel/watchdog.c, and we should
keep it that way.

Guenter