@@ -25,6 +25,7 @@ struct stm32_lp_private {
struct clock_event_device clkevt;
unsigned long period;
struct device *dev;
+ bool ier_wr_enabled; /* Enables LPTIMER before writing into IER register */
};
static struct stm32_lp_private*
@@ -37,8 +38,15 @@ static int stm32_clkevent_lp_shutdown(struct clock_event_device *clkevt)
{
struct stm32_lp_private *priv = to_priv(clkevt);
- regmap_write(priv->reg, STM32_LPTIM_CR, 0);
+ /* Disable LPTIMER either before or after writing IER register (else, keep it enabled) */
+ if (!priv->ier_wr_enabled)
+ regmap_write(priv->reg, STM32_LPTIM_CR, 0);
+
regmap_write(priv->reg, STM32_LPTIM_IER, 0);
+
+ if (priv->ier_wr_enabled)
+ regmap_write(priv->reg, STM32_LPTIM_CR, 0);
+
/* clear pending flags */
regmap_write(priv->reg, STM32_LPTIM_ICR, STM32_LPTIM_ARRMCF);
@@ -51,12 +59,21 @@ static int stm32_clkevent_lp_set_timer(unsigned long evt,
{
struct stm32_lp_private *priv = to_priv(clkevt);
- /* disable LPTIMER to be able to write into IER register*/
- regmap_write(priv->reg, STM32_LPTIM_CR, 0);
+ if (!priv->ier_wr_enabled) {
+ /* Disable LPTIMER to be able to write into IER register */
+ regmap_write(priv->reg, STM32_LPTIM_CR, 0);
+ } else {
+ /* Enable LPTIMER to be able to write into IER register */
+ regmap_write(priv->reg, STM32_LPTIM_CR, STM32_LPTIM_ENABLE);
+ }
+
/* enable ARR interrupt */
regmap_write(priv->reg, STM32_LPTIM_IER, STM32_LPTIM_ARRMIE);
+
/* enable LPTIMER to be able to write into ARR register */
- regmap_write(priv->reg, STM32_LPTIM_CR, STM32_LPTIM_ENABLE);
+ if (!priv->ier_wr_enabled)
+ regmap_write(priv->reg, STM32_LPTIM_CR, STM32_LPTIM_ENABLE);
+
/* set next event counter */
regmap_write(priv->reg, STM32_LPTIM_ARR, evt);
@@ -151,6 +168,7 @@ static int stm32_clkevent_lp_probe(struct platform_device *pdev)
return -ENOMEM;
priv->reg = ddata->regmap;
+ priv->ier_wr_enabled = ddata->version == STM32_LPTIM_VERR_23;
ret = clk_prepare_enable(ddata->clk);
if (ret)
return -EINVAL;