mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Lars-Peter Clausen <lars@metafoo.de>
To: "Nuno Sá" <noname.nuno@gmail.com>,
	"Fabrizio Lamarque" <fl.scratchpad@gmail.com>
Cc: linux-kernel@vger.kernel.org, Jonathan Cameron <jic23@kernel.org>
Subject: Re: iio: ad7192: Pending IRQ on SDO/RDY causing retrigger of interrupt handler and missing every sample
Date: Wed, 5 Apr 2023 07:28:29 -0700	[thread overview]
Message-ID: <3e1a5b94-5aed-aa4b-c5ee-a44c185504bf@metafoo.de> (raw)
In-Reply-To: <3c5f31cf533ef26ea586e2d18b31995541a95411.camel@gmail.com>

On 4/5/23 06:49, Nuno Sá wrote:
> On Wed, 2023-04-05 at 15:20 +0200, Fabrizio Lamarque wrote:
>> On Wed, Apr 5, 2023 at 12:30 PM Nuno Sá <noname.nuno@gmail.com> wrote:
>>> On Wed, 2023-04-05 at 11:53 +0200, Fabrizio Lamarque wrote:
>>>> Link:
>>>> https://lore.kernel.org/all/20210906065630.16325-3-alexandru.tachici@analog.com/
>>>>
>>>> This commit broke the driver functionality, i.e. cat in_voltage1_raw
>>>> triggers a correct sampling sequence only the first time, then it
>>>> always returns the first sampled value.
>>>>
>>>> Following the sequence of ad_sigma_delta_single_conversion() within
>>>> ad_sigma_delta.c, this is due to:
>>>>
>>>> - IRQ resend mechanism is always enabled for ARM cores
>>>> (CONFIG_HARDIRQS_SW_RESEND)
>>>> - Edge IRQs are always made pending when a corresponding event
>>>> happens, even after disable_irq(). This is intentional and designed to
>>>> prevent missing signal edges.
>>>> - Level IRQs are not impacted by IRQ resend (i.e. IRQ_PENDING is
>>>> always cleared).
>>>> - SPI communication causes the IRQ to be set pending (even if
>>>> corresponding interrupt is disabled)
>>>> - The second time ad_sigma_delta_single_conversion() is called,
>>>> enable_irq() will trigger the interrupt immediately, even if RDY line
>>>> is high.
>>>> - In turn, this causes the call
>>>> wait_for_completion_interruptible_timeout() to exit immediately, with
>>>> RDY line still high.
>>>> - Right after the SPI register read, the MODE register is written with
>>>> AD_SD_MODE_IDLE, and pending conversion is stopped. Hence DATA
>>>> register is never updated.
>>>>
>>>> I would suggest to revert this commit or set the flag with
>>>> IRQF_TRIGGER_LOW instead of IRQF_TRIGGER_FALLING, but I am not sure
>>>> about the problem solved by this commit and how to replicate it.
>>>> Another option would be to keep IRQ flags within bindings only.
>>>>
>>> I'm starting to think that what's stated in that commit
>>>
>>> "Leaving IRQ on level instead of falling might trigger a sample read
>>> when the IRQ is enabled, as the SDO line is already low. "
>>>
>>> might actually be related with something else...
>> Hi Nuno Sá,
>>   thank you again for your replies and the time you are spending in checking
>> the reported issues.
>> I see what you mean...
>> I was asking for details on the actual issue that was solved to have a better
>> understanding of the change.
>>
> Yeah, Alex is no longer in ADI so I cannot really say.
>
>>>> As a side note, AD7192 datasheet says that the falling edge on SDO
>>>> line _can_ be used as an interrupt to processor, but it also states
>>>> that the _level_ on SDO/RDY line indicates the sample is ready. What
>>>> happens on SDO/RDY interrupt line before the ADC conversion is
>>>> triggered should be ignored.
>>>>
>>> Well, from the datasheet (as you already know):
>>>
>>> "
>>> In addition, DOUT/RDY operates as a data ready pin, going low to indicate
>>> the completion of a conversion. If the data is not read after the
>>> conversion,
>>> the pin goes high before the next
>>> update occurs. The DOUT/RDY falling edge can be used as an interrupt to a
>>> processor, indicating that valid
>>> data is available.
>>> "
>>>
>>> So I really read IRQF_TRIGGER_FALLING in the above and all the other sigma
>>> delta devices have the same setting (I think). So the fact that it works
>>> with
>>> level IRQs might just be lucky instead of fixing the real problem. Can you
>>> try
>>> the below patch (I'm starting to think it might be related):
>>>
>> We have been using those ADC series for about a decade, the shared SDO/RDY
>> signal has its own quirks.
>> We also discussed several years ago in a support ticket with ADI, both
>> level and edge
>> sensing should be acceptable, provided that limitations are understood.
>>> https://lore.kernel.org/linux-iio/20230306044737.862-1-honda@mechatrax.com/
>> I just tested the patch, but, at least on the platform I'm working on
>> (I.MX6), it does not
>> solve the issue.
>> Whereas the thread describes the very same issue I am experiencing, I
>> am not sure
>> IRQ_DISABLE_UNLAZY would have any impact. By reading CPU registers I see
> I was expecting to have. AFAIU, the lazy approach would be the responsible for
> this behavior because when you call disable_irq() it does not really mask the
> IRQ in HW. Just marks it as disabled and if another IRQ event comes set's it to
> PENDING and only then masks at HW level... If we "unlazy" the IRQ, we should
> mask the IRQ right away so I would expect not to have any pending IRQ...
>
>> the IRQ line disabled at the hardware level, but when the IRQ flag of
>> the processor
>> is set (and this happens even if the interrupt is masked in HW), the
>> interrupt is immediately
>> triggered anyway.
>> (I see GPIOx_IMR cleared, so interrupt is masked, but GPIOx_ISR set. As soon
>> as
>> enable_irq() is called the interrupt is triggered. Just by clearing
>> GPIOx_ISR before
>> enable_irq() solves the issue. I might share a few debug printk).
>>
> Might be that the problem is actually in the behavior of the above controller?
> As said, I would expect a masked IRQ not to be handled and set to PENDING.
>
>> The "real issue" here is that we have a pending IRQ on the RDY line set
>> even if IRQ is disabled (masked) at the hardware level.
>> It does not happen for level sensing interrupts.
>>
>> This link might further clarify why this should be intentional:
>> https://www.kernel.org/doc/html/latest/core-api/genericirq.html#delayed-interrupt-disable
>> (note that I see the IRQ masked at the hardware level anyway, but it
>> does not prevent
>> the described behavior to happen)
>>
>> In case the interrupt flag has to be IRQF_TRIGGER_FALLING, it might be viable
>> to
>> enable the IRQ before the measurement is requested and eventually
>> ignore any spurious
>> interrupt until the measurement is started (SPI write completed).
>>
> Oh no, that looks like just going around the real problem. It would be
> interesting to test this in some other platforms to see if the behavior is the
> same... I guess now is the time to fully understand this. IIRC, originally
> everything was set as LEVEL but since the datasheet states EDGE should be used,
> Alex moved the flags to EDGE.
>
> Maybe you're also right and we should just remove the flags and let users decide
> in the bindings whatever works best for their platforms given the fact that it
> appears that both LEVEL vs EDGE can be used.
>
> Anyways,
>
> +cc Lars since he was the original developer on the sigma delta stuff and maybe
> he remembers something about this level vs edge mess.
>
> Lars, can you shed some light :)?
I don't remember. But the driver was written with the assumption that 
irq_disable() will stop recording of IRQ events. If that does not hold 
we might have to switch from irq_enable/irq_disable to 
request_irq/free_irq, which will come with a slight overhead.



  reply	other threads:[~2023-04-05 14:29 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-05  9:53 Fabrizio Lamarque
2023-04-05 10:32 ` Nuno Sá
2023-04-05 13:20   ` Fabrizio Lamarque
2023-04-05 13:49     ` Nuno Sá
2023-04-05 14:28       ` Lars-Peter Clausen [this message]
2023-04-05 14:35       ` Lars-Peter Clausen
2023-04-07  8:51         ` Fabrizio Lamarque
2023-04-18 11:30           ` Nuno Sá

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3e1a5b94-5aed-aa4b-c5ee-a44c185504bf@metafoo.de \
    --to=lars@metafoo.de \
    --cc=fl.scratchpad@gmail.com \
    --cc=jic23@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=noname.nuno@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®