linux-watchdog 6.11-rc1 tag
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.14 (GNU/Linux) iEYEABECAAYFAmaglhIACgkQ+iyteGJfRspBfQCgnL07s+8mWMcfjYhc92La4573 Z8QAniBh5nvymZRNKpslMR4UEuCCI3gt =IrbV -----END PGP SIGNATURE----- Merge tag 'linux-watchdog-6.11-rc1' of git://www.linux-watchdog.org/linux-watchdog Pull watchdog updates from Wim Van Sebroeck: - make watchdog_class const - rework of the rzg2l_wdt driver - other small fixes and improvements * tag 'linux-watchdog-6.11-rc1' of git://www.linux-watchdog.org/linux-watchdog: dt-bindings: watchdog: dlg,da9062-watchdog: Drop blank space watchdog: rzn1: Convert comma to semicolon watchdog: lenovo_se10_wdt: Convert comma to semicolon dt-bindings: watchdog: renesas,wdt: Document RZ/G3S support watchdog: rzg2l_wdt: Add suspend/resume support watchdog: rzg2l_wdt: Rely on the reset driver for doing proper reset watchdog: rzg2l_wdt: Remove comparison with zero watchdog: rzg2l_wdt: Remove reset de-assert from probe watchdog: rzg2l_wdt: Check return status of pm_runtime_put() watchdog: rzg2l_wdt: Use pm_runtime_resume_and_get() watchdog: rzg2l_wdt: Make the driver depend on PM watchdog: rzg2l_wdt: Restrict the driver to ARCH_RZG2L and ARCH_R9A09G011 watchdog: imx7ulp_wdt: keep already running watchdog enabled watchdog: starfive: Add missing clk_disable_unprepare() watchdog: Make watchdog_class const
This commit is contained in:
commit
b2eed73360
@ -28,7 +28,7 @@ properties:
|
||||
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:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1]
|
||||
|
@ -29,6 +29,7 @@ properties:
|
||||
- renesas,r9a07g043-wdt # RZ/G2UL and RZ/Five
|
||||
- renesas,r9a07g044-wdt # RZ/G2{L,LC}
|
||||
- renesas,r9a07g054-wdt # RZ/V2L
|
||||
- renesas,r9a08g045-wdt # RZ/G3S
|
||||
- const: renesas,rzg2l-wdt
|
||||
|
||||
- items:
|
||||
|
@ -946,7 +946,8 @@ config RENESAS_RZN1WDT
|
||||
|
||||
config RENESAS_RZG2LWDT
|
||||
tristate "Renesas RZ/G2L WDT Watchdog"
|
||||
depends on ARCH_RENESAS || COMPILE_TEST
|
||||
depends on ARCH_RZG2L || ARCH_R9A09G011 || COMPILE_TEST
|
||||
depends on PM || COMPILE_TEST
|
||||
select WATCHDOG_CORE
|
||||
help
|
||||
This driver adds watchdog support for the integrated watchdogs in the
|
||||
|
@ -290,6 +290,11 @@ static int imx7ulp_wdt_init(struct imx7ulp_wdt_device *wdt, unsigned int timeout
|
||||
if (wdt->ext_reset)
|
||||
val |= WDOG_CS_INT_EN;
|
||||
|
||||
if (readl(wdt->base + WDOG_CS) & WDOG_CS_EN) {
|
||||
set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
|
||||
val |= WDOG_CS_EN;
|
||||
}
|
||||
|
||||
do {
|
||||
ret = _imx7ulp_wdt_init(wdt, timeout, val);
|
||||
toval = readl(wdt->base + WDOG_TOVAL);
|
||||
|
@ -196,8 +196,8 @@ static int se10_wdt_probe(struct platform_device *pdev)
|
||||
watchdog_set_drvdata(&priv->wdd, priv);
|
||||
|
||||
priv->wdd.parent = dev;
|
||||
priv->wdd.info = &wdt_info,
|
||||
priv->wdd.ops = &se10_wdt_ops,
|
||||
priv->wdd.info = &wdt_info;
|
||||
priv->wdd.ops = &se10_wdt_ops;
|
||||
priv->wdd.timeout = WATCHDOG_TIMEOUT; /* Set default timeout */
|
||||
priv->wdd.min_timeout = MIN_TIMEOUT;
|
||||
priv->wdd.max_timeout = MAX_TIMEOUT;
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
@ -54,35 +53,11 @@ struct rzg2l_wdt_priv {
|
||||
struct reset_control *rstc;
|
||||
unsigned long osc_clk_rate;
|
||||
unsigned long delay;
|
||||
unsigned long minimum_assertion_period;
|
||||
struct clk *pclk;
|
||||
struct clk *osc_clk;
|
||||
enum rz_wdt_type devtype;
|
||||
};
|
||||
|
||||
static int rzg2l_wdt_reset(struct rzg2l_wdt_priv *priv)
|
||||
{
|
||||
int err, status;
|
||||
|
||||
if (priv->devtype == WDT_RZV2M) {
|
||||
/* WDT needs TYPE-B reset control */
|
||||
err = reset_control_assert(priv->rstc);
|
||||
if (err)
|
||||
return err;
|
||||
ndelay(priv->minimum_assertion_period);
|
||||
err = reset_control_deassert(priv->rstc);
|
||||
if (err)
|
||||
return err;
|
||||
err = read_poll_timeout(reset_control_status, status,
|
||||
status != 1, 0, 1000, false,
|
||||
priv->rstc);
|
||||
} else {
|
||||
err = reset_control_reset(priv->rstc);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void rzg2l_wdt_wait_delay(struct rzg2l_wdt_priv *priv)
|
||||
{
|
||||
/* delay timer when change the setting register */
|
||||
@ -123,8 +98,17 @@ static void rzg2l_wdt_init_timeout(struct watchdog_device *wdev)
|
||||
static int rzg2l_wdt_start(struct watchdog_device *wdev)
|
||||
{
|
||||
struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
|
||||
int ret;
|
||||
|
||||
pm_runtime_get_sync(wdev->parent);
|
||||
ret = pm_runtime_resume_and_get(wdev->parent);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = reset_control_deassert(priv->rstc);
|
||||
if (ret) {
|
||||
pm_runtime_put(wdev->parent);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Initialize time out */
|
||||
rzg2l_wdt_init_timeout(wdev);
|
||||
@ -141,15 +125,23 @@ static int rzg2l_wdt_start(struct watchdog_device *wdev)
|
||||
static int rzg2l_wdt_stop(struct watchdog_device *wdev)
|
||||
{
|
||||
struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
|
||||
int ret;
|
||||
|
||||
rzg2l_wdt_reset(priv);
|
||||
pm_runtime_put(wdev->parent);
|
||||
ret = reset_control_assert(priv->rstc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = pm_runtime_put(wdev->parent);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rzg2l_wdt_set_timeout(struct watchdog_device *wdev, unsigned int timeout)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
wdev->timeout = timeout;
|
||||
|
||||
/*
|
||||
@ -158,22 +150,30 @@ static int rzg2l_wdt_set_timeout(struct watchdog_device *wdev, unsigned int time
|
||||
* to reset the module) so that it is updated with new timeout values.
|
||||
*/
|
||||
if (watchdog_active(wdev)) {
|
||||
rzg2l_wdt_stop(wdev);
|
||||
rzg2l_wdt_start(wdev);
|
||||
ret = rzg2l_wdt_stop(wdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = rzg2l_wdt_start(wdev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rzg2l_wdt_restart(struct watchdog_device *wdev,
|
||||
unsigned long action, void *data)
|
||||
{
|
||||
struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
|
||||
int ret;
|
||||
|
||||
clk_prepare_enable(priv->pclk);
|
||||
clk_prepare_enable(priv->osc_clk);
|
||||
|
||||
if (priv->devtype == WDT_RZG2L) {
|
||||
ret = reset_control_deassert(priv->rstc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Generate Reset (WDTRSTB) Signal on parity error */
|
||||
rzg2l_wdt_write(priv, 0, PECR);
|
||||
|
||||
@ -181,7 +181,9 @@ static int rzg2l_wdt_restart(struct watchdog_device *wdev,
|
||||
rzg2l_wdt_write(priv, PEEN_FORCE, PEEN);
|
||||
} else {
|
||||
/* RZ/V2M doesn't have parity error registers */
|
||||
rzg2l_wdt_reset(priv);
|
||||
ret = reset_control_reset(priv->rstc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
wdev->timeout = 0;
|
||||
|
||||
@ -224,13 +226,11 @@ static const struct watchdog_ops rzg2l_wdt_ops = {
|
||||
.restart = rzg2l_wdt_restart,
|
||||
};
|
||||
|
||||
static void rzg2l_wdt_reset_assert_pm_disable(void *data)
|
||||
static void rzg2l_wdt_pm_disable(void *data)
|
||||
{
|
||||
struct watchdog_device *wdev = data;
|
||||
struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
|
||||
|
||||
pm_runtime_disable(wdev->parent);
|
||||
reset_control_assert(priv->rstc);
|
||||
}
|
||||
|
||||
static int rzg2l_wdt_probe(struct platform_device *pdev)
|
||||
@ -273,19 +273,8 @@ static int rzg2l_wdt_probe(struct platform_device *pdev)
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(priv->rstc),
|
||||
"failed to get cpg reset");
|
||||
|
||||
ret = reset_control_deassert(priv->rstc);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to deassert");
|
||||
|
||||
priv->devtype = (uintptr_t)of_device_get_match_data(dev);
|
||||
|
||||
if (priv->devtype == WDT_RZV2M) {
|
||||
priv->minimum_assertion_period = RZV2M_A_NSEC +
|
||||
3 * F2CYCLE_NSEC(pclk_rate) + 5 *
|
||||
max(F2CYCLE_NSEC(priv->osc_clk_rate),
|
||||
F2CYCLE_NSEC(pclk_rate));
|
||||
}
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
priv->wdev.info = &rzg2l_wdt_ident;
|
||||
@ -297,10 +286,9 @@ static int rzg2l_wdt_probe(struct platform_device *pdev)
|
||||
priv->wdev.timeout = WDT_DEFAULT_TIMEOUT;
|
||||
|
||||
watchdog_set_drvdata(&priv->wdev, priv);
|
||||
ret = devm_add_action_or_reset(&pdev->dev,
|
||||
rzg2l_wdt_reset_assert_pm_disable,
|
||||
&priv->wdev);
|
||||
if (ret < 0)
|
||||
dev_set_drvdata(dev, priv);
|
||||
ret = devm_add_action_or_reset(&pdev->dev, rzg2l_wdt_pm_disable, &priv->wdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
watchdog_set_nowayout(&priv->wdev, nowayout);
|
||||
@ -320,10 +308,35 @@ static const struct of_device_id rzg2l_wdt_ids[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rzg2l_wdt_ids);
|
||||
|
||||
static int rzg2l_wdt_suspend_late(struct device *dev)
|
||||
{
|
||||
struct rzg2l_wdt_priv *priv = dev_get_drvdata(dev);
|
||||
|
||||
if (!watchdog_active(&priv->wdev))
|
||||
return 0;
|
||||
|
||||
return rzg2l_wdt_stop(&priv->wdev);
|
||||
}
|
||||
|
||||
static int rzg2l_wdt_resume_early(struct device *dev)
|
||||
{
|
||||
struct rzg2l_wdt_priv *priv = dev_get_drvdata(dev);
|
||||
|
||||
if (!watchdog_active(&priv->wdev))
|
||||
return 0;
|
||||
|
||||
return rzg2l_wdt_start(&priv->wdev);
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops rzg2l_wdt_pm_ops = {
|
||||
LATE_SYSTEM_SLEEP_PM_OPS(rzg2l_wdt_suspend_late, rzg2l_wdt_resume_early)
|
||||
};
|
||||
|
||||
static struct platform_driver rzg2l_wdt_driver = {
|
||||
.driver = {
|
||||
.name = "rzg2l_wdt",
|
||||
.of_match_table = rzg2l_wdt_ids,
|
||||
.pm = &rzg2l_wdt_pm_ops,
|
||||
},
|
||||
.probe = rzg2l_wdt_probe,
|
||||
};
|
||||
|
@ -140,9 +140,9 @@ static int rzn1_wdt_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
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.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
|
||||
|
@ -152,8 +152,10 @@ static int starfive_wdt_enable_clock(struct starfive_wdt *wdt)
|
||||
return dev_err_probe(wdt->wdd.parent, ret, "failed to enable apb clock\n");
|
||||
|
||||
ret = clk_prepare_enable(wdt->core_clk);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
clk_disable_unprepare(wdt->apb_clk);
|
||||
return dev_err_probe(wdt->wdd.parent, ret, "failed to enable core clock\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1004,7 +1004,7 @@ static struct miscdevice watchdog_miscdev = {
|
||||
.fops = &watchdog_fops,
|
||||
};
|
||||
|
||||
static struct class watchdog_class = {
|
||||
static const struct class watchdog_class = {
|
||||
.name = "watchdog",
|
||||
.dev_groups = wdt_groups,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user