*         Pascal Paillet <p.paillet@st.com> for STMicroelectronics.
  */
 
+#include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/clockchips.h>
 #include <linux/interrupt.h>
        u32 psc;
        struct device *dev;
        struct clk *clk;
+       u32 version;
 };
 
 static struct stm32_lp_private*
        return 0;
 }
 
-static int stm32_clkevent_lp_set_timer(unsigned long evt,
-                                      struct clock_event_device *clkevt,
-                                      int is_periodic)
+static int stm32mp25_clkevent_lp_set_evt(struct stm32_lp_private *priv, unsigned long evt)
 {
-       struct stm32_lp_private *priv = to_priv(clkevt);
+       int ret;
+       u32 val;
+
+       regmap_read(priv->reg, STM32_LPTIM_CR, &val);
+       if (!FIELD_GET(STM32_LPTIM_ENABLE, val)) {
+               /* Enable LPTIMER to be able to write into IER and ARR registers */
+               regmap_write(priv->reg, STM32_LPTIM_CR, STM32_LPTIM_ENABLE);
+               /*
+                * After setting the ENABLE bit, a delay of two counter clock cycles is needed
+                * before the LPTIM is actually enabled. For 32KHz rate, this makes approximately
+                * 62.5 micro-seconds, round it up.
+                */
+               udelay(63);
+       }
+       /* set next event counter */
+       regmap_write(priv->reg, STM32_LPTIM_ARR, evt);
+       /* enable ARR interrupt */
+       regmap_write(priv->reg, STM32_LPTIM_IER, STM32_LPTIM_ARRMIE);
+
+       /* Poll DIEROK and ARROK to ensure register access has completed */
+       ret = regmap_read_poll_timeout_atomic(priv->reg, STM32_LPTIM_ISR, val,
+                                             (val & STM32_LPTIM_DIEROK_ARROK) ==
+                                             STM32_LPTIM_DIEROK_ARROK,
+                                             10, 500);
+       if (ret) {
+               dev_err(priv->dev, "access to LPTIM timed out\n");
+               /* Disable LPTIMER */
+               regmap_write(priv->reg, STM32_LPTIM_CR, 0);
+               return ret;
+       }
+       /* Clear DIEROK and ARROK flags */
+       regmap_write(priv->reg, STM32_LPTIM_ICR, STM32_LPTIM_DIEROKCF_ARROKCF);
 
+       return 0;
+}
+
+static void stm32_clkevent_lp_set_evt(struct stm32_lp_private *priv, unsigned long evt)
+{
        /* disable LPTIMER to be able to write into IER register*/
        regmap_write(priv->reg, STM32_LPTIM_CR, 0);
        /* enable ARR interrupt */
        regmap_write(priv->reg, STM32_LPTIM_CR, STM32_LPTIM_ENABLE);
        /* set next event counter */
        regmap_write(priv->reg, STM32_LPTIM_ARR, evt);
+}
+
+static int stm32_clkevent_lp_set_timer(unsigned long evt,
+                                      struct clock_event_device *clkevt,
+                                      int is_periodic)
+{
+       struct stm32_lp_private *priv = to_priv(clkevt);
+       int ret;
+
+       if (priv->version == STM32_LPTIM_VERR_23) {
+               ret = stm32mp25_clkevent_lp_set_evt(priv, evt);
+               if (ret)
+                       return ret;
+       } else {
+               stm32_clkevent_lp_set_evt(priv, evt);
+       }
 
        /* start counter */
        if (is_periodic)
                return -ENOMEM;
 
        priv->reg = ddata->regmap;
+       priv->version = ddata->version;
        priv->clk = ddata->clk;
        ret = clk_prepare_enable(priv->clk);
        if (ret)