linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] iio: xilinx-ams: Unmask interrupts after updating alarms
@ 2025-07-15  0:28 Sean Anderson
  2025-07-24 15:32 ` Jonathan Cameron
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Sean Anderson @ 2025-07-15  0:28 UTC (permalink / raw)
  To: Anand Ashok Dumbre, Jonathan Cameron, linux-iio
  Cc: David Lechner, Nuno Sá, linux-arm-kernel, Michal Simek,
	Andy Shevchenko, Manish Narani, linux-kernel, Sean Anderson

To convert level-triggered alarms into edge-triggered IIO events, alarms
are masked when they are triggered. To ensure we catch subsequent
alarms, we then periodically poll to see if the alarm is still active.
If it isn't, we unmask it. Active but masked alarms are stored in
current_masked_alarm.

If an active alarm is disabled, it will remain set in
current_masked_alarm until ams_unmask_worker clears it. If the alarm is
re-enabled before ams_unmask_worker runs, then it will never be cleared
from current_masked_alarm. This will prevent the alarm event from being
pushed even if the alarm is still active.

Fix this by recalculating current_masked_alarm immediately when enabling
or disabling alarms.

Fixes: d5c70627a794 ("iio: adc: Add Xilinx AMS driver")
Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
---

 drivers/iio/adc/xilinx-ams.c | 45 ++++++++++++++++++++----------------
 1 file changed, 25 insertions(+), 20 deletions(-)

diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c
index 76dd0343f5f7..180d4140993d 100644
--- a/drivers/iio/adc/xilinx-ams.c
+++ b/drivers/iio/adc/xilinx-ams.c
@@ -389,6 +389,29 @@ static void ams_update_pl_alarm(struct ams *ams, unsigned long alarm_mask)
 	ams_pl_update_reg(ams, AMS_REG_CONFIG3, AMS_REGCFG3_ALARM_MASK, cfg);
 }
 
+static void ams_unmask(struct ams *ams)
+{
+	unsigned int status, unmask;
+
+	status = readl(ams->base + AMS_ISR_0);
+
+	/* Clear those bits which are not active anymore */
+	unmask = (ams->current_masked_alarm ^ status) & ams->current_masked_alarm;
+
+	/* Clear status of disabled alarm */
+	unmask |= ams->intr_mask;
+
+	ams->current_masked_alarm &= status;
+
+	/* Also clear those which are masked out anyway */
+	ams->current_masked_alarm &= ~ams->intr_mask;
+
+	/* Clear the interrupts before we unmask them */
+	writel(unmask, ams->base + AMS_ISR_0);
+
+	ams_update_intrmask(ams, ~AMS_ALARM_MASK, ~AMS_ALARM_MASK);
+}
+
 static void ams_update_alarm(struct ams *ams, unsigned long alarm_mask)
 {
 	unsigned long flags;
@@ -401,6 +424,7 @@ static void ams_update_alarm(struct ams *ams, unsigned long alarm_mask)
 
 	spin_lock_irqsave(&ams->intr_lock, flags);
 	ams_update_intrmask(ams, AMS_ISR0_ALARM_MASK, ~alarm_mask);
+	ams_unmask(ams);
 	spin_unlock_irqrestore(&ams->intr_lock, flags);
 }
 
@@ -1035,28 +1059,9 @@ static void ams_handle_events(struct iio_dev *indio_dev, unsigned long events)
 static void ams_unmask_worker(struct work_struct *work)
 {
 	struct ams *ams = container_of(work, struct ams, ams_unmask_work.work);
-	unsigned int status, unmask;
 
 	spin_lock_irq(&ams->intr_lock);
-
-	status = readl(ams->base + AMS_ISR_0);
-
-	/* Clear those bits which are not active anymore */
-	unmask = (ams->current_masked_alarm ^ status) & ams->current_masked_alarm;
-
-	/* Clear status of disabled alarm */
-	unmask |= ams->intr_mask;
-
-	ams->current_masked_alarm &= status;
-
-	/* Also clear those which are masked out anyway */
-	ams->current_masked_alarm &= ~ams->intr_mask;
-
-	/* Clear the interrupts before we unmask them */
-	writel(unmask, ams->base + AMS_ISR_0);
-
-	ams_update_intrmask(ams, ~AMS_ALARM_MASK, ~AMS_ALARM_MASK);
-
+	ams_unmask(ams);
 	spin_unlock_irq(&ams->intr_lock);
 
 	/* If still pending some alarm re-trigger the timer */
-- 
2.35.1.1320.gc452695387.dirty



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

* Re: [PATCH] iio: xilinx-ams: Unmask interrupts after updating alarms
  2025-07-15  0:28 [PATCH] iio: xilinx-ams: Unmask interrupts after updating alarms Sean Anderson
@ 2025-07-24 15:32 ` Jonathan Cameron
  2025-07-25  4:47   ` Michal Simek
  2025-08-20 11:23 ` Erim, Salih
  2025-08-20 11:28 ` O'Griofa, Conall
  2 siblings, 1 reply; 9+ messages in thread
From: Jonathan Cameron @ 2025-07-24 15:32 UTC (permalink / raw)
  To: Sean Anderson
  Cc: Anand Ashok Dumbre, linux-iio, David Lechner, Nuno Sá,
	linux-arm-kernel, Michal Simek, Andy Shevchenko, Manish Narani,
	linux-kernel

On Mon, 14 Jul 2025 20:28:47 -0400
Sean Anderson <sean.anderson@linux.dev> wrote:

> To convert level-triggered alarms into edge-triggered IIO events, alarms
> are masked when they are triggered. To ensure we catch subsequent
> alarms, we then periodically poll to see if the alarm is still active.
> If it isn't, we unmask it. Active but masked alarms are stored in
> current_masked_alarm.
> 
> If an active alarm is disabled, it will remain set in
> current_masked_alarm until ams_unmask_worker clears it. If the alarm is
> re-enabled before ams_unmask_worker runs, then it will never be cleared
> from current_masked_alarm. This will prevent the alarm event from being
> pushed even if the alarm is still active.
> 
> Fix this by recalculating current_masked_alarm immediately when enabling
> or disabling alarms.
> 
> Fixes: d5c70627a794 ("iio: adc: Add Xilinx AMS driver")
> Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
> ---
Anand?  

This seems fine to me, but I'm not that familiar with the hardware or driver.

> 
>  drivers/iio/adc/xilinx-ams.c | 45 ++++++++++++++++++++----------------
>  1 file changed, 25 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c
> index 76dd0343f5f7..180d4140993d 100644
> --- a/drivers/iio/adc/xilinx-ams.c
> +++ b/drivers/iio/adc/xilinx-ams.c
> @@ -389,6 +389,29 @@ static void ams_update_pl_alarm(struct ams *ams, unsigned long alarm_mask)
>  	ams_pl_update_reg(ams, AMS_REG_CONFIG3, AMS_REGCFG3_ALARM_MASK, cfg);
>  }
>  
> +static void ams_unmask(struct ams *ams)
> +{
> +	unsigned int status, unmask;
> +
> +	status = readl(ams->base + AMS_ISR_0);
> +
> +	/* Clear those bits which are not active anymore */
> +	unmask = (ams->current_masked_alarm ^ status) & ams->current_masked_alarm;
> +
> +	/* Clear status of disabled alarm */
> +	unmask |= ams->intr_mask;
> +
> +	ams->current_masked_alarm &= status;
> +
> +	/* Also clear those which are masked out anyway */
> +	ams->current_masked_alarm &= ~ams->intr_mask;
> +
> +	/* Clear the interrupts before we unmask them */
> +	writel(unmask, ams->base + AMS_ISR_0);
> +
> +	ams_update_intrmask(ams, ~AMS_ALARM_MASK, ~AMS_ALARM_MASK);
> +}
> +
>  static void ams_update_alarm(struct ams *ams, unsigned long alarm_mask)
>  {
>  	unsigned long flags;
> @@ -401,6 +424,7 @@ static void ams_update_alarm(struct ams *ams, unsigned long alarm_mask)
>  
>  	spin_lock_irqsave(&ams->intr_lock, flags);
>  	ams_update_intrmask(ams, AMS_ISR0_ALARM_MASK, ~alarm_mask);
> +	ams_unmask(ams);
>  	spin_unlock_irqrestore(&ams->intr_lock, flags);
>  }
>  
> @@ -1035,28 +1059,9 @@ static void ams_handle_events(struct iio_dev *indio_dev, unsigned long events)
>  static void ams_unmask_worker(struct work_struct *work)
>  {
>  	struct ams *ams = container_of(work, struct ams, ams_unmask_work.work);
> -	unsigned int status, unmask;
>  
>  	spin_lock_irq(&ams->intr_lock);
> -
> -	status = readl(ams->base + AMS_ISR_0);
> -
> -	/* Clear those bits which are not active anymore */
> -	unmask = (ams->current_masked_alarm ^ status) & ams->current_masked_alarm;
> -
> -	/* Clear status of disabled alarm */
> -	unmask |= ams->intr_mask;
> -
> -	ams->current_masked_alarm &= status;
> -
> -	/* Also clear those which are masked out anyway */
> -	ams->current_masked_alarm &= ~ams->intr_mask;
> -
> -	/* Clear the interrupts before we unmask them */
> -	writel(unmask, ams->base + AMS_ISR_0);
> -
> -	ams_update_intrmask(ams, ~AMS_ALARM_MASK, ~AMS_ALARM_MASK);
> -
> +	ams_unmask(ams);
>  	spin_unlock_irq(&ams->intr_lock);
>  
>  	/* If still pending some alarm re-trigger the timer */



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

* Re: [PATCH] iio: xilinx-ams: Unmask interrupts after updating alarms
  2025-07-24 15:32 ` Jonathan Cameron
