Hi Bernhard,

On Mon, Oct 5, 2026 at 6:21 PM Bernhard Beschow <[email protected]> wrote:
>
> Since WDT and WDE are write one once bits, their values always
> correspond with their respective locked attributes. Thus, the attributes
> are redundant. Take advantage of this observation to simplify the code.
>
> Note that removing the attributes changes the vmstate structure which
> constitutes a migration break. This is allowed since QEMU does not
> guarantee migration compatibility for i.MX devices between feature
> releases.
>
> Signed-off-by: Bernhard Beschow <[email protected]>
> ---
>  include/hw/watchdog/wdt_imx2.h |  2 --
>  hw/watchdog/wdt_imx2.c         | 21 ++++-----------------
>  2 files changed, 4 insertions(+), 19 deletions(-)
>
> diff --git a/include/hw/watchdog/wdt_imx2.h b/include/hw/watchdog/wdt_imx2.h
> index fc01fc46e7..0bf2903959 100644
> --- a/include/hw/watchdog/wdt_imx2.h
> +++ b/include/hw/watchdog/wdt_imx2.h
> @@ -84,8 +84,6 @@ struct IMX2WdtState {
>      uint16_t wmcr;
>
>      bool wcr_locked;            /* affects WDZST, WDBG, and WDW */
> -    bool wcr_wde_locked;        /* affects WDE */
> -    bool wcr_wdt_locked;        /* affects WDT, cleared on POR */
>  };
>
>  #endif /* WDT_IMX2_H */
> diff --git a/hw/watchdog/wdt_imx2.c b/hw/watchdog/wdt_imx2.c
> index a15f452d48..e9cb5819e4 100644
> --- a/hw/watchdog/wdt_imx2.c
> +++ b/hw/watchdog/wdt_imx2.c
> @@ -59,8 +59,6 @@ static void imx2_wdt_reset(DeviceState *dev)
>
>      s->wicr_locked = false;
>      s->wcr_locked = false;
> -    s->wcr_wde_locked = false;
> -    s->wcr_wdt_locked = false;
>
>      s->wcr = IMX2_WDT_WCR_WDA | IMX2_WDT_WCR_SRS;
>      s->wsr = 0;
> @@ -156,24 +154,14 @@ static void imx2_wdt_write(void *opaque, hwaddr addr,
>      switch (addr) {
>      case IMX2_WDT_WCR:
>          if (s->wcr_locked) {
> +            /* WDZST, WDBG, and WDW are write-once bits */
>              value &= ~IMX2_WDT_WCR_LOCK_MASK;
>              value |= (s->wcr & IMX2_WDT_WCR_LOCK_MASK);
>          }
>          s->wcr_locked = true;
> -        if (s->wcr_wde_locked) {
> -            value &= ~IMX2_WDT_WCR_WDE;
> -            value |= (s->wcr & IMX2_WDT_WCR_WDE);
> -        } else if (value & IMX2_WDT_WCR_WDE) {
> -            s->wcr_wde_locked = true;
> -        }
> -        if (s->wcr_wdt_locked) {
> -            value &= ~IMX2_WDT_WCR_WDT;
> -            value |= (s->wcr & IMX2_WDT_WCR_WDT);
> -        } else if (value & IMX2_WDT_WCR_WDT) {
> -            s->wcr_wdt_locked = true;
> -        }
>
> -        s->wcr = value;
> +        /* WDT and WDE are write one once bits */
> +        s->wcr = value | (s->wcr & (IMX2_WDT_WCR_WDT | IMX2_WDT_WCR_WDE));
>          if (!(value & IMX2_WDT_WCR_SRS)) {
>              s->wrsr = IMX2_WDT_WRSR_SFTW;
>          }

In the following codes:

        if (!(value & (IMX2_WDT_WCR_WDA | IMX2_WDT_WCR_SRS)) ||
            (!(value & IMX2_WDT_WCR_WT) && (value & IMX2_WDT_WCR_WDE))) {
            watchdog_perform_action();
        }

Since you removed the part:

        value |= (s->wcr & IMX2_WDT_WCR_{WDE,WDT})

now 'value' does not contain the preserved WDE/WDT bits (they are only
preserved in s->wcr in this patch), the watchdog_perform_action()
won't be called.

> @@ -234,13 +222,12 @@ static const MemoryRegionOps imx2_wdt_ops = {
>
>  static const VMStateDescription vmstate_imx2_wdt = {
>      .name = "imx2.wdt",
> +    .version_id = 1,
>      .fields = (const VMStateField[]) {
>          VMSTATE_PTIMER(timer, IMX2WdtState),
>          VMSTATE_PTIMER(itimer, IMX2WdtState),
>          VMSTATE_BOOL(wicr_locked, IMX2WdtState),
>          VMSTATE_BOOL(wcr_locked, IMX2WdtState),
> -        VMSTATE_BOOL(wcr_wde_locked, IMX2WdtState),
> -        VMSTATE_BOOL(wcr_wdt_locked, IMX2WdtState),
>          VMSTATE_UINT16(wcr, IMX2WdtState),
>          VMSTATE_UINT16(wsr, IMX2WdtState),
>          VMSTATE_UINT16(wrsr, IMX2WdtState),

Regards,
Bin

Reply via email to