Lines Matching +full:irq +full:- +full:push +full:- +full:pull

1 // SPDX-License-Identifier: GPL-2.0-or-later
52 .compatible = "aspeed,ast2400-scu",
64 .compatible = "aspeed,ast2500-scu",
76 .compatible = "aspeed,ast2600-scu",
84 { .compatible = "aspeed,ast2400-wdt", .data = &ast2400_config },
85 { .compatible = "aspeed,ast2500-wdt", .data = &ast2500_config },
86 { .compatible = "aspeed,ast2600-wdt", .data = &ast2600_config },
117 * * Drive mode: push-pull vs open-drain
130 * and bit 30 represents push-pull or open-drain. With respect to write, magic
158 wdt->ctrl |= WDT_CTRL_ENABLE; in aspeed_wdt_enable()
160 writel(0, wdt->base + WDT_CTRL); in aspeed_wdt_enable()
161 writel(count, wdt->base + WDT_RELOAD_VALUE); in aspeed_wdt_enable()
162 writel(WDT_RESTART_MAGIC, wdt->base + WDT_RESTART); in aspeed_wdt_enable()
163 writel(wdt->ctrl, wdt->base + WDT_CTRL); in aspeed_wdt_enable()
170 aspeed_wdt_enable(wdt, wdd->timeout * WDT_RATE_1MHZ); in aspeed_wdt_start()
179 wdt->ctrl &= ~WDT_CTRL_ENABLE; in aspeed_wdt_stop()
180 writel(wdt->ctrl, wdt->base + WDT_CTRL); in aspeed_wdt_stop()
189 writel(WDT_RESTART_MAGIC, wdt->base + WDT_RESTART); in aspeed_wdt_ping()
200 wdd->timeout = timeout; in aspeed_wdt_set_timeout()
202 actual = min(timeout, wdd->max_hw_heartbeat_ms / 1000); in aspeed_wdt_set_timeout()
204 writel(actual * WDT_RATE_1MHZ, wdt->base + WDT_RELOAD_VALUE); in aspeed_wdt_set_timeout()
205 writel(WDT_RESTART_MAGIC, wdt->base + WDT_RESTART); in aspeed_wdt_set_timeout()
215 u32 s = wdt->cfg->irq_shift; in aspeed_wdt_set_pretimeout()
216 u32 m = wdt->cfg->irq_mask; in aspeed_wdt_set_pretimeout()
218 wdd->pretimeout = pretimeout; in aspeed_wdt_set_pretimeout()
219 wdt->ctrl &= ~m; in aspeed_wdt_set_pretimeout()
221 wdt->ctrl |= ((actual << s) & m) | WDT_CTRL_WDT_INTR; in aspeed_wdt_set_pretimeout()
223 wdt->ctrl &= ~WDT_CTRL_WDT_INTR; in aspeed_wdt_set_pretimeout()
225 writel(wdt->ctrl, wdt->base + WDT_CTRL); in aspeed_wdt_set_pretimeout()
235 wdt->ctrl &= ~WDT_CTRL_BOOT_SECONDARY; in aspeed_wdt_restart()
247 struct aspeed_wdt_scu scu = wdt->cfg->scu; in aspeed_wdt_update_bootstatus()
255 if (!of_device_is_compatible(pdev->dev.of_node, "aspeed,ast2400-wdt")) { in aspeed_wdt_update_bootstatus()
257 idx = ((intptr_t)wdt->base & 0x00000fff) / (uintptr_t)resource_size(res); in aspeed_wdt_update_bootstatus()
262 wdt->wdd.bootstatus = WDIOS_UNKNOWN; in aspeed_wdt_update_bootstatus()
268 wdt->wdd.bootstatus = WDIOS_UNKNOWN; in aspeed_wdt_update_bootstatus()
277 wdt->wdd.bootstatus = WDIOF_CARDRESET; in aspeed_wdt_update_bootstatus()
280 if (of_device_is_compatible(pdev->dev.of_node, "aspeed,ast2400-wdt") || in aspeed_wdt_update_bootstatus()
281 of_device_is_compatible(pdev->dev.of_node, "aspeed,ast2500-wdt")) { in aspeed_wdt_update_bootstatus()
298 u32 status = readl(wdt->base + WDT_TIMEOUT_STATUS); in access_cs0_show()
312 return -EINVAL; in access_cs0_store()
316 wdt->base + WDT_CLEAR_TIMEOUT_STATUS); in access_cs0_store()
323 * flash with 'alt-boot' option.
329 * (CS0->CS1, CS1->CS0) to (CS0->CS0, CS1->CS1).
372 static irqreturn_t aspeed_wdt_irq(int irq, void *arg) in aspeed_wdt_irq() argument
376 u32 status = readl(wdt->base + WDT_TIMEOUT_STATUS); in aspeed_wdt_irq()
386 struct device *dev = &pdev->dev; in aspeed_wdt_probe()
397 return -ENOMEM; in aspeed_wdt_probe()
399 np = dev->of_node; in aspeed_wdt_probe()
403 return -EINVAL; in aspeed_wdt_probe()
404 wdt->cfg = ofdid->data; in aspeed_wdt_probe()
406 wdt->base = devm_platform_ioremap_resource(pdev, 0); in aspeed_wdt_probe()
407 if (IS_ERR(wdt->base)) in aspeed_wdt_probe()
408 return PTR_ERR(wdt->base); in aspeed_wdt_probe()
410 wdt->wdd.info = &aspeed_wdt_info; in aspeed_wdt_probe()
412 if (wdt->cfg->irq_mask) { in aspeed_wdt_probe()
413 int irq = platform_get_irq_optional(pdev, 0); in aspeed_wdt_probe() local
415 if (irq > 0) { in aspeed_wdt_probe()
416 ret = devm_request_irq(dev, irq, aspeed_wdt_irq, in aspeed_wdt_probe()
422 wdt->wdd.info = &aspeed_wdt_pretimeout_info; in aspeed_wdt_probe()
426 wdt->wdd.ops = &aspeed_wdt_ops; in aspeed_wdt_probe()
427 wdt->wdd.max_hw_heartbeat_ms = WDT_MAX_TIMEOUT_MS; in aspeed_wdt_probe()
428 wdt->wdd.parent = dev; in aspeed_wdt_probe()
430 wdt->wdd.timeout = WDT_DEFAULT_TIMEOUT; in aspeed_wdt_probe()
431 watchdog_init_timeout(&wdt->wdd, 0, dev); in aspeed_wdt_probe()
433 watchdog_set_nowayout(&wdt->wdd, nowayout); in aspeed_wdt_probe()
437 * - ast2400 wdt can run at PCLK, or 1MHz in aspeed_wdt_probe()
438 * - ast2500 only runs at 1MHz, hard coding bit 4 to 1 in aspeed_wdt_probe()
439 * - ast2600 always runs at 1MHz in aspeed_wdt_probe()
443 if (of_device_is_compatible(np, "aspeed,ast2400-wdt")) in aspeed_wdt_probe()
444 wdt->ctrl = WDT_CTRL_1MHZ_CLK; in aspeed_wdt_probe()
447 * Control reset on a per-device basis to ensure the in aspeed_wdt_probe()
450 ret = of_property_read_string(np, "aspeed,reset-type", &reset_type); in aspeed_wdt_probe()
452 wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC | WDT_CTRL_RESET_SYSTEM; in aspeed_wdt_probe()
455 wdt->ctrl |= WDT_CTRL_RESET_MODE_ARM_CPU | in aspeed_wdt_probe()
458 wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC | in aspeed_wdt_probe()
461 wdt->ctrl |= WDT_CTRL_RESET_MODE_FULL_CHIP | in aspeed_wdt_probe()
464 return -EINVAL; in aspeed_wdt_probe()
466 if (of_property_read_bool(np, "aspeed,external-signal")) in aspeed_wdt_probe()
467 wdt->ctrl |= WDT_CTRL_WDT_EXT; in aspeed_wdt_probe()
468 if (of_property_read_bool(np, "aspeed,alt-boot")) in aspeed_wdt_probe()
469 wdt->ctrl |= WDT_CTRL_BOOT_SECONDARY; in aspeed_wdt_probe()
471 if (readl(wdt->base + WDT_CTRL) & WDT_CTRL_ENABLE) { in aspeed_wdt_probe()
474 * write wdt->ctrl to WDT_CTRL to ensure the watchdog's in aspeed_wdt_probe()
478 aspeed_wdt_start(&wdt->wdd); in aspeed_wdt_probe()
479 set_bit(WDOG_HW_RUNNING, &wdt->wdd.status); in aspeed_wdt_probe()
482 if ((of_device_is_compatible(np, "aspeed,ast2500-wdt")) || in aspeed_wdt_probe()
483 (of_device_is_compatible(np, "aspeed,ast2600-wdt"))) { in aspeed_wdt_probe()
485 size_t nrstmask = of_device_is_compatible(np, "aspeed,ast2600-wdt") ? 2 : 1; in aspeed_wdt_probe()
486 u32 reg = readl(wdt->base + WDT_RESET_WIDTH); in aspeed_wdt_probe()
488 reg &= wdt->cfg->ext_pulse_width_mask; in aspeed_wdt_probe()
489 if (of_property_read_bool(np, "aspeed,ext-active-high")) in aspeed_wdt_probe()
494 writel(reg, wdt->base + WDT_RESET_WIDTH); in aspeed_wdt_probe()
496 reg &= wdt->cfg->ext_pulse_width_mask; in aspeed_wdt_probe()
497 if (of_property_read_bool(np, "aspeed,ext-push-pull")) in aspeed_wdt_probe()
502 writel(reg, wdt->base + WDT_RESET_WIDTH); in aspeed_wdt_probe()
504 ret = of_property_read_u32_array(np, "aspeed,reset-mask", reset_mask, nrstmask); in aspeed_wdt_probe()
506 writel(reset_mask[0], wdt->base + WDT_RESET_MASK1); in aspeed_wdt_probe()
508 writel(reset_mask[1], wdt->base + WDT_RESET_MASK2); in aspeed_wdt_probe()
512 if (!of_property_read_u32(np, "aspeed,ext-pulse-duration", &duration)) { in aspeed_wdt_probe()
513 u32 max_duration = wdt->cfg->ext_pulse_width_mask + 1; in aspeed_wdt_probe()
526 * need to offset it - from the datasheet: in aspeed_wdt_probe()
535 writel(duration - 1, wdt->base + WDT_RESET_WIDTH); in aspeed_wdt_probe()
540 status = readl(wdt->base + WDT_TIMEOUT_STATUS); in aspeed_wdt_probe()
542 if (of_device_is_compatible(np, "aspeed,ast2400-wdt") || in aspeed_wdt_probe()
543 of_device_is_compatible(np, "aspeed,ast2500-wdt")) in aspeed_wdt_probe()
544 wdt->wdd.groups = bswitch_groups; in aspeed_wdt_probe()
549 return devm_watchdog_register_device(dev, &wdt->wdd); in aspeed_wdt_probe()