@ 2025-07-25  4:47   ` Michal Simek
  2025-07-27 15:43     ` Jonathan Cameron
  0 siblings, 1 reply; 9+ messages in thread
From: Michal Simek @ 2025-07-25  4:47 UTC (permalink / raw)
  To: Jonathan Cameron, Sean Anderson, Salih Erim, O'Griofa, Conall
  Cc: Anand Ashok Dumbre, linux-iio, David Lechner, Nuno Sá,
	linux-arm-kernel, Andy Shevchenko, Manish Narani, linux-kernel



On 7/24/25 17:32, Jonathan Cameron wrote:
> On Mon, 14 Jul 2025 20:28:47 -0400
> Sean Anderson <sean.anderson@linux.dev> wrote:
> 
>> To convert level-triggered alarms into edge-triggered IIO events, alarms
>> are masked when they are triggered. To ensure we catch subsequent
>> alarms, we then periodically poll to see if the alarm is still active.
>> If it isn't, we unmask it. Active but masked alarms are stored in
>> current_masked_alarm.
>>
>> If an active alarm is disabled, it will remain set in
>> current_masked_alarm until ams_unmask_worker clears it. If the alarm is
>> re-enabled before ams_unmask_worker runs, then it will never be cleared
>> from current_masked_alarm. This will prevent the alarm event from being
>> pushed even if the alarm is still active.
>>
>> Fix this by recalculating current_masked_alarm immediately when enabling
>> or disabling alarms.
>>
>> Fixes: d5c70627a794 ("iio: adc: Add Xilinx AMS driver")
>> Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
>> ---
> Anand?
> 
> This seems fine to me, but I'm not that familiar with the hardware or driver.

