linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] drivers/clocksource/mediatek: Ack and disable interrupts on shutdown
@ 2021-03-25  1:35 Evan Benn
  2021-03-25  8:07 ` Daniel Lezcano
  0 siblings, 1 reply; 5+ messages in thread
From: Evan Benn @ 2021-03-25  1:35 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: Stanley Chu, Alexey Klimov, Julia Lawall, Yingjoe Chen,
	Thomas Gleixner, linux-mediatek, Daniel Lezcano,
	linux-arm-kernel, Evan Benn, Viresh Kumar, LKML, Fabien Parent

set_state_shutdown is called during system suspend after interrupts have
been disabled. If the timer has fired in the meantime, there will be
a pending IRQ. So we ack that now and disable the timer. Without this
ARM trusted firmware will abort the suspend due to the pending
interrupt.

Now always disable the IRQ in state transitions, and re-enable in
set_periodic and next_event.

Signed-off-by: Evan Benn <evanbenn@chromium.org>
---

Changes in v2:
Remove the patch that splits the drivers into 2 files.

 drivers/clocksource/timer-mediatek.c | 49 +++++++++++++++++-----------
 1 file changed, 30 insertions(+), 19 deletions(-)

diff --git a/drivers/clocksource/timer-mediatek.c b/drivers/clocksource/timer-mediatek.c
index 9318edcd8963..fba2f9494d90 100644
--- a/drivers/clocksource/timer-mediatek.c
+++ b/drivers/clocksource/timer-mediatek.c
@@ -132,13 +132,33 @@ static u64 notrace mtk_gpt_read_sched_clock(void)
 	return readl_relaxed(gpt_sched_reg);
 }
 
+static void mtk_gpt_disable_ack_interrupts(struct timer_of *to, u8 timer)
+{
+	u32 val;
+
+	/* Disable interrupts */
+	val = readl(timer_of_base(to) + GPT_IRQ_EN_REG);
+	writel(val & ~GPT_IRQ_ENABLE(timer), timer_of_base(to) +
+	       GPT_IRQ_EN_REG);
+
+	/* Ack interrupts */
+	writel(GPT_IRQ_ACK(timer), timer_of_base(to) + GPT_IRQ_ACK_REG);
+}
+
 static void mtk_gpt_clkevt_time_stop(struct timer_of *to, u8 timer)
 {
 	u32 val;
 
+	/* Disable timer */
 	val = readl(timer_of_base(to) + GPT_CTRL_REG(timer));
 	writel(val & ~GPT_CTRL_ENABLE, timer_of_base(to) +
 	       GPT_CTRL_REG(timer));
+
+	/* This may be called with interrupts disabled,
+	 * so we need to ack any interrupt that is pending
+	 * Or for example ATF will prevent a suspend from completing.
+	 */
+	mtk_gpt_disable_ack_interrupts(to, timer);
 }
 
 static void mtk_gpt_clkevt_time_setup(struct timer_of *to,
@@ -152,8 +172,10 @@ static void mtk_gpt_clkevt_time_start(struct timer_of *to,
 {
 	u32 val;
 
-	/* Acknowledge interrupt */
-	writel(GPT_IRQ_ACK(timer), timer_of_base(to) + GPT_IRQ_ACK_REG);
+	/* Enable interrupts */
+	val = readl(timer_of_base(to) + GPT_IRQ_EN_REG);
+	writel(val | GPT_IRQ_ENABLE(timer),
+	       timer_of_base(to) + GPT_IRQ_EN_REG);
 
 	val = readl(timer_of_base(to) + GPT_CTRL_REG(timer));
 
@@ -226,21 +248,6 @@ __init mtk_gpt_setup(struct timer_of *to, u8 timer, u8 option)
 	       timer_of_base(to) + GPT_CTRL_REG(timer));
 }
 
-static void mtk_gpt_enable_irq(struct timer_of *to, u8 timer)
-{
-	u32 val;
-
-	/* Disable all interrupts */
-	writel(0x0, timer_of_base(to) + GPT_IRQ_EN_REG);
-
-	/* Acknowledge all spurious pending interrupts */
-	writel(0x3f, timer_of_base(to) + GPT_IRQ_ACK_REG);
-
-	val = readl(timer_of_base(to) + GPT_IRQ_EN_REG);
-	writel(val | GPT_IRQ_ENABLE(timer),
-	       timer_of_base(to) + GPT_IRQ_EN_REG);
-}
-
 static struct timer_of to = {
 	.flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK,
 
@@ -292,6 +299,12 @@ static int __init mtk_gpt_init(struct device_node *node)
 	if (ret)
 		return ret;
 
+	/* In case the firmware left the interrupts enabled
+	 * disable and ack those now
+	 */
+	mtk_gpt_disable_ack_interrupts(&to, TIMER_CLK_SRC);
+	mtk_gpt_disable_ack_interrupts(&to, TIMER_CLK_EVT);
+
 	/* Configure clock source */
 	mtk_gpt_setup(&to, TIMER_CLK_SRC, GPT_CTRL_OP_FREERUN);
 	clocksource_mmio_init(timer_of_base(&to) + GPT_CNT_REG(TIMER_CLK_SRC),
@@ -305,8 +318,6 @@ static int __init mtk_gpt_init(struct device_node *node)
 	clockevents_config_and_register(&to.clkevt, timer_of_rate(&to),
 					TIMER_SYNC_TICKS, 0xffffffff);
 
-	mtk_gpt_enable_irq(&to, TIMER_CLK_EVT);
-
 	return 0;
 }
 TIMER_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_gpt_init);
-- 
2.31.0.291.g576ba9dcdaf-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] drivers/clocksource/mediatek: Ack and disable interrupts on shutdown
  2021-03-25  1:35 [PATCH v2] drivers/clocksource/mediatek: Ack and disable interrupts on shutdown Evan Benn
@ 2021-03-25  8:07 ` Daniel Lezcano
  2021-03-27  1:31   ` Evan Benn
  0 siblings, 1 reply; 5+ messages in thread
From: Daniel Lezcano @ 2021-03-25  8:07 UTC (permalink / raw)
  To: Evan Benn, Matthias Brugger
  Cc: Stanley Chu, Alexey Klimov, Julia Lawall, Yingjoe Chen,
	Thomas Gleixner, linux-mediatek, linux-arm-kernel, Viresh Kumar,
	LKML, Fabien Parent

On 25/03/2021 02:35, Evan Benn wrote:
> set_state_shutdown is called during system suspend after interrupts have
> been disabled. If the timer has fired in the meantime, there will be
> a pending IRQ. So we ack that now and disable the timer. Without this
> ARM trusted firmware will abort the suspend due to the pending
> interrupt.
> 
> Now always disable the IRQ in state transitions, and re-enable in
> set_periodic and next_event.

Why not put add the suspend/resume callbacks and put there the specific
code and let the irq untouched in the normal flow ?

> Signed-off-by: Evan Benn <evanbenn@chromium.org>
> ---
> 
> Changes in v2:
> Remove the patch that splits the drivers into 2 files.
> 
>  drivers/clocksource/timer-mediatek.c | 49 +++++++++++++++++-----------
>  1 file changed, 30 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/clocksource/timer-mediatek.c b/drivers/clocksource/timer-mediatek.c
> index 9318edcd8963..fba2f9494d90 100644
> --- a/drivers/clocksource/timer-mediatek.c
> +++ b/drivers/clocksource/timer-mediatek.c
> @@ -132,13 +132,33 @@ static u64 notrace mtk_gpt_read_sched_clock(void)
>  	return readl_relaxed(gpt_sched_reg);
>  }
>  
> +static void mtk_gpt_disable_ack_interrupts(struct timer_of *to, u8 timer)
> +{
> +	u32 val;
> +
> +	/* Disable interrupts */
> +	val = readl(timer_of_base(to) + GPT_IRQ_EN_REG);
> +	writel(val & ~GPT_IRQ_ENABLE(timer), timer_of_base(to) +
> +	       GPT_IRQ_EN_REG);
> +
> +	/* Ack interrupts */
> +	writel(GPT_IRQ_ACK(timer), timer_of_base(to) + GPT_IRQ_ACK_REG);
> +}
> +
>  static void mtk_gpt_clkevt_time_stop(struct timer_of *to, u8 timer)
>  {
>  	u32 val;
>  
> +	/* Disable timer */
>  	val = readl(timer_of_base(to) + GPT_CTRL_REG(timer));
>  	writel(val & ~GPT_CTRL_ENABLE, timer_of_base(to) +
>  	       GPT_CTRL_REG(timer));
> +
> +	/* This may be called with interrupts disabled,
> +	 * so we need to ack any interrupt that is pending
> +	 * Or for example ATF will prevent a suspend from completing.
> +	 */
> +	mtk_gpt_disable_ack_interrupts(to, timer);
>  }
>  
>  static void mtk_gpt_clkevt_time_setup(struct timer_of *to,
> @@ -152,8 +172,10 @@ static void mtk_gpt_clkevt_time_start(struct timer_of *to,
>  {
>  	u32 val;
>  
> -	/* Acknowledge interrupt */
> -	writel(GPT_IRQ_ACK(timer), timer_of_base(to) + GPT_IRQ_ACK_REG);
> +	/* Enable interrupts */
> +	val = readl(timer_of_base(to) + GPT_IRQ_EN_REG);
> +	writel(val | GPT_IRQ_ENABLE(timer),
> +	       timer_of_base(to) + GPT_IRQ_EN_REG);
>  
>  	val = readl(timer_of_base(to) + GPT_CTRL_REG(timer));
>  
> @@ -226,21 +248,6 @@ __init mtk_gpt_setup(struct timer_of *to, u8 timer, u8 option)
>  	       timer_of_base(to) + GPT_CTRL_REG(timer));
>  }
>  
> -static void mtk_gpt_enable_irq(struct timer_of *to, u8 timer)
> -{
> -	u32 val;
> -
> -	/* Disable all interrupts */
> -	writel(0x0, timer_of_base(to) + GPT_IRQ_EN_REG);
> -
> -	/* Acknowledge all spurious pending interrupts */
> -	writel(0x3f, timer_of_base(to) + GPT_IRQ_ACK_REG);
> -
> -	val = readl(timer_of_base(to) + GPT_IRQ_EN_REG);
> -	writel(val | GPT_IRQ_ENABLE(timer),
> -	       timer_of_base(to) + GPT_IRQ_EN_REG);
> -}
> -
>  static struct timer_of to = {
>  	.flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK,
>  
> @@ -292,6 +299,12 @@ static int __init mtk_gpt_init(struct device_node *node)
>  	if (ret)
>  		return ret;
>  
> +	/* In case the firmware left the interrupts enabled
> +	 * disable and ack those now
> +	 */
> +	mtk_gpt_disable_ack_interrupts(&to, TIMER_CLK_SRC);
> +	mtk_gpt_disable_ack_interrupts(&to, TIMER_CLK_EVT);
> +
>  	/* Configure clock source */
>  	mtk_gpt_setup(&to, TIMER_CLK_SRC, GPT_CTRL_OP_FREERUN);
>  	clocksource_mmio_init(timer_of_base(&to) + GPT_CNT_REG(TIMER_CLK_SRC),
> @@ -305,8 +318,6 @@ static int __init mtk_gpt_init(struct device_node *node)
>  	clockevents_config_and_register(&to.clkevt, timer_of_rate(&to),
>  					TIMER_SYNC_TICKS, 0xffffffff);
>  
> -	mtk_gpt_enable_irq(&to, TIMER_CLK_EVT);
> -
>  	return 0;
>  }
>  TIMER_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_gpt_init);
> 


-- 
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] drivers/clocksource/mediatek: Ack and disable interrupts on shutdown
  2021-03-25  8:07 ` Daniel Lezcano
