Commit 96752be4 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'linux-watchdog-5.19-rc1' of git://www.linux-watchdog.org/linux-watchdog

Pull watchdog updates from Wim Van Sebroeck:

 - Add MediaTek MT8186 support

 - Add Mediatek MT7986 reset-controller support

 - Add i.MX93 support

 - Add watchdog driver for Sunplus SP7021

 - Add SC8180X and SC8280XP compatibles

 - Add Renesas RZ/N1 Watchdog driver and support for RZ/N1

 - rzg2l_wdt improvements and fixes

 - Several other improvements and fixes

* tag 'linux-watchdog-5.19-rc1' of git://www.linux-watchdog.org/linux-watchdog: (38 commits)
  watchdog: ts4800_wdt: Fix refcount leak in ts4800_wdt_probe
  dt-bindings: watchdog: renesas,wdt: R-Car V3U is R-Car Gen4
  watchdog: Add Renesas RZ/N1 Watchdog driver
  dt-bindings: watchdog: renesas,wdt: Add support for RZ/N1
  watchdog: wdat_wdt: Stop watchdog when uninstalling module
  watchdog: wdat_wdt: Stop watchdog when rebooting the system
  watchdog: wdat_wdt: Using the existing function to check parameter timeout
  dt-bindings: watchdog: da9062: add watchdog timeout mode
  dt-bindings: watchdog: renesas,wdt: Document RZ/G2UL SoC
  watchdog: iTCO_wdt: Using existing macro define covers more scenarios
  watchdog: rti-wdt: Fix pm_runtime_get_sync() error checking
  dt-bindings: watchdog: Add SC8180X and SC8280XP compatibles
  watchdog: rti_wdt: Fix calculation and evaluation of preset heartbeat
  dt-bindings: watchdog: uniphier: Use unevaluatedProperties
  watchdog: sp805: disable watchdog on remove
  watchdog: da9063: optionally disable watchdog during suspend
  dt-bindings: mfd: da9063: watchdog: add suspend disable option
  dt-bindings: watchdog: sunxi: clarify clock support
  dt-bindings: watchdog: sunxi: fix F1C100s compatible
  watchdog: Add watchdog driver for Sunplus SP7021
  ...