Anand left some time ago. Salih or Conall should be able to provide some input.

Thanks,
Michal


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

* Re: [PATCH] iio: xilinx-ams: Unmask interrupts after updating alarms
  2025-07-25  4:47   ` Michal Simek
@ 2025-07-27 15:43     ` Jonathan Cameron
  2025-07-28  5:54       ` Michal Simek
  0 siblings, 1 reply; 9+ messages in thread
From: Jonathan Cameron @ 2025-07-27 15:43 UTC (permalink / raw)
  To: Michal Simek
  Cc: Sean Anderson, Salih Erim, O'Griofa, Conall,
	Anand Ashok Dumbre, linux-iio, David Lechner, Nuno Sá,
	linux-arm-kernel, Andy Shevchenko, Manish Narani, linux-kernel

On Fri, 25 Jul 2025 06:47:16 +0200
Michal Simek <michal.simek@amd.com> wrote:

> On 7/24/25 17:32, Jonathan Cameron wrote:
> > On Mon, 14 Jul 2025 20:28:47 -0400
> > Sean Anderson <sean.anderson@linux.dev> wrote:
> >   
> >> To convert level-triggered alarms into edge-triggered IIO events, alarms
> >> are masked when they are triggered. To ensure we catch subsequent
> >> alarms, we then periodically poll to see if the alarm is still active.
> >> If it isn't, we unmask it. Active but masked alarms are stored in
> >> current_masked_alarm.
> >>
> >> If an active alarm is disabled, it will remain set in
> >> current_masked_alarm until ams_unmask_worker clears it. If the alarm is
> >> re-enabled before ams_unmask_worker runs, then it will never be cleared
> >> from current_masked_alarm. This will prevent the alarm event from being
> >> pushed even if the alarm is still active.
> >>
> >> Fix this by recalculating current_masked_alarm immediately when enabling
> >> or disabling alarms.
> >>
> >> Fixes: d5c70627a794 ("iio: adc: Add Xilinx AMS driver")
> >> Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
> >> ---  
> > Anand?
> > 
> > This seems fine to me, but I'm not that familiar with the hardware or driver.  
> 
> Anand left some time ago. Salih or Conall should be able to provide some input.
> 
> Thanks,
> Michal
> 

Hi Michal,

Thanks for letting me know.  Would be good to have a MAINTAINERS update patch
to remove Anand + ideally add someone else.  If not to mark it orphaned
(will still be covered by the top level IIO entry).



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

* Re: [PATCH] iio: xilinx-ams: Unmask interrupts after updating alarms
  2025-07-27 15:43     ` Jonathan Cameron
@ 2025-07-28  5:54       ` Michal Simek
  2025-07-30 10:55         ` Erim, Salih
  0 siblings, 1 reply; 9+ messages in thread
From: Michal Simek @ 2025-07-28  5:54 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Sean Anderson, Salih Erim, O'Griofa, Conall,
	Anand Ashok Dumbre, linux-iio, David Lechner, Nuno Sá,
	linux-arm-kernel, Andy Shevchenko, Manish Narani, linux-kernel