@ 2021-03-27  1:31   ` Evan Benn
  2021-04-02 14:15     ` Daniel Lezcano
  0 siblings, 1 reply; 5+ messages in thread
From: Evan Benn @ 2021-03-27  1:31 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Evan Benn, Matthias Brugger, Stanley Chu, Alexey Klimov,
	Julia Lawall, Yingjoe Chen, Thomas Gleixner, linux-mediatek,
	linux-arm-kernel, Viresh Kumar, LKML, Fabien Parent

Hi Daniel,

That is a good point, and I did try that at first and it works fine. I
uploaded this version because the suspend/resume callbacks were
undocumented and mostly not used by other clocksource drivers. I
thought a smaller diff might be preferable.
I also thought it would be better to shut off the interrupt as soon as
it is not needed, avoiding any other potential bugs, instead of just
fixing the one we know about with suspend. I'm not sure how the other
driver / timer disable flows are intended to work for example
(shutdown, detach, etc).

That said I am happy to upload that version if people think it is better.

https://elixir.bootlin.com/linux/latest/source/include/linux/clockchips.h#L120


On Thu, 25 Mar 2021 at 19:10, Daniel Lezcano <daniel.lezcano@linaro.org> wrote:
>
> On 25/03/2021 02:35, Evan Benn wrote:
> > set_state_shutdown is called during system suspend after interrupts have
> > been disabled. If the timer has fired in the meantime, there will be
> > a pending IRQ. So we ack that now and disable the timer. Without this
> > ARM trusted firmware will abort the suspend due to the pending
> > interrupt.
> >
> > Now always disable the IRQ in state transitions, and re-enable in
> > set_periodic and next_event.
>
> Why not put add the suspend/resume callbacks and put there the specific
> code and let the irq untouched in the normal flow ?
>
> > Signed-off-by: Evan Benn <evanbenn@chromium.org>
> > ---
> >
> > Changes in v2:
> > Remove the patch that splits the drivers into 2 files.
> >
> >  drivers/clocksource/timer-mediatek.c | 49 +++++++++++++++++-----------
> >  1 file changed, 30 insertions(+), 19 deletions(-)
> >
> > diff --git a/drivers/clocksource/timer-mediatek.c b/drivers/clocksource/timer-mediatek.c
> > index 9318edcd8963..fba2f9494d90 100644
> > --- a/drivers/clocksource/timer-mediatek.c
> > +++ b/drivers/clocksource/timer-mediatek.c
> > @@ -132,13 +132,33 @@ static u64 notrace mtk_gpt_read_sched_clock(void)
> >       return readl_relaxed(gpt_sched_reg);
> >  }
> >
> > +static void mtk_gpt_disable_ack_interrupts(struct timer_of *to, u8 timer)
> > +{
> > +     u32 val;
> > +
> > +     /* Disable interrupts */
> > +     val = readl(timer_of_base(to) + GPT_IRQ_EN_REG);
> > +     writel(val & ~GPT_IRQ_ENABLE(timer), timer_of_base(to) +
> > +            GPT_IRQ_EN_REG);
> > +
> > +     /* Ack interrupts */
> > +     writel(GPT_IRQ_ACK(timer), timer_of_base(to) + GPT_IRQ_ACK_REG);
> > +}
> > +
> >  static void mtk_gpt_clkevt_time_stop(struct timer_of *to, u8 timer)
> >  {
> >       u32 val;
> >
> > +     /* Disable timer */
> >       val = readl(timer_of_base(to) + GPT_CTRL_REG(timer));
> >       writel(val & ~GPT_CTRL_ENABLE, timer_of_base(to) +
> >              GPT_CTRL_REG(timer));
> > +
> > +     /* This may be called with interrupts disabled,
> > +      * so we need to ack any interrupt that is pending
> > +      * Or for example ATF will prevent a suspend from completing.
> > +      */
> > +     mtk_gpt_disable_ack_interrupts(to, timer);
> >  }
> >
> >  static void mtk_gpt_clkevt_time_setup(struct timer_of *to,
> > @@ -152,8 +172,10 @@ static void mtk_gpt_clkevt_time_start(struct timer_of *to,
> >  {
> >       u32 val;
> >
> > -     /* Acknowledge interrupt */
> > -     writel(GPT_IRQ_ACK(timer), timer_of_base(to) + GPT_IRQ_ACK_REG);
> > +     /* Enable interrupts */
> > +     val = readl(timer_of_base(to) + GPT_IRQ_EN_REG);
> > +     writel(val | GPT_IRQ_ENABLE(timer),
> > +            timer_of_base(to) + GPT_IRQ_EN_REG);
> >
> >       val = readl(timer_of_base(to) + GPT_CTRL_REG(timer));
> >
> > @@ -226,21 +248,6 @@ __init mtk_gpt_setup(struct timer_of *to, u8 timer, u8 option)
> >              timer_of_base(to) + GPT_CTRL_REG(timer));
> >  }
> >
> > -static void mtk_gpt_enable_irq(struct timer_of *to, u8 timer)
> > -{
> > -     u32 val;
> > -
> > -     /* Disable all interrupts */
> > -     writel(0x0, timer_of_base(to) + GPT_IRQ_EN_REG);
> > -
> > -     /* Acknowledge all spurious pending interrupts */
> > -     writel(0x3f, timer_of_base(to) + GPT_IRQ_ACK_REG);
> > -
> > -     val = readl(timer_of_base(to) + GPT_IRQ_EN_REG);
> > -     writel(val | GPT_IRQ_ENABLE(timer),
> > -            timer_of_base(to) + GPT_IRQ_EN_REG);
> > -}
> > -
> >  static struct timer_of to = {
> >       .flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK,
> >
> > @@ -292,6 +299,12 @@ static int __init mtk_gpt_init(struct device_node *node)
> >       if (ret)
> >               return ret;
> >
> > +     /* In case the firmware left the interrupts enabled
> > +      * disable and ack those now
> > +      */
> > +     mtk_gpt_disable_ack_interrupts(&to, TIMER_CLK_SRC);
> > +     mtk_gpt_disable_ack_interrupts(&to, TIMER_CLK_EVT);
> > +
> >       /* Configure clock source */
> >       mtk_gpt_setup(&to, TIMER_CLK_SRC, GPT_CTRL_OP_FREERUN);
> >       clocksource_mmio_init(timer_of_base(&to) + GPT_CNT_REG(TIMER_CLK_SRC),
> > @@ -305,8 +318,6 @@ static int __init mtk_gpt_init(struct device_node *node)
> >       clockevents_config_and_register(&to.clkevt, timer_of_rate(&to),
> >                                       TIMER_SYNC_TICKS, 0xffffffff);
> >
> > -     mtk_gpt_enable_irq(&to, TIMER_CLK_EVT);
> > -
> >       return 0;
> >  }
> >  TIMER_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_gpt_init);
> >
>
>
> --
> <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
>
> Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
> <http://twitter.com/#!/linaroorg> Twitter |
> <http://www.linaro.org/linaro-blog/> Blog

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] drivers/clocksource/mediatek: Ack and disable interrupts on shutdown
  2021-03-27  1:31   ` Evan Benn
@ 2021-04-02 14:15     ` Daniel Lezcano
  2021-04-06  1:01       ` Evan Benn
  0 siblings, 1 reply; 5+ messages in thread
From: Daniel Lezcano @ 2021-04-02 14:15 UTC (permalink / raw)
  To: Evan Benn
  Cc: Evan Benn, Matthias Brugger, Stanley Chu, Alexey Klimov,
	Julia Lawall, Yingjoe Chen, Thomas Gleixner, linux-mediatek,
	linux-arm-kernel, Viresh Kumar, LKML, Fabien Parent


Hi Evan,

On 27/03/2021 02:31, Evan Benn wrote:
> Hi Daniel,
> 
> That is a good point, and I did try that at first and it works fine. I
> uploaded this version because the suspend/resume callbacks were
> undocumented and mostly not used by other clocksource drivers. I
> thought a smaller diff might be preferable.
> I also thought it would be better to shut off the interrupt as soon as
> it is not needed, avoiding any other potential bugs, instead of just
> fixing the one we know about with suspend. I'm not sure how the other
> driver / timer disable flows are intended to work for example
> (shutdown, detach, etc).
> 
> That said I am happy to upload that version if people think it is better.

IMO, it is not in the normal flow to disable/enable the interrupts.

Does this timer belong to an always-on power domain ?



> https://elixir.bootlin.com/linux/latest/source/include/linux/clockchips.h#L120
> 
> 
> On Thu, 25 Mar 2021 at 19:10, Daniel Lezcano <daniel.lezcano@linaro.org> wrote:
>>
>> On 25/03/2021 02:35, Evan Benn wrote:
>>> set_state_shutdown is called during system suspend after interrupts have
>>> been disabled. If the timer has fired in the meantime, there will be
>>> a pending IRQ. So we ack that now and disable the timer. Without this
>>> ARM trusted firmware will abort the suspend due to the pending
>>> interrupt.


>>> Now always disable the IRQ in state transitions, and re-enable in
>>> set_periodic and next_event.
>>
>> Why not put add the suspend/resume callbacks and put there the specific
>> code and let the irq untouched in the normal flow ?
>>
>>> Signed-off-by: Evan Benn <evanbenn@chromium.org>
>>> ---
>>>
>>> Changes in v2:
>>> Remove the patch that splits the drivers into 2 files.
>>>
>>>  drivers/clocksource/timer-mediatek.c | 49 +++++++++++++++++-----------
>>>  1 file changed, 30 insertions(+), 19 deletions(-)
>>>
>>> diff --git a/drivers/clocksource/timer-mediatek.c b/drivers/clocksource/timer-mediatek.c
>>> index 9318edcd8963..fba2f9494d90 100644
>>> --- a/drivers/clocksource/timer-mediatek.c
>>> +++ b/drivers/clocksource/timer-mediatek.c
>>> @@ -132,13 +132,33 @@ static u64 notrace mtk_gpt_read_sched_clock(void)
>>>       return readl_relaxed(gpt_sched_reg);
>>>  }
>>>
>>> +static void mtk_gpt_disable_ack_interrupts(struct timer_of *to, u8 timer)
>>> +{
>>> +     u32 val;
>>> +
>>> +     /* Disable interrupts */
>>> +     val = readl(timer_of_base(to) + GPT_IRQ_EN_REG);
>>> +     writel(val & ~GPT_IRQ_ENABLE(timer), timer_of_base(to) +
>>> +            GPT_IRQ_EN_REG);
>>> +
>>> +     /* Ack interrupts */
>>> +     writel(GPT_IRQ_ACK(timer), timer_of_base(to) + GPT_IRQ_ACK_REG);
>>> +}
>>> +
>>>  static void mtk_gpt_clkevt_time_stop(struct timer_of *to, u8 timer)
>>>  {
>>>       u32 val;
>>>
>>> +     /* Disable timer */
>>>       val = readl(timer_of_base(to) + GPT_CTRL_REG(timer));
>>>       writel(val & ~GPT_CTRL_ENABLE, timer_of_base(to) +
>>>              GPT_CTRL_REG(timer));
>>> +
>>> +     /* This may be called with interrupts disabled,
>>> +      * so we need to ack any interrupt that is pending
>>> +      * Or for example ATF will prevent a suspend from completing.
>>> +      */
>>> +     mtk_gpt_disable_ack_interrupts(to, timer);
>>>  }
>>>
>>>  static void mtk_gpt_clkevt_time_setup(struct timer_of *to,
>>> @@ -152,8 +172,10 @@ static void mtk_gpt_clkevt_time_start(struct timer_of *to,
>>>  {
>>>       u32 val;
>>>
>>> -     /* Acknowledge interrupt */
>>> -     writel(GPT_IRQ_ACK(timer), timer_of_base(to) + GPT_IRQ_ACK_REG);
>>> +     /* Enable interrupts */
>>> +     val = readl(timer_of_base(to) + GPT_IRQ_EN_REG);
>>> +     writel(val | GPT_IRQ_ENABLE(timer),
>>> +            timer_of_base(to) + GPT_IRQ_EN_REG);
>>>
>>>       val = readl(timer_of_base(to) + GPT_CTRL_REG(timer));
>>>
>>> @@ -226,21 +248,6 @@ __init mtk_gpt_setup(struct timer_of *to, u8 timer, u8 option)
>>>              timer_of_base(to) + GPT_CTRL_REG(timer));
>>>  }
>>>
>>> -static void mtk_gpt_enable_irq(struct timer_of *to, u8 timer)
>>> -{
>>> -     u32 val;
>>> -
>>> -     /* Disable all interrupts */
>>> -     writel(0x0, timer_of_base(to) + GPT_IRQ_EN_REG);
>>> -
>>> -     /* Acknowledge all spurious pending interrupts */
>>> -     writel(0x3f, timer_of_base(to) + GPT_IRQ_ACK_REG);
>>> -
>>> -     val = readl(timer_of_base(to) + GPT_IRQ_EN_REG);
>>> -     writel(val | GPT_IRQ_ENABLE(timer),
>>> -            timer_of_base(to) + GPT_IRQ_EN_REG);
>>> -}
>>> -
>>>  static struct timer_of to = {
>>>       .flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK,
>>>
>>> @@ -292,6 +299,12 @@ static int __init mtk_gpt_init(struct device_node *node)
>>>       if (ret)
>>>               return ret;
>>>
>>> +     /* In case the firmware left the interrupts enabled
>>> +      * disable and ack those now
>>> +      */
>>> +     mtk_gpt_disable_ack_interrupts(&to, TIMER_CLK_SRC);
>>> +     mtk_gpt_disable_ack_interrupts(&to, TIMER_CLK_EVT);
>>> +
>>>       /* Configure clock source */
>>>       mtk_gpt_setup(&to, TIMER_CLK_SRC, GPT_CTRL_OP_FREERUN);
>>>       clocksource_mmio_init(timer_of_base(&to) + GPT_CNT_REG(TIMER_CLK_SRC),
>>> @@ -305,8 +318,6 @@ static int __init mtk_gpt_init(struct device_node *node)
>>>       clockevents_config_and_register(&to.clkevt, timer_of_rate(&to),
>>>                                       TIMER_SYNC_TICKS, 0xffffffff);
>>>
>>> -     mtk_gpt_enable_irq(&to, TIMER_CLK_EVT);
>>> -
>>>       return 0;
>>>  }
>>>  TIMER_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_gpt_init);
>>>
>>
>>
>> --
>> <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
>>
>> Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
>> <http://twitter.com/#!/linaroorg> Twitter |
>> <http://www.linaro.org/linaro-blog/> Blog


-- 
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] drivers/clocksource/mediatek: Ack and disable interrupts on shutdown
  2021-04-02 14:15     ` Daniel Lezcano
