[PATCH linux dev-4.10 v3 3/4] watchdog: aspeed: Support configuration of external signal properties
Andrew Jeffery
andrew at aj.id.au
Thu Jul 27 20:16:46 AEST 2017
Add support for configuring the drive strength and polarity on the
AST2500, and the pulse duration on both the AST2400 and AST2500.
Signed-off-by: Andrew Jeffery <andrew at aj.id.au>
---
drivers/watchdog/aspeed_wdt.c | 42 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c
index d29f75e90bb6..334e43f0164b 100644
--- a/drivers/watchdog/aspeed_wdt.c
+++ b/drivers/watchdog/aspeed_wdt.c
@@ -42,6 +42,14 @@ MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table);
#define WDT_CTRL_WDT_INTR BIT(2)
#define WDT_CTRL_RESET_SYSTEM BIT(1)
#define WDT_CTRL_ENABLE BIT(0)
+#define WDT_RESET_WIDTH 0x18
+#define WDT_RESET_WIDTH_ACTIVE_HIGH BIT(31)
+#define WDT_ACTIVE_HIGH_MAGIC (0xA5 << 24)
+#define WDT_ACTIVE_LOW_MAGIC (0x5A << 24)
+#define WDT_RESET_WIDTH_PUSH_PULL BIT(30)
+#define WDT_PUSH_PULL_MAGIC (0xA8 << 24)
+#define WDT_OPEN_DRAIN_MAGIC (0x8A << 24)
+#define WDT_RESET_WIDTH_DURATION 0xFFF
#define WDT_RESTART_MAGIC 0x4755
@@ -152,6 +160,7 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
struct resource *res;
struct device_node *np;
const char *reset_type;
+ u32 duration;
int ret;
wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
@@ -204,6 +213,39 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
}
+ if (of_device_is_compatible(np, "aspeed,ast2500-wdt")) {
+ u32 reg = readl(wdt->base + WDT_RESET_WIDTH);
+
+ reg &= WDT_RESET_WIDTH_DURATION;
+ if (of_property_read_bool(np, "aspeed,ext-push-pull"))
+ reg |= WDT_PUSH_PULL_MAGIC;
+ else
+ reg |= WDT_OPEN_DRAIN_MAGIC;
+
+ writel(reg, wdt->base + WDT_RESET_WIDTH);
+
+ reg &= WDT_RESET_WIDTH_DURATION;
+ if (of_property_read_bool(np, "aspeed,ext-active-high"))
+ reg |= WDT_ACTIVE_HIGH_MAGIC;
+ else
+ reg |= WDT_ACTIVE_LOW_MAGIC;
+
+ writel(reg, wdt->base + WDT_RESET_WIDTH);
+ }
+
+ if (!of_property_read_u32(np, "aspeed,ext-pulse-duration", &duration)) {
+ if (duration > WDT_RESET_WIDTH_DURATION) {
+ dev_err(&pdev->dev, "Invalid reset width\n");
+ return -EINVAL;
+ }
+
+ /*
+ * The watchdog is always configured with a 1MHz source, so
+ * there is no need to scale the microsecond value.
+ */
+ writel(duration, wdt->base + WDT_RESET_WIDTH);
+ }
+
ret = watchdog_register_device(&wdt->wdd);
if (ret) {
dev_err(&pdev->dev, "failed to register\n");
--
2.11.0
More information about the openbmc
mailing list