On 7/27/25 17:43, Jonathan Cameron wrote:
> On Fri, 25 Jul 2025 06:47:16 +0200
> Michal Simek <michal.simek@amd.com> wrote:
> 
>> On 7/24/25 17:32, Jonathan Cameron wrote:
>>> On Mon, 14 Jul 2025 20:28:47 -0400
>>> Sean Anderson <sean.anderson@linux.dev> wrote:
>>>    
>>>> To convert level-triggered alarms into edge-triggered IIO events, alarms
>>>> are masked when they are triggered. To ensure we catch subsequent
>>>> alarms, we then periodically poll to see if the alarm is still active.
>>>> If it isn't, we unmask it. Active but masked alarms are stored in
>>>> current_masked_alarm.
>>>>
>>>> If an active alarm is disabled, it will remain set in
>>>> current_masked_alarm until ams_unmask_worker clears it. If the alarm is
>>>> re-enabled before ams_unmask_worker runs, then it will never be cleared
>>>> from current_masked_alarm. This will prevent the alarm event from being
>>>> pushed even if the alarm is still active.
>>>>
>>>> Fix this by recalculating current_masked_alarm immediately when enabling
>>>> or disabling alarms.
>>>>
>>>> Fixes: d5c70627a794 ("iio: adc: Add Xilinx AMS driver")
>>>> Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
>>>> ---
>>> Anand?
>>>
>>> This seems fine to me, but I'm not that familiar with the hardware or driver.
>>
>> Anand left some time ago. Salih or Conall should be able to provide some input.
>>
>> Thanks,
>> Michal
>>
> 
> Hi Michal,
> 
> Thanks for letting me know.  Would be good to have a MAINTAINERS update patch
> to remove Anand + ideally add someone else.  If not to mark it orphaned
> (will still be covered by the top level IIO entry).

Salih: Can you please send a patch for it?

It is also covered my fragment that's why you don't need to explicitly add me there.

Thanks,
Michal





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

* RE: [PATCH] iio: xilinx-ams: Unmask interrupts after updating alarms
  2025-07-28  5:54       ` Michal Simek
@ 2025-07-30 10:55         ` Erim, Salih
  0 siblings, 0 replies; 9+ messages in thread
From: Erim, Salih @ 2025-07-30 10:55 UTC (permalink / raw)
  To: Simek, Michal, Jonathan Cameron
  Cc: Sean Anderson, O'Griofa, Conall, linux-iio@vger.kernel.org,
	David Lechner, Nuno Sá, linux-arm-kernel@lists.infradead.org,
	Andy Shevchenko, Manish Narani, linux-kernel@vger.kernel.org

[AMD Official Use Only - AMD Internal Distribution Only]

Hi,

I am really busy right now. I will look into this within next week.

Regards,
Salih.

> -----Original Message-----
> From: Simek, Michal <michal.simek@amd.com>
> Sent: Monday, July 28, 2025 6:55 AM
> To: Jonathan Cameron <jic23@kernel.org>
> Cc: Sean Anderson <sean.anderson@linux.dev>; Erim, Salih
> <Salih.Erim@amd.com>; O'Griofa, Conall <conall.ogriofa@amd.com>; Anand
> Ashok Dumbre <anand.ashok.dumbre@xilinx.com>; linux-iio@vger.kernel.org;
> David Lechner <dlechner@baylibre.com>; Nuno Sá <nuno.sa@analog.com>; linux-
> arm-kernel@lists.infradead.org; Andy Shevchenko <andy@kernel.org>; Manish
> Narani <manish.narani@xilinx.com>; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH] iio: xilinx-ams: Unmask interrupts after updating alarms
>
>
>
> On 7/27/25 17:43, Jonathan Cameron wrote:
> > On Fri, 25 Jul 2025 06:47:16 +0200
> > Michal Simek <michal.simek@amd.com> wrote:
> >
> >> On 7/24/25 17:32, Jonathan Cameron wrote:
> >>> On Mon, 14 Jul 2025 20:28:47 -0400
> >>> Sean Anderson <sean.anderson@linux.dev> wrote:
> >>>
> >>>> To convert level-triggered alarms into edge-triggered IIO events,
> >>>> alarms are masked when they are triggered. To ensure we catch
> >>>> subsequent alarms, we then periodically poll to see if the alarm is still active.
> >>>> If it isn't, we unmask it. Active but masked alarms are stored in
> >>>> current_masked_alarm.
> >>>>
> >>>> If an active alarm is disabled, it will remain set in
> >>>> current_masked_alarm until ams_unmask_worker clears it. If the
> >>>> alarm is re-enabled before ams_unmask_worker runs, then it will
> >>>> never be cleared from current_masked_alarm. This will prevent the
> >>>> alarm event from being pushed even if the alarm is still active.
> >>>>
> >>>> Fix this by recalculating current_masked_alarm immediately when
> >>>> enabling or disabling alarms.
> >>>>
> >>>> Fixes: d5c70627a794 ("iio: adc: Add Xilinx AMS driver")
> >>>> Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
> >>>> ---
> >>> Anand?
> >>>
> >>> This seems fine to me, but I'm not that familiar with the hardware or driver.
> >>
> >> Anand left some time ago. Salih or Conall should be able to provide some input.
> >>
> >> Thanks,
> >> Michal
> >>
> >
> > Hi Michal,
> >
> > Thanks for letting me know.  Would be good to have a MAINTAINERS
> > update patch to remove Anand + ideally add someone else.  If not to
> > mark it orphaned (will still be covered by the top level IIO entry).
>
> Salih: Can you please send a patch for it?
>
> It is also covered my fragment that's why you don't need to explicitly add me there.
>
> Thanks,
> Michal
>
>



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