parents 17688215 5d24df3d
......@@ -64,10 +64,13 @@ Sub-nodes:
and KEY_SLEEP.
- watchdog : This node defines settings for the Watchdog timer associated
with the DA9063 and DA9063L. There are currently no entries in this
binding, however compatible = "dlg,da9063-watchdog" should be added
if a node is created.
with the DA9063 and DA9063L. The node should contain the compatible property
with the value "dlg,da9063-watchdog".
Optional watchdog properties:
- dlg,use-sw-pm: Add this property to disable the watchdog during suspend.
Only use this option if you can't use the watchdog automatic suspend
function during a suspend (see register CONTROL_B).
Example:
......
......@@ -10,6 +10,12 @@ Optional properties:
- dlg,use-sw-pm: Add this property to disable the watchdog during suspend.
Only use this option if you can't use the watchdog automatic suspend
function during a suspend (see register CONTROL_B).
- dlg,wdt-sd: Set what happens on watchdog timeout. If this bit is set the
watchdog timeout triggers SHUTDOWN, if cleared the watchdog triggers
POWERDOWN. Can be 0 or 1. Only use this option if you want to change the
default chip's OTP setting for WATCHDOG_SD bit. If this property is NOT
set the WATCHDOG_SD bit and on timeout watchdog behavior will match the
chip's OTP settings.
Example: DA9062
......
Faraday Technology FTWDT010 watchdog
This is an IP part from Faraday Technology found in the Gemini
SoCs and others.
Required properties:
- compatible : must be one of
"faraday,ftwdt010"
"cortina,gemini-watchdog", "faraday,ftwdt010"
- reg : shall contain base register location and length
- interrupts : shall contain the interrupt for the watchdog
Optional properties:
- timeout-sec : the default watchdog timeout in seconds.
Example:
watchdog@41000000 {
compatible = "faraday,ftwdt010";
reg = <0x41000000 0x1000>;
interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/watchdog/faraday,ftwdt010.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Faraday Technology FTWDT010 watchdog
maintainers:
- Linus Walleij <linus.walleij@linaro.org>
- Corentin Labbe <clabbe@baylibre.com>
description: |
This is an IP part from Faraday Technology found in the Gemini
SoCs and others.
allOf:
- $ref: "watchdog.yaml#"
properties:
compatible:
oneOf:
- const: faraday,ftwdt010
- items:
- enum:
- cortina,gemini-watchdog
- moxa,moxart-watchdog
- const: faraday,ftwdt010
reg:
maxItems: 1
resets:
maxItems: 1
clocks:
maxItems: 1
clock-names:
const: PCLK
interrupts:
maxItems: 1
required:
- compatible
- reg
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
watchdog@41000000 {
compatible = "faraday,ftwdt010";
reg = <0x41000000 0x1000>;
interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
timeout-secs = <5>;
};
- |
watchdog: watchdog@98500000 {
compatible = "moxa,moxart-watchdog", "faraday,ftwdt010";
reg = <0x98500000 0x10>;
clocks = <&clk_apb>;
clock-names = "PCLK";
};
...
......@@ -19,6 +19,7 @@ properties:
- items:
- const: fsl,imx8ulp-wdt
- const: fsl,imx7ulp-wdt
- const: fsl,imx93-wdt
reg:
maxItems: 1
......
......@@ -16,6 +16,7 @@ Required properties:
"mediatek,mt7629-wdt", "mediatek,mt6589-wdt": for MT7629
"mediatek,mt7986-wdt", "mediatek,mt6589-wdt": for MT7986
"mediatek,mt8183-wdt": for MT8183
"mediatek,mt8186-wdt", "mediatek,mt6589-wdt": for MT8186
"mediatek,mt8516-wdt", "mediatek,mt6589-wdt": for MT8516
"mediatek,mt8192-wdt": for MT8192
"mediatek,mt8195-wdt", "mediatek,mt6589-wdt": for MT8195
......
......@@ -14,17 +14,24 @@ allOf:
properties:
compatible:
enum:
oneOf:
- items:
- enum:
- qcom,apss-wdt-qcs404
- qcom,apss-wdt-sc7180
- qcom,apss-wdt-sc7280
- qcom,apss-wdt-sc8180x
- qcom,apss-wdt-sc8280xp
- qcom,apss-wdt-sdm845
- qcom,apss-wdt-sdx55
- qcom,apss-wdt-sm6350
- qcom,apss-wdt-sm8150
- qcom,apss-wdt-sm8250
- qcom,kpss-timer
- const: qcom,kpss-wdt
- items:
- enum:
- qcom,kpss-wdt
- qcom,kpss-timer
- qcom,kpss-wdt-apq8064
- qcom,kpss-wdt-ipq4019
- qcom,kpss-wdt-ipq8064
......
......@@ -21,8 +21,15 @@ properties:
- items:
- enum:
- renesas,r9a06g032-wdt # RZ/N1D
- const: renesas,rzn1-wdt # RZ/N1
- items:
- enum:
- renesas,r9a07g043-wdt # RZ/G2UL
- renesas,r9a07g044-wdt # RZ/G2{L,LC}
- const: renesas,rzg2l-wdt # RZ/G2L
- renesas,r9a07g054-wdt # RZ/V2L
- const: renesas,rzg2l-wdt
- items:
- enum:
......@@ -52,11 +59,11 @@ properties:
- renesas,r8a77980-wdt # R-Car V3H
- renesas,r8a77990-wdt # R-Car E3
- renesas,r8a77995-wdt # R-Car D3
- renesas,r8a779a0-wdt # R-Car V3U
- const: renesas,rcar-gen3-wdt # R-Car Gen3 and RZ/G2
- items:
- enum:
- renesas,r8a779a0-wdt # R-Car V3U
- renesas,r8a779f0-wdt # R-Car S4-8
- const: renesas,rcar-gen4-wdt # R-Car Gen4
......@@ -94,6 +101,7 @@ allOf:
contains:
enum:
- renesas,rza-wdt
- renesas,rzn1-wdt
then:
required:
- power-domains
......
......@@ -19,7 +19,7 @@ properties:
required:
- compatible
additionalProperties: false
unevaluatedProperties: false
examples:
- |
......
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
# Copyright (C) Sunplus Co., Ltd. 2021
%YAML 1.2
---
$id: http://devicetree.org/schemas/watchdog/sunplus,sp7021-wdt.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Sunplus SoCs Watchdog
maintainers:
- XianTao Hu <xt.hu@cqplus1.com>
allOf:
- $ref: watchdog.yaml#
properties:
compatible:
const: sunplus,sp7021-wdt
reg:
items:
- description: watchdog registers regions
- description: miscellaneous control registers regions
clocks:
maxItems: 1
resets:
maxItems: 1
required:
- compatible
- reg
- clocks
- resets
additionalProperties: false
examples:
- |
watchdog: watchdog@9c000630 {
compatible = "sunplus,sp7021-wdt";
reg = <0x9c000630 0x08>, <0x9c000274 0x04>;
clocks = <&clkc 0x24>;
resets = <&rstc 0x14>;
};
...
......@@ -19057,6 +19057,13 @@ S: Maintained
F: Documentation/devicetree/bindings/serial/sunplus,sp7021-uart.yaml
F: drivers/tty/serial/sunplus-uart.c
SUNPLUS WATCHDOG DRIVER
M: Xiantao Hu <xt.hu@cqplus1.com>
L: linux-watchdog@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/watchdog/sunplus,sp7021-wdt.yaml
F: drivers/watchdog/sunplus_wdt.c
SUPERH
M: Yoshinori Sato <ysato@users.sourceforge.jp>
M: Rich Felker <dalias@libc.org>
......
......@@ -883,6 +883,14 @@ config RENESAS_RZAWDT
This driver adds watchdog support for the integrated watchdogs in the
Renesas RZ/A SoCs. These watchdogs can be used to reset a system.
config RENESAS_RZN1WDT
tristate "Renesas RZ/N1 watchdog"
depends on ARCH_RENESAS || COMPILE_TEST
select WATCHDOG_CORE
help
This driver adds watchdog support for the integrated watchdogs in the
Renesas RZ/N1 SoCs. These watchdogs can be used to reset a system.
config RENESAS_RZG2LWDT
tristate "Renesas RZ/G2L WDT Watchdog"
depends on ARCH_RENESAS || COMPILE_TEST
......@@ -1011,6 +1019,17 @@ config APPLE_WATCHDOG
To compile this driver as a module, choose M here: the
module will be called apple_wdt.
config SUNPLUS_WATCHDOG
tristate "Sunplus watchdog support"
depends on ARCH_SUNPLUS || COMPILE_TEST
select WATCHDOG_CORE
help
Say Y here to include support for the watchdog timer
in Sunplus SoCs.
To compile this driver as a module, choose M here: the
module will be called sunplus_wdt.
# X86 (i386 + ia64 + x86_64) Architecture
config ACQUIRE_WDT
......
......@@ -84,6 +84,7 @@ obj-$(CONFIG_LPC18XX_WATCHDOG) += lpc18xx_wdt.o
obj-$(CONFIG_BCM7038_WDT) += bcm7038_wdt.o
obj-$(CONFIG_RENESAS_WDT) += renesas_wdt.o
obj-$(CONFIG_RENESAS_RZAWDT) += rza_wdt.o
obj-$(CONFIG_RENESAS_RZN1WDT) += rzn1_wdt.o
obj-$(CONFIG_RENESAS_RZG2LWDT) += rzg2l_wdt.o
obj-$(CONFIG_ASPEED_WATCHDOG) += aspeed_wdt.o
obj-$(CONFIG_STM32_WATCHDOG) += stm32_iwdg.o
......@@ -95,6 +96,7 @@ obj-$(CONFIG_ARM_SMC_WATCHDOG) += arm_smc_wdt.o
obj-$(CONFIG_VISCONTI_WATCHDOG) += visconti_wdt.o
obj-$(CONFIG_MSC313E_WATCHDOG) += msc313e_wdt.o
obj-$(CONFIG_APPLE_WATCHDOG) += apple_wdt.o
obj-$(CONFIG_SUNPLUS_WATCHDOG) += sunplus_wdt.o
# X86 (i386 + ia64 + x86_64) Architecture
obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
......
......@@ -218,6 +218,7 @@ static SIMPLE_DEV_PM_OPS(bcm7038_wdt_pm_ops, bcm7038_wdt_suspend,
bcm7038_wdt_resume);
static const struct of_device_id bcm7038_wdt_match[] = {
{ .compatible = "brcm,bcm6345-wdt" },
{ .compatible = "brcm,bcm7038-wdt" },
{},
};
......
......@@ -18,6 +18,7 @@
#include <linux/delay.h>
#include <linux/mfd/da9063/registers.h>
#include <linux/mfd/da9063/core.h>
#include <linux/property.h>
#include <linux/regmap.h>
/*
......@@ -26,6 +27,8 @@
* others: timeout = 2048 ms * 2^(TWDSCALE-1).
*/
static const unsigned int wdt_timeout[] = { 0, 2, 4, 8, 16, 32, 65, 131 };
static bool use_sw_pm;
#define DA9063_TWDSCALE_DISABLE 0
#define DA9063_TWDSCALE_MIN 1
#define DA9063_TWDSCALE_MAX (ARRAY_SIZE(wdt_timeout) - 1)
......@@ -218,6 +221,8 @@ static int da9063_wdt_probe(struct platform_device *pdev)
if (!wdd)
return -ENOMEM;
use_sw_pm = device_property_present(dev, "dlg,use-sw-pm");
wdd->info = &da9063_watchdog_info;
wdd->ops = &da9063_watchdog_ops;
wdd->min_timeout = DA9063_WDT_MIN_TIMEOUT;
......@@ -228,6 +233,7 @@ static int da9063_wdt_probe(struct platform_device *pdev)
watchdog_set_restart_priority(wdd, 128);
watchdog_set_drvdata(wdd, da9063);
dev_set_drvdata(dev, wdd);
wdd->timeout = DA9063_WDG_TIMEOUT;
......@@ -249,10 +255,40 @@ static int da9063_wdt_probe(struct platform_device *pdev)
return devm_watchdog_register_device(dev, wdd);
}
static int __maybe_unused da9063_wdt_suspend(struct device *dev)
{
struct watchdog_device *wdd = dev_get_drvdata(dev);
if (!use_sw_pm)
return 0;
if (watchdog_active(wdd))
return da9063_wdt_stop(wdd);
return 0;
}
static int __maybe_unused da9063_wdt_resume(struct device *dev)
{
struct watchdog_device *wdd = dev_get_drvdata(dev);
if (!use_sw_pm)
return 0;
if (watchdog_active(wdd))
return da9063_wdt_start(wdd);
return 0;
}
static SIMPLE_DEV_PM_OPS(da9063_wdt_pm_ops,
da9063_wdt_suspend, da9063_wdt_resume);
static struct platform_driver da9063_wdt_driver = {
.probe = da9063_wdt_probe,
.driver = {
.name = DA9063_DRVNAME_WATCHDOG,
.pm = &da9063_wdt_pm_ops,
},
};
module_platform_driver(da9063_wdt_driver);
......
......@@ -596,7 +596,6 @@ static int iTCO_wdt_probe(struct platform_device *pdev)
return 0;
}
#ifdef CONFIG_PM_SLEEP
/*
* Suspend-to-idle requires this, because it stops the ticks and timekeeping, so
* the watchdog cannot be pinged while in that state. In ACPI sleep states the
......@@ -604,15 +603,15 @@ static int iTCO_wdt_probe(struct platform_device *pdev)
*/
#ifdef CONFIG_ACPI
static inline bool need_suspend(void)
static inline bool __maybe_unused need_suspend(void)
{
return acpi_target_system_state() == ACPI_STATE_S0;
}
#else
static inline bool need_suspend(void) { return true; }
static inline bool __maybe_unused need_suspend(void) { return true; }
#endif
static int iTCO_wdt_suspend_noirq(struct device *dev)
static int __maybe_unused iTCO_wdt_suspend_noirq(struct device *dev)
{
struct iTCO_wdt_private *p = dev_get_drvdata(dev);
int ret = 0;
......@@ -626,7 +625,7 @@ static int iTCO_wdt_suspend_noirq(struct device *dev)
return ret;
}
static int iTCO_wdt_resume_noirq(struct device *dev)
static int __maybe_unused iTCO_wdt_resume_noirq(struct device *dev)
{
struct iTCO_wdt_private *p = dev_get_drvdata(dev);
......@@ -637,20 +636,15 @@ static int iTCO_wdt_resume_noirq(struct device *dev)
}
static const struct dev_pm_ops iTCO_wdt_pm = {
.suspend_noirq = iTCO_wdt_suspend_noirq,
.resume_noirq = iTCO_wdt_resume_noirq,
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(iTCO_wdt_suspend_noirq,
iTCO_wdt_resume_noirq)
};
#define ITCO_WDT_PM_OPS (&iTCO_wdt_pm)
#else
#define ITCO_WDT_PM_OPS NULL
#endif /* CONFIG_PM_SLEEP */
static struct platform_driver iTCO_wdt_driver = {
.probe = iTCO_wdt_probe,
.driver = {
.name = DRV_NAME,
.pm = ITCO_WDT_PM_OPS,
.pm = &iTCO_wdt_pm,
},
};
......
......@@ -10,7 +10,9 @@
*/
#include <dt-bindings/reset/mt2712-resets.h>
#include <dt-bindings/reset/mt7986-resets.h>
#include <dt-bindings/reset/mt8183-resets.h>
#include <dt-bindings/reset/mt8186-resets.h>
#include <dt-bindings/reset/mt8192-resets.h>
#include <dt-bindings/reset/mt8195-resets.h>
#include <linux/delay.h>
......@@ -76,10 +78,18 @@ static const struct mtk_wdt_data mt2712_data = {
.toprgu_sw_rst_num = MT2712_TOPRGU_SW_RST_NUM,
};
static const struct mtk_wdt_data mt7986_data = {
.toprgu_sw_rst_num = MT7986_TOPRGU_SW_RST_NUM,
};
static const struct mtk_wdt_data mt8183_data = {
.toprgu_sw_rst_num = MT8183_TOPRGU_SW_RST_NUM,
};
static const struct mtk_wdt_data mt8186_data = {
.toprgu_sw_rst_num = MT8186_TOPRGU_SW_RST_NUM,
};
static const struct mtk_wdt_data mt8192_data = {
.toprgu_sw_rst_num = MT8192_TOPRGU_SW_RST_NUM,
};
......@@ -418,7 +428,9 @@ static int mtk_wdt_resume(struct device *dev)
static const struct of_device_id mtk_wdt_dt_ids[] = {
{ .compatible = "mediatek,mt2712-wdt", .data = &mt2712_data },
{ .compatible = "mediatek,mt6589-wdt" },
{ .compatible = "mediatek,mt7986-wdt", .data = &mt7986_data },
{ .compatible = "mediatek,mt8183-wdt", .data = &mt8183_data },
{ .compatible = "mediatek,mt8186-wdt", .data = &mt8186_data },
{ .compatible = "mediatek,mt8192-wdt", .data = &mt8192_data },
{ .compatible = "mediatek,mt8195-wdt", .data = &mt8195_data },
{ /* sentinel */ }
......
......@@ -226,7 +226,7 @@ static int rti_wdt_probe(struct platform_device *pdev)
pm_runtime_enable(dev);
ret = pm_runtime_get_sync(dev);
if (ret) {
if (ret < 0) {
pm_runtime_put_noidle(dev);
pm_runtime_disable(&pdev->dev);
return dev_err_probe(dev, ret, "runtime pm failed\n");
......@@ -253,6 +253,7 @@ static int rti_wdt_probe(struct platform_device *pdev)
}
if (readl(wdt->base + RTIDWDCTRL) == WDENABLE_KEY) {
int preset_heartbeat;
u32 time_left_ms;
u64 heartbeat_ms;
u32 wsize;
......@@ -263,11 +264,12 @@ static int rti_wdt_probe(struct platform_device *pdev)
heartbeat_ms <<= WDT_PRELOAD_SHIFT;
heartbeat_ms *= 1000;
do_div(heartbeat_ms, wdt->freq);
if (heartbeat_ms != heartbeat * 1000)
preset_heartbeat = heartbeat_ms + 500;
preset_heartbeat /= 1000;
if (preset_heartbeat != heartbeat)
dev_warn(dev, "watchdog already running, ignoring heartbeat config!\n");
heartbeat = heartbeat_ms;
heartbeat /= 1000;
heartbeat = preset_heartbeat;
wsize = readl(wdt->base + RTIWWDSIZECTRL);
ret = rti_wdt_setup_hw_hb(wdd, wsize);
......
......@@ -21,8 +21,11 @@
#define WDTSET 0x04
#define WDTTIM 0x08
#define WDTINT 0x0C
#define PECR 0x10
#define PEEN 0x14
#define WDTCNT_WDTEN BIT(0)
#define WDTINT_INTDISP BIT(0)
#define PEEN_FORCE BIT(0)
#define WDT_DEFAULT_TIMEOUT 60U
......@@ -43,6 +46,8 @@ struct rzg2l_wdt_priv {
struct reset_control *rstc;
unsigned long osc_clk_rate;
unsigned long delay;
struct clk *pclk;
struct clk *osc_clk;
};
static void rzg2l_wdt_wait_delay(struct rzg2l_wdt_priv *priv)
......@@ -53,7 +58,7 @@ static void rzg2l_wdt_wait_delay(struct rzg2l_wdt_priv *priv)
static u32 rzg2l_wdt_get_cycle_usec(unsigned long cycle, u32 wdttime)
{
u64 timer_cycle_us = 1024 * 1024 * (wdttime + 1) * MICRO;
u64 timer_cycle_us = 1024 * 1024ULL * (wdttime + 1) * MICRO;
return div64_ul(timer_cycle_us, cycle);
}
......@@ -86,7 +91,6 @@ static int rzg2l_wdt_start(struct watchdog_device *wdev)
{
struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
reset_control_deassert(priv->rstc);
pm_runtime_get_sync(wdev->parent);
/* Initialize time out */
......@@ -106,7 +110,26 @@ static int rzg2l_wdt_stop(struct watchdog_device *wdev)
struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
pm_runtime_put(wdev->parent);
reset_control_assert(priv->rstc);
reset_control_reset(priv->rstc);
return 0;
}
static int rzg2l_wdt_set_timeout(struct watchdog_device *wdev, unsigned int timeout)
{
struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
wdev->timeout = timeout;
/*
* If the watchdog is active, reset the module for updating the WDTSET
* register so that it is updated with new timeout values.
*/
if (watchdog_active(wdev)) {
pm_runtime_put(wdev->parent);
reset_control_reset(priv->rstc);
rzg2l_wdt_start(wdev);
}
return 0;
}
......@@ -116,15 +139,14 @@ static int rzg2l_wdt_restart(struct watchdog_device *wdev,
{
struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
/* Reset the module before we modify any register */
reset_control_reset(priv->rstc);
pm_runtime_get_sync(wdev->parent);
clk_prepare_enable(priv->pclk);
clk_prepare_enable(priv->osc_clk);
/* smallest counter value to reboot soon */
rzg2l_wdt_write(priv, WDTSET_COUNTER_VAL(1), WDTSET);
/* Generate Reset (WDTRSTB) Signal on parity error */
rzg2l_wdt_write(priv, 0, PECR);
/* Enable watchdog timer*/
rzg2l_wdt_write(priv, WDTCNT_WDTEN, WDTCNT);
/* Force parity error */
rzg2l_wdt_write(priv, PEEN_FORCE, PEEN);
return 0;
}
......@@ -148,15 +170,15 @@ static const struct watchdog_ops rzg2l_wdt_ops = {
.start = rzg2l_wdt_start,
.stop = rzg2l_wdt_stop,
.ping = rzg2l_wdt_ping,
.set_timeout = rzg2l_wdt_set_timeout,
.restart = rzg2l_wdt_restart,
};
static void rzg2l_wdt_reset_assert_pm_disable_put(void *data)
static void rzg2l_wdt_reset_assert_pm_disable(void *data)
{
struct watchdog_device *wdev = data;
struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
pm_runtime_put(wdev->parent);
pm_runtime_disable(wdev->parent);
reset_control_assert(priv->rstc);
}
......@@ -166,7 +188,6 @@ static int rzg2l_wdt_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct rzg2l_wdt_priv *priv;
unsigned long pclk_rate;
struct clk *wdt_clk;
int ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
......@@ -178,22 +199,20 @@ static int rzg2l_wdt_probe(struct platform_device *pdev)
return PTR_ERR(priv->base);
/* Get watchdog main clock */
wdt_clk = clk_get(&pdev->dev, "oscclk");
if (IS_ERR(wdt_clk))
return dev_err_probe(&pdev->dev, PTR_ERR(wdt_clk), "no oscclk");
priv->osc_clk = devm_clk_get(&pdev->dev, "oscclk");
if (IS_ERR(priv->osc_clk))
return dev_err_probe(&pdev->dev, PTR_ERR(priv->osc_clk), "no oscclk");
priv->osc_clk_rate = clk_get_rate(wdt_clk);
clk_put(wdt_clk);
priv->osc_clk_rate = clk_get_rate(priv->osc_clk);
if (!priv->osc_clk_rate)
return dev_err_probe(&pdev->dev, -EINVAL, "oscclk rate is 0");
/* Get Peripheral clock */
wdt_clk = clk_get(&pdev->dev, "pclk");
if (IS_ERR(wdt_clk))
return dev_err_probe(&pdev->dev, PTR_ERR(wdt_clk), "no pclk");
priv->pclk = devm_clk_get(&pdev->dev, "pclk");
if (IS_ERR(priv->pclk))
return dev_err_probe(&pdev->dev, PTR_ERR(priv->pclk), "no pclk");
pclk_rate = clk_get_rate(wdt_clk);
clk_put(wdt_clk);
pclk_rate = clk_get_rate(priv->pclk);
if (!pclk_rate)
return dev_err_probe(&pdev->dev, -EINVAL, "pclk rate is 0");
......@@ -204,13 +223,11 @@ static int rzg2l_wdt_probe(struct platform_device *pdev)
return dev_err_probe(&pdev->dev, PTR_ERR(priv->rstc),
"failed to get cpg reset");
reset_control_deassert(priv->rstc);
ret = reset_control_deassert(priv->rstc);
if (ret)
return dev_err_probe(dev, ret, "failed to deassert");
pm_runtime_enable(&pdev->dev);
ret = pm_runtime_resume_and_get(&pdev->dev);
if (ret < 0) {
dev_err(dev, "pm_runtime_resume_and_get failed ret=%pe", ERR_PTR(ret));
goto out_pm_get;
}
priv->wdev.info = &rzg2l_wdt_ident;
priv->wdev.ops = &rzg2l_wdt_ops;
......@@ -222,7 +239,7 @@ static int rzg2l_wdt_probe(struct platform_device *pdev)
watchdog_set_drvdata(&priv->wdev, priv);
ret = devm_add_action_or_reset(&pdev->dev,
rzg2l_wdt_reset_assert_pm_disable_put,
rzg2l_wdt_reset_assert_pm_disable,
&priv->wdev);
if (ret < 0)
return ret;
......@@ -235,12 +252,6 @@ static int rzg2l_wdt_probe(struct platform_device *pdev)
dev_warn(dev, "Specified timeout invalid, using default");
return devm_watchdog_register_device(&pdev->dev, &priv->wdev);
out_pm_get:
pm_runtime_disable(dev);
reset_control_assert(priv->rstc);
return ret;
}
static const struct of_device_id rzg2l_wdt_ids[] = {
......
// SPDX-License-Identifier: GPL-2.0
/*
* Renesas RZ/N1 Watchdog timer.
* This is a 12-bit timer driver from a (62.5/16384) MHz clock. It can't even
* cope with 2 seconds.
*
* Copyright 2018 Renesas Electronics Europe Ltd.
*
* Derived from Ralink RT288x watchdog timer.
*/
#include <linux/clk.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/reboot.h>
#include <linux/watchdog.h>
#define DEFAULT_TIMEOUT 60
#define RZN1_WDT_RETRIGGER 0x0
#define RZN1_WDT_RETRIGGER_RELOAD_VAL 0
#define RZN1_WDT_RETRIGGER_RELOAD_VAL_MASK 0xfff
#define RZN1_WDT_RETRIGGER_PRESCALE BIT(12)
#define RZN1_WDT_RETRIGGER_ENABLE BIT(13)
#define RZN1_WDT_RETRIGGER_WDSI (0x2 << 14)
#define RZN1_WDT_PRESCALER 16384
#define RZN1_WDT_MAX 4095
struct rzn1_watchdog {
struct watchdog_device wdtdev;
void __iomem *base;
unsigned long clk_rate_khz;
};
static inline uint32_t max_heart_beat_ms(unsigned long clk_rate_khz)
{
return (RZN1_WDT_MAX * RZN1_WDT_PRESCALER) / clk_rate_khz;
}
static inline uint32_t compute_reload_value(uint32_t tick_ms,
unsigned long clk_rate_khz)
{
return (tick_ms * clk_rate_khz) / RZN1_WDT_PRESCALER;
}
static int rzn1_wdt_ping(struct watchdog_device *w)
{
struct rzn1_watchdog *wdt = watchdog_get_drvdata(w);
/* Any value retrigggers the watchdog */
writel(0, wdt->base + RZN1_WDT_RETRIGGER);
return 0;
}
static int rzn1_wdt_start(struct watchdog_device *w)
{
struct rzn1_watchdog *wdt = watchdog_get_drvdata(w);
u32 val;
/*
* The hardware allows you to write to this reg only once.
* Since this includes the reload value, there is no way to change the
* timeout once started. Also note that the WDT clock is half the bus
* fabric clock rate, so if the bus fabric clock rate is changed after
* the WDT is started, the WDT interval will be wrong.
*/
val = RZN1_WDT_RETRIGGER_WDSI;
val |= RZN1_WDT_RETRIGGER_ENABLE;
val |= RZN1_WDT_RETRIGGER_PRESCALE;
val |= compute_reload_value(w->max_hw_heartbeat_ms, wdt->clk_rate_khz);
writel(val, wdt->base + RZN1_WDT_RETRIGGER);
return 0;
}
static irqreturn_t rzn1_wdt_irq(int irq, void *_wdt)
{
pr_crit("RZN1 Watchdog. Initiating system reboot\n");
emergency_restart();
return IRQ_HANDLED;
}
static struct watchdog_info rzn1_wdt_info = {
.identity = "RZ/N1 Watchdog",
.options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
};
static const struct watchdog_ops rzn1_wdt_ops = {
.owner = THIS_MODULE,
.start = rzn1_wdt_start,
.ping = rzn1_wdt_ping,
};
static void rzn1_wdt_clk_disable_unprepare(void *data)
{
clk_disable_unprepare(data);
}
static int rzn1_wdt_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct rzn1_watchdog *wdt;
struct device_node *np = dev->of_node;
struct clk *clk;
unsigned long clk_rate;
int ret;
int irq;
wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt)
return -ENOMEM;
wdt->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(wdt->base))
return PTR_ERR(wdt->base);
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
ret = devm_request_irq(dev, irq, rzn1_wdt_irq, 0,
np->name, wdt);
if (ret) {
dev_err(dev, "failed to request irq %d\n", irq);
return ret;
}
clk = devm_clk_get(dev, NULL);
if (IS_ERR(clk)) {
dev_err(dev, "failed to get the clock\n");
return PTR_ERR(clk);
}
ret = clk_prepare_enable(clk);
if (ret) {
dev_err(dev, "failed to prepare/enable the clock\n");
return ret;
}
ret = devm_add_action_or_reset(dev, rzn1_wdt_clk_disable_unprepare,
clk);
if (ret)
return ret;
clk_rate = clk_get_rate(clk);
if (!clk_rate) {
dev_err(dev, "failed to get the clock rate\n");
return -EINVAL;
}
wdt->clk_rate_khz = clk_rate / 1000;
wdt->wdtdev.info = &rzn1_wdt_info,
wdt->wdtdev.ops = &rzn1_wdt_ops,
wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS,
wdt->wdtdev.parent = dev;
/*
* The period of the watchdog cannot be changed once set
* and is limited to a very short period.
* Configure it for a 1s period once and for all, and
* rely on the heart-beat provided by the watchdog core
* to make this usable by the user-space.
*/
wdt->wdtdev.max_hw_heartbeat_ms = max_heart_beat_ms(wdt->clk_rate_khz);
if (wdt->wdtdev.max_hw_heartbeat_ms > 1000)
wdt->wdtdev.max_hw_heartbeat_ms = 1000;
wdt->wdtdev.timeout = DEFAULT_TIMEOUT;
ret = watchdog_init_timeout(&wdt->wdtdev, 0, dev);
if (ret)
return ret;
watchdog_set_drvdata(&wdt->wdtdev, wdt);
return devm_watchdog_register_device(dev, &wdt->wdtdev);
}
static const struct of_device_id rzn1_wdt_match[] = {
{ .compatible = "renesas,rzn1-wdt" },
{},
};
MODULE_DEVICE_TABLE(of, rzn1_wdt_match);
static struct platform_driver rzn1_wdt_driver = {
.probe = rzn1_wdt_probe,
.driver = {
.name = KBUILD_MODNAME,
.of_match_table = rzn1_wdt_match,
},
};
module_platform_driver(rzn1_wdt_driver);
MODULE_DESCRIPTION("Renesas RZ/N1 hardware watchdog");
MODULE_AUTHOR("Phil Edworthy <phil.edworthy@renesas.com>");
MODULE_LICENSE("GPL");
......@@ -272,6 +272,7 @@ sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id)
watchdog_set_nowayout(&wdt->wdd, nowayout);
watchdog_set_drvdata(&wdt->wdd, wdt);
watchdog_set_restart_priority(&wdt->wdd, 128);
watchdog_stop_on_unregister(&wdt->wdd);
/*
* If 'timeout-sec' devicetree property is specified, use that.
......
// SPDX-License-Identifier: GPL-2.0-only
/*
* sunplus Watchdog Driver
*
* Copyright (C) 2021 Sunplus Technology Co., Ltd.
*
*/
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
#include <linux/watchdog.h>
#define WDT_CTRL 0x00
#define WDT_CNT 0x04
#define WDT_STOP 0x3877
#define WDT_RESUME 0x4A4B
#define WDT_CLRIRQ 0x7482
#define WDT_UNLOCK 0xAB00
#define WDT_LOCK 0xAB01
#define WDT_CONMAX 0xDEAF
/* TIMEOUT_MAX = ffff0/90kHz =11.65, so longer than 11 seconds will time out. */
#define SP_WDT_MAX_TIMEOUT 11U
#define SP_WDT_DEFAULT_TIMEOUT 10
#define STC_CLK 90000
#define DEVICE_NAME "sunplus-wdt"
static unsigned int timeout;
module_param(timeout, int, 0);
MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds");
static bool nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, bool, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
struct sp_wdt_priv {
struct watchdog_device wdev;
void __iomem *base;
struct clk *clk;
struct reset_control *rstc;
};
static int sp_wdt_restart(struct watchdog_device *wdev,
unsigned long action, void *data)
{
struct sp_wdt_priv *priv = watchdog_get_drvdata(wdev);
void __iomem *base = priv->base;
writel(WDT_STOP, base + WDT_CTRL);
writel(WDT_UNLOCK, base + WDT_CTRL);
writel(0x0001, base + WDT_CNT);
writel(WDT_LOCK, base + WDT_CTRL);
writel(WDT_RESUME, base + WDT_CTRL);
return 0;
}
static int sp_wdt_ping(struct watchdog_device *wdev)
{
struct sp_wdt_priv *priv = watchdog_get_drvdata(wdev);
void __iomem *base = priv->base;
u32 count;
if (wdev->timeout > SP_WDT_MAX_TIMEOUT) {
/* WDT_CONMAX sets the count to the maximum (down-counting). */
writel(WDT_CONMAX, base + WDT_CTRL);
} else {
writel(WDT_UNLOCK, base + WDT_CTRL);
/*
* Watchdog timer is a 20-bit down-counting based on STC_CLK.
* This register bits[16:0] is from bit[19:4] of the watchdog
* timer counter.
*/
count = (wdev->timeout * STC_CLK) >> 4;
writel(count, base + WDT_CNT);
writel(WDT_LOCK, base + WDT_CTRL);
}
return 0;
}
static int sp_wdt_stop(struct watchdog_device *wdev)
{
struct sp_wdt_priv *priv = watchdog_get_drvdata(wdev);
void __iomem *base = priv->base;
writel(WDT_STOP, base + WDT_CTRL);
return 0;
}
static int sp_wdt_start(struct watchdog_device *wdev)
{
struct sp_wdt_priv *priv = watchdog_get_drvdata(wdev);
void __iomem *base = priv->base;
writel(WDT_RESUME, base + WDT_CTRL);
return 0;
}
static unsigned int sp_wdt_get_timeleft(struct watchdog_device *wdev)
{
struct sp_wdt_priv *priv = watchdog_get_drvdata(wdev);
void __iomem *base = priv->base;
u32 val;
val = readl(base + WDT_CNT);
val &= 0xffff;
val = val << 4;
return val;
}
static const struct watchdog_info sp_wdt_info = {
.identity = DEVICE_NAME,
.options = WDIOF_SETTIMEOUT |
WDIOF_MAGICCLOSE |
WDIOF_KEEPALIVEPING,
};
static const struct watchdog_ops sp_wdt_ops = {
.owner = THIS_MODULE,
.start = sp_wdt_start,
.stop = sp_wdt_stop,
.ping = sp_wdt_ping,
.get_timeleft = sp_wdt_get_timeleft,
.restart = sp_wdt_restart,
};
static void sp_clk_disable_unprepare(void *data)
{
clk_disable_unprepare(data);
}
static void sp_reset_control_assert(void *data)
{
reset_control_assert(data);
}
static int sp_wdt_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct sp_wdt_priv *priv;
int ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->clk = devm_clk_get(dev, NULL);
if (IS_ERR(priv->clk))
return dev_err_probe(dev, PTR_ERR(priv->clk), "Failed to get clock\n");
ret = clk_prepare_enable(priv->clk);
if (ret)
return dev_err_probe(dev, ret, "Failed to enable clock\n");
ret = devm_add_action_or_reset(dev, sp_clk_disable_unprepare, priv->clk);
if (ret)
return ret;
/* The timer and watchdog shared the STC reset */
priv->rstc = devm_reset_control_get_shared(dev, NULL);
if (IS_ERR(priv->rstc))
return dev_err_probe(dev, PTR_ERR(priv->rstc), "Failed to get reset\n");
reset_control_deassert(priv->rstc);
ret = devm_add_action_or_reset(dev, sp_reset_control_assert, priv->rstc);
if (ret)
return ret;
priv->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->base))
return PTR_ERR(priv->base);
priv->wdev.info = &sp_wdt_info;
priv->wdev.ops = &sp_wdt_ops;
priv->wdev.timeout = SP_WDT_DEFAULT_TIMEOUT;
priv->wdev.max_hw_heartbeat_ms = SP_WDT_MAX_TIMEOUT * 1000;
priv->wdev.min_timeout = 1;
priv->wdev.parent = dev;
watchdog_set_drvdata(&priv->wdev, priv);
watchdog_init_timeout(&priv->wdev, timeout, dev);
watchdog_set_nowayout(&priv->wdev, nowayout);
watchdog_stop_on_reboot(&priv->wdev);
watchdog_set_restart_priority(&priv->wdev, 128);
return devm_watchdog_register_device(dev, &priv->wdev);
}
static const struct of_device_id sp_wdt_of_match[] = {
{.compatible = "sunplus,sp7021-wdt", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, sp_wdt_of_match);
static struct platform_driver sp_wdt_driver = {
.probe = sp_wdt_probe,
.driver = {
.name = DEVICE_NAME,
.of_match_table = sp_wdt_of_match,
},
};
module_platform_driver(sp_wdt_driver);
MODULE_AUTHOR("Xiantao Hu <xt.hu@cqplus1.com>");
MODULE_DESCRIPTION("Sunplus Watchdog Timer Driver");
MODULE_LICENSE("GPL");
......@@ -125,13 +125,16 @@ static int ts4800_wdt_probe(struct platform_device *pdev)
ret = of_property_read_u32_index(np, "syscon", 1, &reg);
if (ret < 0) {
dev_err(dev, "no offset in syscon\n");
of_node_put(syscon_np);
return ret;
}
/* allocate memory for watchdog struct */
wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt)
if (!wdt) {
of_node_put(syscon_np);
return -ENOMEM;
}
/* set regmap and offset to know where to write */
wdt->feed_offset = reg;
......
......@@ -344,6 +344,7 @@ static int wdat_wdt_probe(struct platform_device *pdev)
wdat->period = tbl->timer_period;
wdat->wdd.min_hw_heartbeat_ms = wdat->period * tbl->min_count;
wdat->wdd.max_hw_heartbeat_ms = wdat->period * tbl->max_count;
wdat->wdd.min_timeout = 1;
wdat->stopped_in_sleep = tbl->flags & ACPI_WDAT_STOPPED;
wdat->wdd.info = &wdat_wdt_info;
wdat->wdd.ops = &wdat_wdt_ops;
......@@ -450,8 +451,7 @@ static int wdat_wdt_probe(struct platform_device *pdev)
* watchdog properly after it has opened the device. In some cases
* the BIOS default is too short and causes immediate reboot.
*/
if (timeout * 1000 < wdat->wdd.min_hw_heartbeat_ms ||
timeout * 1000 > wdat->wdd.max_hw_heartbeat_ms) {
if (watchdog_timeout_invalid(&wdat->wdd, timeout)) {
dev_warn(dev, "Invalid timeout %d given, using %d\n",
timeout, WDAT_DEFAULT_TIMEOUT);
timeout = WDAT_DEFAULT_TIMEOUT;
......@@ -462,6 +462,8 @@ static int wdat_wdt_probe(struct platform_device *pdev)
return ret;
watchdog_set_nowayout(&wdat->wdd, nowayout);
watchdog_stop_on_reboot(&wdat->wdd);
watchdog_stop_on_unregister(&wdat->wdd);
return devm_watchdog_register_device(dev, &wdat->wdd);
}
......
/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
/*
* Copyright (c) 2022 MediaTek Inc.
* Author: Sam Shih <sam.shih@mediatek.com>
*/
#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT7986
#define _DT_BINDINGS_RESET_CONTROLLER_MT7986
/* INFRACFG resets */
#define MT7986_INFRACFG_PEXTP_MAC_SW_RST 6
#define MT7986_INFRACFG_SSUSB_SW_RST 7
#define MT7986_INFRACFG_EIP97_SW_RST 8
#define MT7986_INFRACFG_AUDIO_SW_RST 13
#define MT7986_INFRACFG_CQ_DMA_SW_RST 14
#define MT7986_INFRACFG_TRNG_SW_RST 17
#define MT7986_INFRACFG_AP_DMA_SW_RST 32
#define MT7986_INFRACFG_I2C_SW_RST 33
#define MT7986_INFRACFG_NFI_SW_RST 34
#define MT7986_INFRACFG_SPI0_SW_RST 35
#define MT7986_INFRACFG_SPI1_SW_RST 36
#define MT7986_INFRACFG_UART0_SW_RST 37
#define MT7986_INFRACFG_UART1_SW_RST 38
#define MT7986_INFRACFG_UART2_SW_RST 39
#define MT7986_INFRACFG_AUXADC_SW_RST 43
#define MT7986_INFRACFG_APXGPT_SW_RST 66
#define MT7986_INFRACFG_PWM_SW_RST 68
#define MT7986_INFRACFG_SW_RST_NUM 69
/* TOPRGU resets */
#define MT7986_TOPRGU_APMIXEDSYS_SW_RST 0
#define MT7986_TOPRGU_SGMII0_SW_RST 1
#define MT7986_TOPRGU_SGMII1_SW_RST 2
#define MT7986_TOPRGU_INFRA_SW_RST 3
#define MT7986_TOPRGU_U2PHY_SW_RST 5
#define MT7986_TOPRGU_PCIE_SW_RST 6
#define MT7986_TOPRGU_SSUSB_SW_RST 7
#define MT7986_TOPRGU_ETHDMA_SW_RST 20
#define MT7986_TOPRGU_CONSYS_SW_RST 23
#define MT7986_TOPRGU_SW_RST_NUM 24
/* ETHSYS Subsystem resets */
#define MT7986_ETHSYS_FE_SW_RST 6
#define MT7986_ETHSYS_PMTR_SW_RST 8
#define MT7986_ETHSYS_GMAC_SW_RST 23
#define MT7986_ETHSYS_PPE0_SW_RST 30
#define MT7986_ETHSYS_PPE1_SW_RST 31
#define MT7986_ETHSYS_SW_RST_NUM 32
#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT7986 */
/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
/*
* Copyright (c) 2022 MediaTek Inc.
* Author: Runyang Chen <runyang.chen@mediatek.com>
*/
#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT8186
#define _DT_BINDINGS_RESET_CONTROLLER_MT8186
#define MT8186_TOPRGU_INFRA_SW_RST 0
#define MT8186_TOPRGU_MM_SW_RST 1
#define MT8186_TOPRGU_MFG_SW_RST 2
#define MT8186_TOPRGU_VENC_SW_RST 3
#define MT8186_TOPRGU_VDEC_SW_RST 4
#define MT8186_TOPRGU_IMG_SW_RST 5
#define MT8186_TOPRGU_DDR_SW_RST 6
#define MT8186_TOPRGU_INFRA_AO_SW_RST 8
#define MT8186_TOPRGU_CONNSYS_SW_RST 9
#define MT8186_TOPRGU_APMIXED_SW_RST 10
#define MT8186_TOPRGU_PWRAP_SW_RST 11
#define MT8186_TOPRGU_CONN_MCU_SW_RST 12
#define MT8186_TOPRGU_IPNNA_SW_RST 13
#define MT8186_TOPRGU_WPE_SW_RST 14
#define MT8186_TOPRGU_ADSP_SW_RST 15
#define MT8186_TOPRGU_AUDIO_SW_RST 17
#define MT8186_TOPRGU_CAM_MAIN_SW_RST 18
#define MT8186_TOPRGU_CAM_RAWA_SW_RST 19
#define MT8186_TOPRGU_CAM_RAWB_SW_RST 20
#define MT8186_TOPRGU_IPE_SW_RST 21
#define MT8186_TOPRGU_IMG2_SW_RST 22
#define MT8186_TOPRGU_SW_RST_NUM 23
/* MMSYS resets */
#define MT8186_MMSYS_SW0_RST_B_DISP_DSI0 19
#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT8186 */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment