* [PATCH linux dev-6.0 1/3] watchdog: aspeed: Add pre-timeout interrupt support
2022-10-19 15:07 [PATCH linux dev-6.0 0/3] watchdog: aspeed: Add pre-timeout interrupt support Eddie James
@ 2022-10-19 15:07 ` Eddie James
2022-10-19 15:07 ` [PATCH linux dev-6.0 2/3] ARM: dts: aspeed: Setup watchdog pre-timeout interrupt Eddie James
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Eddie James @ 2022-10-19 15:07 UTC (permalink / raw)
To: openbmc; +Cc: Eddie James, joel
Enable the pre-timeout interrupt if requested by device property.
Signed-off-by: Eddie James <eajames@linux.ibm.com>
---
drivers/watchdog/aspeed_wdt.c | 54 +++++++++++++++++++++++++++++++++--
1 file changed, 52 insertions(+), 2 deletions(-)
diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c
index bd06622813eb..6a6d53a9e21c 100644
--- a/drivers/watchdog/aspeed_wdt.c
+++ b/drivers/watchdog/aspeed_wdt.c
@@ -5,11 +5,14 @@
* Joel Stanley <joel@jms.id.au>
*/
+#include <linux/bits.h>
#include <linux/delay.h>
+#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/watchdog.h>
@@ -22,24 +25,37 @@ struct aspeed_wdt {
struct watchdog_device wdd;
void __iomem *base;
u32 ctrl;
+ u8 stop : 1;
};
struct aspeed_wdt_config {
u32 ext_pulse_width_mask;
+ u32 irq_shift;
+ u32 irq_mask;
};
static const struct aspeed_wdt_config ast2400_config = {
.ext_pulse_width_mask = 0xff,
+ .irq_shift = 0,
+ .irq_mask = 0,
};
static const struct aspeed_wdt_config ast2500_config = {
.ext_pulse_width_mask = 0xfffff,
+ .irq_shift = 12,
+ .irq_mask = GENMASK(31, 12),
+};
+
+static const struct aspeed_wdt_config ast2600_config = {
+ .ext_pulse_width_mask = 0xfffff,
+ .irq_shift = 0,
+ .irq_mask = GENMASK(31, 10),
};
static const struct of_device_id aspeed_wdt_of_table[] = {
{ .compatible = "aspeed,ast2400-wdt", .data = &ast2400_config },
{ .compatible = "aspeed,ast2500-wdt", .data = &ast2500_config },
- { .compatible = "aspeed,ast2600-wdt", .data = &ast2500_config },
+ { .compatible = "aspeed,ast2600-wdt", .data = &ast2600_config },
{ },
};
MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table);
@@ -58,6 +74,7 @@ MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table);
#define WDT_CTRL_RESET_SYSTEM BIT(1)
#define WDT_CTRL_ENABLE BIT(0)
#define WDT_TIMEOUT_STATUS 0x10
+#define WDT_TIMEOUT_STATUS_IRQ BIT(2)
#define WDT_TIMEOUT_STATUS_BOOT_SECONDARY BIT(1)
#define WDT_CLEAR_TIMEOUT_STATUS 0x14
#define WDT_CLEAR_TIMEOUT_AND_BOOT_CODE_SELECTION BIT(0)
@@ -243,6 +260,17 @@ static const struct watchdog_info aspeed_wdt_info = {
.identity = KBUILD_MODNAME,
};
+static irqreturn_t aspeed_wdt_irq(int irq, void *arg)
+{
+ struct aspeed_wdt *wdt = arg;
+ u32 status = readl(wdt->base + WDT_TIMEOUT_STATUS);
+
+ if (status & WDT_TIMEOUT_STATUS_IRQ)
+ panic("Watchdog pre-timeout IRQ");
+
+ return IRQ_NONE;
+}
+
static int aspeed_wdt_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -253,6 +281,7 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
const char *reset_type;
u32 duration;
u32 status;
+ u32 timeout = 0;
int ret;
wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
@@ -291,6 +320,27 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
if (of_device_is_compatible(np, "aspeed,ast2400-wdt"))
wdt->ctrl = WDT_CTRL_1MHZ_CLK;
+ if (config->irq_mask) {
+ if (!of_property_read_u32(np, "aspeed,pre-timeout-irq-us", &timeout) && timeout) {
+ int irq = platform_get_irq(pdev, 0);
+
+ if (irq < 0) {
+ dev_warn(dev, "Couldn't find IRQ: %d\n", irq);
+ timeout = 0;
+ } else {
+ ret = devm_request_irq(dev, irq, aspeed_wdt_irq, IRQF_SHARED,
+ dev_name(dev), wdt);
+ if (ret) {
+ dev_warn(dev, "Couldn't request IRQ:%d\n", ret);
+ timeout = 0;
+ } else {
+ wdt->ctrl |= ((timeout << config->irq_shift) &
+ config->irq_mask) | WDT_CTRL_WDT_INTR;
+ }
+ }
+ }
+ }
+
/*
* Control reset on a per-device basis to ensure the
* host is not affected by a BMC reboot
@@ -308,7 +358,7 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
else if (!strcmp(reset_type, "system"))
wdt->ctrl |= WDT_CTRL_RESET_MODE_FULL_CHIP |
WDT_CTRL_RESET_SYSTEM;
- else if (strcmp(reset_type, "none"))
+ else if (strcmp(reset_type, "none") && !timeout)
return -EINVAL;
}
if (of_property_read_bool(np, "aspeed,external-signal"))
--
2.31.1
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH linux dev-6.0 2/3] ARM: dts: aspeed: Setup watchdog pre-timeout interrupt
2022-10-19 15:07 [PATCH linux dev-6.0 0/3] watchdog: aspeed: Add pre-timeout interrupt support Eddie James
2022-10-19 15:07 ` [PATCH linux dev-6.0 1/3] " Eddie James
@ 2022-10-19 15:07 ` Eddie James
2022-10-19 15:07 ` [PATCH linux dev-6.0 3/3] ARM: dts: aspeed: p10bmc: Set " Eddie James
2022-10-20 5:12 ` [PATCH linux dev-6.0 0/3] watchdog: aspeed: Add pre-timeout interrupt support Joel Stanley
3 siblings, 0 replies; 5+ messages in thread
From: Eddie James @ 2022-10-19 15:07 UTC (permalink / raw)
To: openbmc; +Cc: Eddie James, joel
Specify the interrupt lines for the base SOCs that support it.
Signed-off-by: Eddie James <eajames@linux.ibm.com>
---
arch/arm/boot/dts/aspeed-g5.dtsi | 3 +++
arch/arm/boot/dts/aspeed-g6.dtsi | 4 ++++
2 files changed, 7 insertions(+)
diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi
index c89092c3905b..2ed19bb5710a 100644
--- a/arch/arm/boot/dts/aspeed-g5.dtsi
+++ b/arch/arm/boot/dts/aspeed-g5.dtsi
@@ -402,18 +402,21 @@ wdt1: watchdog@1e785000 {
compatible = "aspeed,ast2500-wdt";
reg = <0x1e785000 0x20>;
clocks = <&syscon ASPEED_CLK_APB>;
+ interrupts = <27>;
};
wdt2: watchdog@1e785020 {
compatible = "aspeed,ast2500-wdt";
reg = <0x1e785020 0x20>;
clocks = <&syscon ASPEED_CLK_APB>;
+ interrupts = <27>;
};
wdt3: watchdog@1e785040 {
compatible = "aspeed,ast2500-wdt";
reg = <0x1e785040 0x20>;
clocks = <&syscon ASPEED_CLK_APB>;
+ interrupts = <27>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi
index 1387a763a6a5..a9a53724f2af 100644
--- a/arch/arm/boot/dts/aspeed-g6.dtsi
+++ b/arch/arm/boot/dts/aspeed-g6.dtsi
@@ -531,23 +531,27 @@ uart5: serial@1e784000 {
wdt1: watchdog@1e785000 {
compatible = "aspeed,ast2600-wdt";
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x1e785000 0x40>;
};
wdt2: watchdog@1e785040 {
compatible = "aspeed,ast2600-wdt";
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x1e785040 0x40>;
status = "disabled";
};
wdt3: watchdog@1e785080 {
compatible = "aspeed,ast2600-wdt";
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x1e785080 0x40>;
status = "disabled";
};
wdt4: watchdog@1e7850c0 {
compatible = "aspeed,ast2600-wdt";
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x1e7850C0 0x40>;
status = "disabled";
};
--
2.31.1
^ permalink raw reply related [flat|nested] 5+ messages in thread