* RE: [PATCH] iio: xilinx-ams: Unmask interrupts after updating alarms
  2025-07-15  0:28 [PATCH] iio: xilinx-ams: Unmask interrupts after updating alarms Sean Anderson
  2025-07-24 15:32 ` Jonathan Cameron
@ 2025-08-20 11:23 ` Erim, Salih
  2025-08-20 11:28 ` O'Griofa, Conall
  2 siblings, 0 replies; 9+ messages in thread
From: Erim, Salih @ 2025-08-20 11:23 UTC (permalink / raw)
  To: Sean Anderson, Jonathan Cameron, linux-iio@vger.kernel.org,
	O'Griofa, Conall
  Cc: David Lechner, Nuno Sá, linux-arm-kernel@lists.infradead.org,
	Simek, Michal, Andy Shevchenko, Manish Narani,
	linux-kernel@vger.kernel.org

Hi Sean,

> -----Original Message-----
> From: Sean Anderson <sean.anderson@linux.dev>
> Sent: Tuesday, July 15, 2025 1:29 AM
> To: Anand Ashok Dumbre <anand.ashok.dumbre@xilinx.com>; Jonathan Cameron
> <jic23@kernel.org>; linux-iio@vger.kernel.org
> Cc: David Lechner <dlechner@baylibre.com>; Nuno Sá <nuno.sa@analog.com>;
> linux-arm-kernel@lists.infradead.org; Simek, Michal <michal.simek@amd.com>;
> Andy Shevchenko <andy@kernel.org>; Manish Narani
> <manish.narani@xilinx.com>; linux-kernel@vger.kernel.org; Sean Anderson
> <sean.anderson@linux.dev>
> Subject: [PATCH] iio: xilinx-ams: Unmask interrupts after updating alarms
> 
> Caution: This message originated from an External Source. Use proper caution
> when opening attachments, clicking links, or responding.
> 
> 
> To convert level-triggered alarms into edge-triggered IIO events, alarms are masked
> when they are triggered. To ensure we catch subsequent alarms, we then
> periodically poll to see if the alarm is still active.
> If it isn't, we unmask it. Active but masked alarms are stored in
> current_masked_alarm.
> 
> If an active alarm is disabled, it will remain set in current_masked_alarm until
> ams_unmask_worker clears it. If the alarm is re-enabled before
> ams_unmask_worker runs, then it will never be cleared from
> current_masked_alarm. This will prevent the alarm event from being pushed even if
> the alarm is still active.
> 
> Fix this by recalculating current_masked_alarm immediately when enabling or
> disabling alarms.
> 
> Fixes: d5c70627a794 ("iio: adc: Add Xilinx AMS driver")
> Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
> ---
> 
>  drivers/iio/adc/xilinx-ams.c | 45 ++++++++++++++++++++----------------
>  1 file changed, 25 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c index
> 76dd0343f5f7..180d4140993d 100644
> --- a/drivers/iio/adc/xilinx-ams.c
> +++ b/drivers/iio/adc/xilinx-ams.c
> @@ -389,6 +389,29 @@ static void ams_update_pl_alarm(struct ams *ams,
> unsigned long alarm_mask)
>         ams_pl_update_reg(ams, AMS_REG_CONFIG3,
> AMS_REGCFG3_ALARM_MASK, cfg);  }
> 
> +static void ams_unmask(struct ams *ams) {
> +       unsigned int status, unmask;
> +
> +       status = readl(ams->base + AMS_ISR_0);
> +
> +       /* Clear those bits which are not active anymore */
> +       unmask = (ams->current_masked_alarm ^ status) &
> + ams->current_masked_alarm;
> +
> +       /* Clear status of disabled alarm */
> +       unmask |= ams->intr_mask;
> +
> +       ams->current_masked_alarm &= status;
> +
> +       /* Also clear those which are masked out anyway */
> +       ams->current_masked_alarm &= ~ams->intr_mask;
> +
> +       /* Clear the interrupts before we unmask them */
> +       writel(unmask, ams->base + AMS_ISR_0);
> +
> +       ams_update_intrmask(ams, ~AMS_ALARM_MASK, ~AMS_ALARM_MASK);
> }
> +
>  static void ams_update_alarm(struct ams *ams, unsigned long alarm_mask)  {
>         unsigned long flags;
> @@ -401,6 +424,7 @@ static void ams_update_alarm(struct ams *ams, unsigned
> long alarm_mask)
> 
>         spin_lock_irqsave(&ams->intr_lock, flags);
>         ams_update_intrmask(ams, AMS_ISR0_ALARM_MASK, ~alarm_mask);
> +       ams_unmask(ams);
>         spin_unlock_irqrestore(&ams->intr_lock, flags);  }
> 
> @@ -1035,28 +1059,9 @@ static void ams_handle_events(struct iio_dev
> *indio_dev, unsigned long events)  static void ams_unmask_worker(struct
> work_struct *work)  {
>         struct ams *ams = container_of(work, struct ams, ams_unmask_work.work);
> -       unsigned int status, unmask;
> 
>         spin_lock_irq(&ams->intr_lock);
> -
> -       status = readl(ams->base + AMS_ISR_0);
> -
> -       /* Clear those bits which are not active anymore */
> -       unmask = (ams->current_masked_alarm ^ status) & ams-
> >current_masked_alarm;
> -
> -       /* Clear status of disabled alarm */
> -       unmask |= ams->intr_mask;
> -
> -       ams->current_masked_alarm &= status;
> -
> -       /* Also clear those which are masked out anyway */
> -       ams->current_masked_alarm &= ~ams->intr_mask;
> -
> -       /* Clear the interrupts before we unmask them */
> -       writel(unmask, ams->base + AMS_ISR_0);
> -
> -       ams_update_intrmask(ams, ~AMS_ALARM_MASK, ~AMS_ALARM_MASK);
> -
> +       ams_unmask(ams);
>         spin_unlock_irq(&ams->intr_lock);
> 
>         /* If still pending some alarm re-trigger the timer */
> --
> 2.35.1.1320.gc452695387.dirty
> 

Tested-by: Erim, Salih <Salih.Erim@amd.com>
Acked-by: Erim, Salih <Salih.Erim@amd.com>


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

* RE: [PATCH] iio: xilinx-ams: Unmask interrupts after updating alarms
  2025-07-15  0:28 [PATCH] iio: xilinx-ams: Unmask interrupts after updating alarms Sean Anderson
  2025-07-24 15:32 ` Jonathan Cameron
  2025-08-20 11:23 ` Erim, Salih
@ 2025-08-20 11:28 ` O'Griofa, Conall
  2025-08-25 11:23   ` Jonathan Cameron
  2 siblings, 1 reply; 9+ messages in thread
From: O'Griofa, Conall @ 2025-08-20 11:28 UTC (permalink / raw)
  To: Sean Anderson, Anand Ashok Dumbre, Jonathan Cameron,
	linux-iio@vger.kernel.org
  Cc: David Lechner, Nuno Sá, linux-arm-kernel@lists.infradead.org,
	Simek, Michal, Andy Shevchenko, Manish Narani,
	linux-kernel@vger.kernel.org

Hi,

Looks good, thank you for taking the time to submit this patch.

Cheers,
Conall.

> -----Original Message-----
> From: Sean Anderson <sean.anderson@linux.dev>
> Sent: 15 July 2025 01:29
> To: Anand Ashok Dumbre <anand.ashok.dumbre@xilinx.com>; Jonathan Cameron
> <jic23@kernel.org>; linux-iio@vger.kernel.org
> Cc: David Lechner <dlechner@baylibre.com>; Nuno Sá <nuno.sa@analog.com>;
> linux-arm-kernel@lists.infradead.org; Simek, Michal <michal.simek@amd.com>;
> Andy Shevchenko <andy@kernel.org>; Manish Narani
> <manish.narani@xilinx.com>; linux-kernel@vger.kernel.org; Sean Anderson
> <sean.anderson@linux.dev>
> Subject: [PATCH] iio: xilinx-ams: Unmask interrupts after updating alarms
> 
> To convert level-triggered alarms into edge-triggered IIO events, alarms are masked
> when they are triggered. To ensure we catch subsequent alarms, we then
> periodically poll to see if the alarm is still active.
> If it isn't, we unmask it. Active but masked alarms are stored in
> current_masked_alarm.
> 
> If an active alarm is disabled, it will remain set in current_masked_alarm until
> ams_unmask_worker clears it. If the alarm is re-enabled before
> ams_unmask_worker runs, then it will never be cleared from
> current_masked_alarm. This will prevent the alarm event from being pushed even if
> the alarm is still active.
> 
> Fix this by recalculating current_masked_alarm immediately when enabling or
> disabling alarms.
> 
> Fixes: d5c70627a794 ("iio: adc: Add Xilinx AMS driver")
> Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
> ---
> 
>  drivers/iio/adc/xilinx-ams.c | 45 ++++++++++++++++++++----------------
>  1 file changed, 25 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c index
> 76dd0343f5f7..180d4140993d 100644
> --- a/drivers/iio/adc/xilinx-ams.c
> +++ b/drivers/iio/adc/xilinx-ams.c
> @@ -389,6 +389,29 @@ static void ams_update_pl_alarm(struct ams *ams,
> unsigned long alarm_mask)
>  	ams_pl_update_reg(ams, AMS_REG_CONFIG3,
> AMS_REGCFG3_ALARM_MASK, cfg);  }
> 
> +static void ams_unmask(struct ams *ams) {
> +	unsigned int status, unmask;
> +
> +	status = readl(ams->base + AMS_ISR_0);
> +
> +	/* Clear those bits which are not active anymore */
> +	unmask = (ams->current_masked_alarm ^ status) &
> +ams->current_masked_alarm;
> +
> +	/* Clear status of disabled alarm */
> +	unmask |= ams->intr_mask;
> +
> +	ams->current_masked_alarm &= status;
> +
> +	/* Also clear those which are masked out anyway */
> +	ams->current_masked_alarm &= ~ams->intr_mask;
> +
> +	/* Clear the interrupts before we unmask them */
> +	writel(unmask, ams->base + AMS_ISR_0);
> +
> +	ams_update_intrmask(ams, ~AMS_ALARM_MASK,
> ~AMS_ALARM_MASK); }
> +
>  static void ams_update_alarm(struct ams *ams, unsigned long alarm_mask)  {
>  	unsigned long flags;
> @@ -401,6 +424,7 @@ static void ams_update_alarm(struct ams *ams, unsigned
> long alarm_mask)
> 
>  	spin_lock_irqsave(&ams->intr_lock, flags);
>  	ams_update_intrmask(ams, AMS_ISR0_ALARM_MASK, ~alarm_mask);
> +	ams_unmask(ams);
>  	spin_unlock_irqrestore(&ams->intr_lock, flags);  }
> 
> @@ -1035,28 +1059,9 @@ static void ams_handle_events(struct iio_dev
> *indio_dev, unsigned long events)  static void ams_unmask_worker(struct
> work_struct *work)  {
>  	struct ams *ams = container_of(work, struct ams, ams_unmask_work.work);
> -	unsigned int status, unmask;
> 
>  	spin_lock_irq(&ams->intr_lock);
> -
> -	status = readl(ams->base + AMS_ISR_0);
> -
> -	/* Clear those bits which are not active anymore */
> -	unmask = (ams->current_masked_alarm ^ status) & ams-
> >current_masked_alarm;
> -
> -	/* Clear status of disabled alarm */
> -	unmask |= ams->intr_mask;
> -
> -	ams->current_masked_alarm &= status;
> -
> -	/* Also clear those which are masked out anyway */
> -	ams->current_masked_alarm &= ~ams->intr_mask;
> -
> -	/* Clear the interrupts before we unmask them */
> -	writel(unmask, ams->base + AMS_ISR_0);
> -
> -	ams_update_intrmask(ams, ~AMS_ALARM_MASK,
> ~AMS_ALARM_MASK);
> -
> +	ams_unmask(ams);
>  	spin_unlock_irq(&ams->intr_lock);
> 
>  	/* If still pending some alarm re-trigger the timer */
> --
> 2.35.1.1320.gc452695387.dirty

Reviewed-by: O'Griofa, Conall <conall.ogriofa@amd.com>

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

* Re: [PATCH] iio: xilinx-ams: Unmask interrupts after updating alarms
  2025-08-20 11:28 ` O'Griofa, Conall
