Re: Design of interrupt controller driver

From: Mason
Date: Tue Jun 06 2017 - 05:36:15 EST


On 06/06/2017 09:39, Thomas Gleixner wrote:

> On Mon, 5 Jun 2017, Mason wrote:
>
>> Is it possible to call the interrupt controller's mask callback
>> from the DMA engine driver ISR, or is that reserved for the IRQ
>> framework? Because that's what the HW designers had in mind,
>> thus they didn't provide a way to mask the interrupt in the
>> device. It just outputs the signal to the interrupt router.
>
> No, it's not and we are not going to provide an interface for that because
> that violates any form of layering and abstractions. The DMA device driver
> has to be oblivious of the underlying interrupt handling machinery.

Sorry, I didn't mean *explicitly* calling the mask callback,
but rather void mask_irq(struct irq_desc *desc);
I note that mask_irq() is *not* exported, which means modules
cannot to use it. In-tree drivers are probably not supposed
to use it either? Same thing for irq_disable?

What about disable_irq(virq);
That function /is/ exported API, and eventually calls mask_irq.

disable_irq -> __disable_irq_nosync -> __disable_irq -> irq_disable -> mask_irq

>> So their proposed setup is as follows:
>>
>> Start the system with the DMA interrupt masked in the intc.
>> When SW needs to perform a DMA op, the DMA driver starts
>> the op (thus the interrupt signal goes low), then unmasks
>> the interrupt in the intc. Interrupt triggers when signal
>> goes high (level high). Driver masks interrupt in ISR,
>> until next op is available.
>>
>> Is that possible in the Linux framework?
>
> You can do that, but not for shared interrupts:
>
> isr()
> {
> disable_irq_nosync();
> .....
> }
>
> submit()
> {
> ....
> enable_irq();
> }
>
> init()
> {
> irq_set_status_flags(irq, IRQ_NOAUTOEN);
> request_irq(irq, ....);
> }
>
> This affects the whole interrupt line, so if you share that interrupt at
> the CPU interrupt controller level this wont work.
>
> If your 'router' IP has a mechanism to mask input lines individually, then
> you can do something about this.
>
> Each group of inputs which shares an output becomes it's own demultiplexing
> interrupt domain with it's own interrupt chip which controls the input
> lines. The output is handled by a chained interrupt handler which checks
> the status of the input lines and invokes the handlers for the devices with
> an active input.
>
> Then the above example will disable the interrupt at the 'router' level
> which will not affect the other device which shares the underlying output
> to the GIC (or whatever interrupt controller your CPU has).

I will have to re-read this a few times to digest it.

Regards.