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.k...@linux.intel.com>
---
  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.

Regards,
-Dilip

Guenter


Reply via email to