@ 2021-04-06  1:01       ` Evan Benn
  0 siblings, 0 replies; 5+ messages in thread
From: Evan Benn @ 2021-04-06  1:01 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Evan Benn, Matthias Brugger, Stanley Chu, Alexey Klimov,
	Julia Lawall, Yingjoe Chen, Thomas Gleixner,
	moderated list:ARM/Mediatek SoC support,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	Viresh Kumar, LKML, Fabien Parent

On Sat, Apr 3, 2021 at 1:15 AM Daniel Lezcano <daniel.lezcano@linaro.org> wrote:
> >
> > That said I am happy to upload that version if people think it is better.
>
> IMO, it is not in the normal flow to disable/enable the interrupts.

Hi Daniel, no problem.

I will upload the suspend/resume version. Please note the similar fix
to the other timer in this file:

https://patchwork.kernel.org/project/linux-mediatek/patch/1614670085-26229-2-git-send-email-Fengquan.Chen@mediatek.com/

Is doing the same ack/disable.

>
> Does this timer belong to an always-on power domain ?
>

I'm not sure sorry, the datasheet does not seem to say. Maybe mediatek
can answer.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-04-06  1:03 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-25  1:35 [PATCH v2] drivers/clocksource/mediatek: Ack and disable interrupts on shutdown Evan Benn
2021-03-25  8:07 ` Daniel Lezcano
2021-03-27  1:31   ` Evan Benn
2021-04-02 14:15     ` Daniel Lezcano
2021-04-06  1:01       ` Evan Benn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).