* [PATCH v2 1/5] watchdog: loongson1: Add missing MODULE_PARM_DESC
2025-11-07 6:01 [PATCH v2 0/5] Watchdog: Add Loongson-2K0300 watchdog support Binbin Zhou
@ 2025-11-07 6:01 ` Binbin Zhou
2025-11-07 6:01 ` [PATCH v2 2/5] watchdog: loongson1: Simplify ls1x_wdt_probe code Binbin Zhou
` (3 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Binbin Zhou @ 2025-11-07 6:01 UTC (permalink / raw)
To: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Keguang Zhang, Wim Van Sebroeck, Guenter Roeck
Cc: Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-watchdog,
Binbin Zhou
Add documentation for module_param so that they're visible with
modinfo command.
Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
drivers/watchdog/loongson1_wdt.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/watchdog/loongson1_wdt.c b/drivers/watchdog/loongson1_wdt.c
index 0587ff44d3a1..8502263b0d6f 100644
--- a/drivers/watchdog/loongson1_wdt.c
+++ b/drivers/watchdog/loongson1_wdt.c
@@ -18,10 +18,14 @@
#define DEFAULT_HEARTBEAT 30
static bool nowayout = WATCHDOG_NOWAYOUT;
-module_param(nowayout, bool, 0444);
+module_param(nowayout, bool, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
+ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
static unsigned int heartbeat;
-module_param(heartbeat, uint, 0444);
+module_param(heartbeat, uint, 0);
+MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (default="
+ __MODULE_STRING(DEFAULT_HEARTBEAT) ")");
struct ls1x_wdt_drvdata {
void __iomem *base;
--
2.47.3
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH v2 2/5] watchdog: loongson1: Simplify ls1x_wdt_probe code
2025-11-07 6:01 [PATCH v2 0/5] Watchdog: Add Loongson-2K0300 watchdog support Binbin Zhou
2025-11-07 6:01 ` [PATCH v2 1/5] watchdog: loongson1: Add missing MODULE_PARM_DESC Binbin Zhou
@ 2025-11-07 6:01 ` Binbin Zhou
2025-11-07 6:01 ` [PATCH v2 3/5] watchdog: loongson1: Drop CONFIG_OF Binbin Zhou
` (2 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Binbin Zhou @ 2025-11-07 6:01 UTC (permalink / raw)
To: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Keguang Zhang, Wim Van Sebroeck, Guenter Roeck
Cc: Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-watchdog,
Binbin Zhou
Remove meaningless output to simplify ls1x_wdt_probe().
Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
drivers/watchdog/loongson1_wdt.c | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/drivers/watchdog/loongson1_wdt.c b/drivers/watchdog/loongson1_wdt.c
index 8502263b0d6f..781f01f1f888 100644
--- a/drivers/watchdog/loongson1_wdt.c
+++ b/drivers/watchdog/loongson1_wdt.c
@@ -108,11 +108,11 @@ static int ls1x_wdt_probe(struct platform_device *pdev)
struct ls1x_wdt_drvdata *drvdata;
struct watchdog_device *ls1x_wdt;
unsigned long clk_rate;
- int err;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
if (!drvdata)
return -ENOMEM;
+ platform_set_drvdata(pdev, drvdata);
drvdata->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(drvdata->base))
@@ -139,15 +139,7 @@ static int ls1x_wdt_probe(struct platform_device *pdev)
watchdog_set_nowayout(ls1x_wdt, nowayout);
watchdog_set_drvdata(ls1x_wdt, drvdata);
- err = devm_watchdog_register_device(dev, &drvdata->wdt);
- if (err)
- return err;
-
- platform_set_drvdata(pdev, drvdata);
-
- dev_info(dev, "Loongson1 Watchdog driver registered\n");
-
- return 0;
+ return devm_watchdog_register_device(dev, &drvdata->wdt);
}
#ifdef CONFIG_OF
--
2.47.3
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH v2 3/5] watchdog: loongson1: Drop CONFIG_OF
2025-11-07 6:01 [PATCH v2 0/5] Watchdog: Add Loongson-2K0300 watchdog support Binbin Zhou
2025-11-07 6:01 ` [PATCH v2 1/5] watchdog: loongson1: Add missing MODULE_PARM_DESC Binbin Zhou
2025-11-07 6:01 ` [PATCH v2 2/5] watchdog: loongson1: Simplify ls1x_wdt_probe code Binbin Zhou
@ 2025-11-07 6:01 ` Binbin Zhou
2025-11-07 6:01 ` [PATCH v2 4/5] dt-bindings: watchdog: loongson,ls1x-wdt: Add ls2k0300-wdt compatible Binbin Zhou
2025-11-07 6:01 ` [PATCH v2 5/5] watchdog: loongson1: Add Loongson-2k0300 watchdog support Binbin Zhou
4 siblings, 0 replies; 8+ messages in thread
From: Binbin Zhou @ 2025-11-07 6:01 UTC (permalink / raw)
To: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Keguang Zhang, Wim Van Sebroeck, Guenter Roeck
Cc: Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-watchdog,
Binbin Zhou
The general recommendation is to not use of_match_ptr() or CONFIG_OF
ifdef.
Drop them.
Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
drivers/watchdog/loongson1_wdt.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/watchdog/loongson1_wdt.c b/drivers/watchdog/loongson1_wdt.c
index 781f01f1f888..255198cbf5bf 100644
--- a/drivers/watchdog/loongson1_wdt.c
+++ b/drivers/watchdog/loongson1_wdt.c
@@ -142,20 +142,18 @@ static int ls1x_wdt_probe(struct platform_device *pdev)
return devm_watchdog_register_device(dev, &drvdata->wdt);
}
-#ifdef CONFIG_OF
static const struct of_device_id ls1x_wdt_dt_ids[] = {
{ .compatible = "loongson,ls1b-wdt", },
{ .compatible = "loongson,ls1c-wdt", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ls1x_wdt_dt_ids);
-#endif
static struct platform_driver ls1x_wdt_driver = {
.probe = ls1x_wdt_probe,
.driver = {
.name = "ls1x-wdt",
- .of_match_table = of_match_ptr(ls1x_wdt_dt_ids),
+ .of_match_table = ls1x_wdt_dt_ids,
},
};
--
2.47.3
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH v2 4/5] dt-bindings: watchdog: loongson,ls1x-wdt: Add ls2k0300-wdt compatible
2025-11-07 6:01 [PATCH v2 0/5] Watchdog: Add Loongson-2K0300 watchdog support Binbin Zhou
` (2 preceding siblings ...)
2025-11-07 6:01 ` [PATCH v2 3/5] watchdog: loongson1: Drop CONFIG_OF Binbin Zhou
@ 2025-11-07 6:01 ` Binbin Zhou
2025-11-07 17:20 ` Conor Dooley
2025-11-07 6:01 ` [PATCH v2 5/5] watchdog: loongson1: Add Loongson-2k0300 watchdog support Binbin Zhou
4 siblings, 1 reply; 8+ messages in thread
From: Binbin Zhou @ 2025-11-07 6:01 UTC (permalink / raw)
To: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Keguang Zhang, Wim Van Sebroeck, Guenter Roeck
Cc: Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-watchdog,
Binbin Zhou
Add "loongson,ls2k0300-wdt" compatible to the dt-schema document, which
is similar to Loongson-1 watchdog, but with differences in some register
offsets and bit definitions.
Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
.../devicetree/bindings/watchdog/loongson,ls1x-wdt.yaml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/watchdog/loongson,ls1x-wdt.yaml b/Documentation/devicetree/bindings/watchdog/loongson,ls1x-wdt.yaml
index 81690d4b62a6..50a9b468c4a3 100644
--- a/Documentation/devicetree/bindings/watchdog/loongson,ls1x-wdt.yaml
+++ b/Documentation/devicetree/bindings/watchdog/loongson,ls1x-wdt.yaml
@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/watchdog/loongson,ls1x-wdt.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
-title: Loongson-1 Watchdog Timer
+title: Loongson Watchdog Timer
maintainers:
- Keguang Zhang <keguang.zhang@gmail.com>
@@ -17,6 +17,7 @@ properties:
enum:
- loongson,ls1b-wdt
- loongson,ls1c-wdt
+ - loongson,ls2k0300-wdt
reg:
maxItems: 1
--
2.47.3
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH v2 4/5] dt-bindings: watchdog: loongson,ls1x-wdt: Add ls2k0300-wdt compatible
2025-11-07 6:01 ` [PATCH v2 4/5] dt-bindings: watchdog: loongson,ls1x-wdt: Add ls2k0300-wdt compatible Binbin Zhou
@ 2025-11-07 17:20 ` Conor Dooley
0 siblings, 0 replies; 8+ messages in thread
From: Conor Dooley @ 2025-11-07 17:20 UTC (permalink / raw)
To: Binbin Zhou
Cc: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Keguang Zhang, Wim Van Sebroeck, Guenter Roeck,
Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-watchdog
[-- Attachment #1: Type: text/plain, Size: 75 bytes --]
Acked-by: Conor Dooley <conor.dooley@microchip.com>
pw-bot: not-applicable
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 5/5] watchdog: loongson1: Add Loongson-2k0300 watchdog support
2025-11-07 6:01 [PATCH v2 0/5] Watchdog: Add Loongson-2K0300 watchdog support Binbin Zhou
` (3 preceding siblings ...)
2025-11-07 6:01 ` [PATCH v2 4/5] dt-bindings: watchdog: loongson,ls1x-wdt: Add ls2k0300-wdt compatible Binbin Zhou
@ 2025-11-07 6:01 ` Binbin Zhou
2025-11-07 7:53 ` Huacai Chen
4 siblings, 1 reply; 8+ messages in thread
From: Binbin Zhou @ 2025-11-07 6:01 UTC (permalink / raw)
To: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Keguang Zhang, Wim Van Sebroeck, Guenter Roeck
Cc: Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-watchdog,
Binbin Zhou, Xiaochuang Mao
According to the manual, the Loongson-2K0300 watchdog is similar to the
Loongson-1, except for some register offsets and inconsistent register
bit definitions. Separate definitions via driver_data suffice.
Co-developed-by: Xiaochuang Mao <maoxiaochuan@loongson.cn>
Signed-off-by: Xiaochuang Mao <maoxiaochuan@loongson.cn>
Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
drivers/watchdog/Kconfig | 4 +-
drivers/watchdog/loongson1_wdt.c | 73 ++++++++++++++++++++++++++------
2 files changed, 62 insertions(+), 15 deletions(-)
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 0c25b2ed44eb..002eb785ca1f 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -1965,10 +1965,10 @@ config LANTIQ_WDT
config LOONGSON1_WDT
tristate "Loongson1 SoC hardware watchdog"
- depends on MACH_LOONGSON32 || COMPILE_TEST
+ depends on MACH_LOONGSON32 || MACH_LOONGSON64 || COMPILE_TEST
select WATCHDOG_CORE
help
- Hardware driver for the Loongson1 SoC Watchdog Timer.
+ Hardware driver for the Loongson family Watchdog Timer.
config RALINK_WDT
tristate "Ralink SoC watchdog"
diff --git a/drivers/watchdog/loongson1_wdt.c b/drivers/watchdog/loongson1_wdt.c
index 255198cbf5bf..2417519717cc 100644
--- a/drivers/watchdog/loongson1_wdt.c
+++ b/drivers/watchdog/loongson1_wdt.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2016 Yang Ling <gnaygnil@gmail.com>
+ * Copyright (C) 2025 Binbin Zhou <zhoubinbin@loongson.cn>
*/
#include <linux/clk.h>
@@ -10,10 +11,8 @@
#include <linux/platform_device.h>
#include <linux/watchdog.h>
-/* Loongson 1 Watchdog Register Definitions */
+/* Loongson Watchdog Register Definitions */
#define WDT_EN 0x0
-#define WDT_TIMER 0x4
-#define WDT_SET 0x8
#define DEFAULT_HEARTBEAT 30
@@ -27,18 +26,37 @@ module_param(heartbeat, uint, 0);
MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (default="
__MODULE_STRING(DEFAULT_HEARTBEAT) ")");
+struct ls1x_wdt_pdata {
+ u32 timer_offset;
+ u32 set_offset;
+ u32 wdt_en_bit;
+};
+
+static const struct ls1x_wdt_pdata ls1b_wdt_pdata = {
+ .timer_offset = 0x4,
+ .set_offset = 0x8,
+ .wdt_en_bit = BIT(0),
+};
+
+static const struct ls1x_wdt_pdata ls2k0300_wdt_pdata = {
+ .timer_offset = 0x8,
+ .set_offset = 0x4,
+ .wdt_en_bit = BIT(1),
+};
+
struct ls1x_wdt_drvdata {
void __iomem *base;
struct clk *clk;
unsigned long clk_rate;
struct watchdog_device wdt;
+ const struct ls1x_wdt_pdata *pdata;
};
static int ls1x_wdt_ping(struct watchdog_device *wdt_dev)
{
struct ls1x_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev);
- writel(0x1, drvdata->base + WDT_SET);
+ writel(0x1, drvdata->base + drvdata->pdata->set_offset);
return 0;
}
@@ -53,7 +71,7 @@ static int ls1x_wdt_set_timeout(struct watchdog_device *wdt_dev,
wdt_dev->timeout = timeout;
counts = drvdata->clk_rate * min(timeout, max_hw_heartbeat);
- writel(counts, drvdata->base + WDT_TIMER);
+ writel(counts, drvdata->base + drvdata->pdata->timer_offset);
return 0;
}
@@ -62,7 +80,7 @@ static int ls1x_wdt_start(struct watchdog_device *wdt_dev)
{
struct ls1x_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev);
- writel(0x1, drvdata->base + WDT_EN);
+ writel(drvdata->pdata->wdt_en_bit, drvdata->base + WDT_EN);
return 0;
}
@@ -70,8 +88,10 @@ static int ls1x_wdt_start(struct watchdog_device *wdt_dev)
static int ls1x_wdt_stop(struct watchdog_device *wdt_dev)
{
struct ls1x_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev);
+ u32 val = readl(drvdata->base + WDT_EN);
- writel(0x0, drvdata->base + WDT_EN);
+ val &= ~(drvdata->pdata->wdt_en_bit);
+ writel(val, drvdata->base + WDT_EN);
return 0;
}
@@ -81,9 +101,9 @@ static int ls1x_wdt_restart(struct watchdog_device *wdt_dev,
{
struct ls1x_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev);
- writel(0x1, drvdata->base + WDT_EN);
- writel(0x1, drvdata->base + WDT_TIMER);
- writel(0x1, drvdata->base + WDT_SET);
+ writel(drvdata->pdata->wdt_en_bit, drvdata->base + WDT_EN);
+ writel(0x1, drvdata->base + drvdata->pdata->timer_offset);
+ writel(0x1, drvdata->base + drvdata->pdata->set_offset);
return 0;
}
@@ -114,6 +134,8 @@ static int ls1x_wdt_probe(struct platform_device *pdev)
return -ENOMEM;
platform_set_drvdata(pdev, drvdata);
+ drvdata->pdata = of_device_get_match_data(dev);
+
drvdata->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(drvdata->base))
return PTR_ERR(drvdata->base);
@@ -142,9 +164,32 @@ static int ls1x_wdt_probe(struct platform_device *pdev)
return devm_watchdog_register_device(dev, &drvdata->wdt);
}
+static int ls1x_wdt_resume(struct device *dev)
+{
+ struct ls1x_wdt_drvdata *data = dev_get_drvdata(dev);
+
+ if (watchdog_active(&data->wdt))
+ ls1x_wdt_start(&data->wdt);
+
+ return 0;
+}
+
+static int ls1x_wdt_suspend(struct device *dev)
+{
+ struct ls1x_wdt_drvdata *data = dev_get_drvdata(dev);
+
+ if (watchdog_active(&data->wdt))
+ ls1x_wdt_stop(&data->wdt);
+
+ return 0;
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(ls1x_wdt_pm_ops, ls1x_wdt_suspend, ls1x_wdt_resume);
+
static const struct of_device_id ls1x_wdt_dt_ids[] = {
- { .compatible = "loongson,ls1b-wdt", },
- { .compatible = "loongson,ls1c-wdt", },
+ { .compatible = "loongson,ls1b-wdt", .data = &ls1b_wdt_pdata },
+ { .compatible = "loongson,ls1c-wdt", .data = &ls1b_wdt_pdata },
+ { .compatible = "loongson,ls2k0300-wdt", .data = &ls2k0300_wdt_pdata },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ls1x_wdt_dt_ids);
@@ -154,11 +199,13 @@ static struct platform_driver ls1x_wdt_driver = {
.driver = {
.name = "ls1x-wdt",
.of_match_table = ls1x_wdt_dt_ids,
+ .pm = pm_ptr(&ls1x_wdt_pm_ops),
},
};
module_platform_driver(ls1x_wdt_driver);
MODULE_AUTHOR("Yang Ling <gnaygnil@gmail.com>");
-MODULE_DESCRIPTION("Loongson1 Watchdog Driver");
+MODULE_AUTHOR("Binbin Zhou <zhoubinbin@loongson.cn>");
+MODULE_DESCRIPTION("Loongson Watchdog Driver");
MODULE_LICENSE("GPL");
--
2.47.3
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH v2 5/5] watchdog: loongson1: Add Loongson-2k0300 watchdog support
2025-11-07 6:01 ` [PATCH v2 5/5] watchdog: loongson1: Add Loongson-2k0300 watchdog support Binbin Zhou
@ 2025-11-07 7:53 ` Huacai Chen
0 siblings, 0 replies; 8+ messages in thread
From: Huacai Chen @ 2025-11-07 7:53 UTC (permalink / raw)
To: Binbin Zhou
Cc: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Keguang Zhang, Wim Van Sebroeck, Guenter Roeck,
Xuerui Wang, loongarch, devicetree, linux-watchdog,
Xiaochuang Mao
Hi, Binbin,
On Fri, Nov 7, 2025 at 2:02 PM Binbin Zhou <zhoubinbin@loongson.cn> wrote:
>
> According to the manual, the Loongson-2K0300 watchdog is similar to the
> Loongson-1, except for some register offsets and inconsistent register
> bit definitions. Separate definitions via driver_data suffice.
>
> Co-developed-by: Xiaochuang Mao <maoxiaochuan@loongson.cn>
> Signed-off-by: Xiaochuang Mao <maoxiaochuan@loongson.cn>
> Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
> ---
> drivers/watchdog/Kconfig | 4 +-
> drivers/watchdog/loongson1_wdt.c | 73 ++++++++++++++++++++++++++------
> 2 files changed, 62 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> index 0c25b2ed44eb..002eb785ca1f 100644
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -1965,10 +1965,10 @@ config LANTIQ_WDT
>
> config LOONGSON1_WDT
> tristate "Loongson1 SoC hardware watchdog"
> - depends on MACH_LOONGSON32 || COMPILE_TEST
> + depends on MACH_LOONGSON32 || MACH_LOONGSON64 || COMPILE_TEST
> select WATCHDOG_CORE
> help
> - Hardware driver for the Loongson1 SoC Watchdog Timer.
> + Hardware driver for the Loongson family Watchdog Timer.
>
> config RALINK_WDT
> tristate "Ralink SoC watchdog"
> diff --git a/drivers/watchdog/loongson1_wdt.c b/drivers/watchdog/loongson1_wdt.c
> index 255198cbf5bf..2417519717cc 100644
> --- a/drivers/watchdog/loongson1_wdt.c
> +++ b/drivers/watchdog/loongson1_wdt.c
> @@ -1,6 +1,7 @@
> // SPDX-License-Identifier: GPL-2.0-or-later
> /*
> * Copyright (c) 2016 Yang Ling <gnaygnil@gmail.com>
> + * Copyright (C) 2025 Binbin Zhou <zhoubinbin@loongson.cn>
> */
>
> #include <linux/clk.h>
> @@ -10,10 +11,8 @@
> #include <linux/platform_device.h>
> #include <linux/watchdog.h>
>
> -/* Loongson 1 Watchdog Register Definitions */
> +/* Loongson Watchdog Register Definitions */
> #define WDT_EN 0x0
> -#define WDT_TIMER 0x4
> -#define WDT_SET 0x8
>
> #define DEFAULT_HEARTBEAT 30
>
> @@ -27,18 +26,37 @@ module_param(heartbeat, uint, 0);
> MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (default="
> __MODULE_STRING(DEFAULT_HEARTBEAT) ")");
>
> +struct ls1x_wdt_pdata {
> + u32 timer_offset;
> + u32 set_offset;
> + u32 wdt_en_bit;
> +};
> +
> +static const struct ls1x_wdt_pdata ls1b_wdt_pdata = {
> + .timer_offset = 0x4,
> + .set_offset = 0x8,
> + .wdt_en_bit = BIT(0),
> +};
> +
> +static const struct ls1x_wdt_pdata ls2k0300_wdt_pdata = {
> + .timer_offset = 0x8,
> + .set_offset = 0x4,
> + .wdt_en_bit = BIT(1),
> +};
> +
> struct ls1x_wdt_drvdata {
> void __iomem *base;
> struct clk *clk;
> unsigned long clk_rate;
> struct watchdog_device wdt;
> + const struct ls1x_wdt_pdata *pdata;
> };
>
> static int ls1x_wdt_ping(struct watchdog_device *wdt_dev)
> {
> struct ls1x_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev);
>
> - writel(0x1, drvdata->base + WDT_SET);
> + writel(0x1, drvdata->base + drvdata->pdata->set_offset);
>
> return 0;
> }
> @@ -53,7 +71,7 @@ static int ls1x_wdt_set_timeout(struct watchdog_device *wdt_dev,
> wdt_dev->timeout = timeout;
>
> counts = drvdata->clk_rate * min(timeout, max_hw_heartbeat);
> - writel(counts, drvdata->base + WDT_TIMER);
> + writel(counts, drvdata->base + drvdata->pdata->timer_offset);
>
> return 0;
> }
> @@ -62,7 +80,7 @@ static int ls1x_wdt_start(struct watchdog_device *wdt_dev)
> {
> struct ls1x_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev);
>
> - writel(0x1, drvdata->base + WDT_EN);
> + writel(drvdata->pdata->wdt_en_bit, drvdata->base + WDT_EN);
>
> return 0;
> }
> @@ -70,8 +88,10 @@ static int ls1x_wdt_start(struct watchdog_device *wdt_dev)
> static int ls1x_wdt_stop(struct watchdog_device *wdt_dev)
> {
> struct ls1x_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev);
> + u32 val = readl(drvdata->base + WDT_EN);
>
> - writel(0x0, drvdata->base + WDT_EN);
> + val &= ~(drvdata->pdata->wdt_en_bit);
> + writel(val, drvdata->base + WDT_EN);
>
> return 0;
> }
> @@ -81,9 +101,9 @@ static int ls1x_wdt_restart(struct watchdog_device *wdt_dev,
> {
> struct ls1x_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev);
>
> - writel(0x1, drvdata->base + WDT_EN);
> - writel(0x1, drvdata->base + WDT_TIMER);
> - writel(0x1, drvdata->base + WDT_SET);
> + writel(drvdata->pdata->wdt_en_bit, drvdata->base + WDT_EN);
> + writel(0x1, drvdata->base + drvdata->pdata->timer_offset);
> + writel(0x1, drvdata->base + drvdata->pdata->set_offset);
>
> return 0;
> }
> @@ -114,6 +134,8 @@ static int ls1x_wdt_probe(struct platform_device *pdev)
> return -ENOMEM;
> platform_set_drvdata(pdev, drvdata);
>
> + drvdata->pdata = of_device_get_match_data(dev);
> +
> drvdata->base = devm_platform_ioremap_resource(pdev, 0);
> if (IS_ERR(drvdata->base))
> return PTR_ERR(drvdata->base);
> @@ -142,9 +164,32 @@ static int ls1x_wdt_probe(struct platform_device *pdev)
> return devm_watchdog_register_device(dev, &drvdata->wdt);
> }
>
> +static int ls1x_wdt_resume(struct device *dev)
> +{
> + struct ls1x_wdt_drvdata *data = dev_get_drvdata(dev);
> +
> + if (watchdog_active(&data->wdt))
> + ls1x_wdt_start(&data->wdt);
> +
> + return 0;
> +}
> +
> +static int ls1x_wdt_suspend(struct device *dev)
> +{
> + struct ls1x_wdt_drvdata *data = dev_get_drvdata(dev);
> +
> + if (watchdog_active(&data->wdt))
> + ls1x_wdt_stop(&data->wdt);
> +
> + return 0;
> +}
We usually define suspend first and then resume, that looks more
natural. But this is not a big deal.
Others look good to me.
For the whole series,
Reviewed-by: Huacai Chen <chenhuacai@loongson.cn>
Huacai
> +
> +static DEFINE_SIMPLE_DEV_PM_OPS(ls1x_wdt_pm_ops, ls1x_wdt_suspend, ls1x_wdt_resume);
> +
> static const struct of_device_id ls1x_wdt_dt_ids[] = {
> - { .compatible = "loongson,ls1b-wdt", },
> - { .compatible = "loongson,ls1c-wdt", },
> + { .compatible = "loongson,ls1b-wdt", .data = &ls1b_wdt_pdata },
> + { .compatible = "loongson,ls1c-wdt", .data = &ls1b_wdt_pdata },
> + { .compatible = "loongson,ls2k0300-wdt", .data = &ls2k0300_wdt_pdata },
> { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, ls1x_wdt_dt_ids);
> @@ -154,11 +199,13 @@ static struct platform_driver ls1x_wdt_driver = {
> .driver = {
> .name = "ls1x-wdt",
> .of_match_table = ls1x_wdt_dt_ids,
> + .pm = pm_ptr(&ls1x_wdt_pm_ops),
> },
> };
>
> module_platform_driver(ls1x_wdt_driver);
>
> MODULE_AUTHOR("Yang Ling <gnaygnil@gmail.com>");
> -MODULE_DESCRIPTION("Loongson1 Watchdog Driver");
> +MODULE_AUTHOR("Binbin Zhou <zhoubinbin@loongson.cn>");
> +MODULE_DESCRIPTION("Loongson Watchdog Driver");
> MODULE_LICENSE("GPL");
> --
> 2.47.3
>
^ permalink raw reply [flat|nested] 8+ messages in thread