@ 2025-08-25 11:23   ` Jonathan Cameron
  0 siblings, 0 replies; 9+ messages in thread
From: Jonathan Cameron @ 2025-08-25 11:23 UTC (permalink / raw)
  To: O'Griofa, Conall
  Cc: Sean Anderson, Anand Ashok Dumbre, linux-iio@vger.kernel.org,
	David Lechner, Nuno Sá, linux-arm-kernel@lists.infradead.org,
	Simek, Michal, Andy Shevchenko, Manish Narani,
	linux-kernel@vger.kernel.org

On Wed, 20 Aug 2025 11:28:27 +0000
"O'Griofa, Conall" <conall.ogriofa@amd.com> wrote:

> Hi,
> 
> Looks good, thank you for taking the time to submit this patch.
Applied to the fixes-togreg branch of iio.git and marked for stable.

Thanks,

Jonathan

> 
> Cheers,
> Conall.
> 
> > -----Original Message-----
> > From: Sean Anderson <sean.anderson@linux.dev>
> > Sent: 15 July 2025 01:29
> > To: Anand Ashok Dumbre <anand.ashok.dumbre@xilinx.com>; Jonathan Cameron
> > <jic23@kernel.org>; linux-iio@vger.kernel.org
> > Cc: David Lechner <dlechner@baylibre.com>; Nuno Sá <nuno.sa@analog.com>;
> > linux-arm-kernel@lists.infradead.org; Simek, Michal <michal.simek@amd.com>;
> > Andy Shevchenko <andy@kernel.org>; Manish Narani
> > <manish.narani@xilinx.com>; linux-kernel@vger.kernel.org; Sean Anderson
> > <sean.anderson@linux.dev>
> > Subject: [PATCH] iio: xilinx-ams: Unmask interrupts after updating alarms
> > 
> > To convert level-triggered alarms into edge-triggered IIO events, alarms are masked
> > when they are triggered. To ensure we catch subsequent alarms, we then
> > periodically poll to see if the alarm is still active.
> > If it isn't, we unmask it. Active but masked alarms are stored in
> > current_masked_alarm.
> > 
> > If an active alarm is disabled, it will remain set in current_masked_alarm until
> > ams_unmask_worker clears it. If the alarm is re-enabled before
> > ams_unmask_worker runs, then it will never be cleared from
> > current_masked_alarm. This will prevent the alarm event from being pushed even if
> > the alarm is still active.
> > 
> > Fix this by recalculating current_masked_alarm immediately when enabling or
> > disabling alarms.
> > 
> > Fixes: d5c70627a794 ("iio: adc: Add Xilinx AMS driver")
> > Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
> > ---
> > 
> >  drivers/iio/adc/xilinx-ams.c | 45 ++++++++++++++++++++----------------
> >  1 file changed, 25 insertions(+), 20 deletions(-)
> > 
> > diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c index
> > 76dd0343f5f7..180d4140993d 100644
> > --- a/drivers/iio/adc/xilinx-ams.c
> > +++ b/drivers/iio/adc/xilinx-ams.c
> > @@ -389,6 +389,29 @@ static void ams_update_pl_alarm(struct ams *ams,
> > unsigned long alarm_mask)
> >  	ams_pl_update_reg(ams, AMS_REG_CONFIG3,
> > AMS_REGCFG3_ALARM_MASK, cfg);  }
> > 
> > +static void ams_unmask(struct ams *ams) {
> > +	unsigned int status, unmask;
> > +
> > +	status = readl(ams->base + AMS_ISR_0);
> > +
> > +	/* Clear those bits which are not active anymore */
> > +	unmask = (ams->current_masked_alarm ^ status) &
> > +ams->current_masked_alarm;
> > +
> > +	/* Clear status of disabled alarm */
> > +	unmask |= ams->intr_mask;
> > +
> > +	ams->current_masked_alarm &= status;
> > +
> > +	/* Also clear those which are masked out anyway */
> > +	ams->current_masked_alarm &= ~ams->intr_mask;
> > +
> > +	/* Clear the interrupts before we unmask them */
> > +	writel(unmask, ams->base + AMS_ISR_0);
> > +
> > +	ams_update_intrmask(ams, ~AMS_ALARM_MASK,
> > ~AMS_ALARM_MASK); }
> > +
> >  static void ams_update_alarm(struct ams *ams, unsigned long alarm_mask)  {
> >  	unsigned long flags;
> > @@ -401,6 +424,7 @@ static void ams_update_alarm(struct ams *ams, unsigned
> > long alarm_mask)
> > 
> >  	spin_lock_irqsave(&ams->intr_lock, flags);
> >  	ams_update_intrmask(ams, AMS_ISR0_ALARM_MASK, ~alarm_mask);
> > +	ams_unmask(ams);
> >  	spin_unlock_irqrestore(&ams->intr_lock, flags);  }
> > 
> > @@ -1035,28 +1059,9 @@ static void ams_handle_events(struct iio_dev
> > *indio_dev, unsigned long events)  static void ams_unmask_worker(struct
> > work_struct *work)  {
> >  	struct ams *ams = container_of(work, struct ams, ams_unmask_work.work);
> > -	unsigned int status, unmask;
> > 
> >  	spin_lock_irq(&ams->intr_lock);
> > -
> > -	status = readl(ams->base + AMS_ISR_0);
> > -
> > -	/* Clear those bits which are not active anymore */
> > -	unmask = (ams->current_masked_alarm ^ status) & ams-  
> > >current_masked_alarm;  
> > -
> > -	/* Clear status of disabled alarm */
> > -	unmask |= ams->intr_mask;
> > -
> > -	ams->current_masked_alarm &= status;
> > -
> > -	/* Also clear those which are masked out anyway */
> > -	ams->current_masked_alarm &= ~ams->intr_mask;
> > -
> > -	/* Clear the interrupts before we unmask them */
> > -	writel(unmask, ams->base + AMS_ISR_0);
> > -
> > -	ams_update_intrmask(ams, ~AMS_ALARM_MASK,
> > ~AMS_ALARM_MASK);
> > -
> > +	ams_unmask(ams);
> >  	spin_unlock_irq(&ams->intr_lock);
> > 
> >  	/* If still pending some alarm re-trigger the timer */
> > --
> > 2.35.1.1320.gc452695387.dirty  
> 
> Reviewed-by: O'Griofa, Conall <conall.ogriofa@amd.com>



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

end of thread, other threads:[~2025-08-25 12:52 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-15  0:28 [PATCH] iio: xilinx-ams: Unmask interrupts after updating alarms Sean Anderson
2025-07-24 15:32 ` Jonathan Cameron
2025-07-25  4:47   ` Michal Simek
2025-07-27 15:43     ` Jonathan Cameron
2025-07-28  5:54       ` Michal Simek
2025-07-30 10:55         ` Erim, Salih
2025-08-20 11:23 ` Erim, Salih
2025-08-20 11:28 ` O'Griofa, Conall
2025-08-25 11:23   ` Jonathan Cameron

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).