Skip to contentSkip to conversation

QUERY: How to handle sharing of interrupt between different peripherals.

DISCUSSION Viresh KUMAR 6 participants 12 messages Mar 15, 2010

lore
Share & tools
lore
#0 lore raw

Hello everybody,

In our SOC (SPEArxxx), we have few peripherals which share common interrupt line. For example we can have GPIO (PL061), SPI (PL022) and SDIO (Arasan) sharing same physical IRQ line. Now there is a register in SOC which can give status of this interrupt line (i.e. source of interrupt). We have standard drivers for all of these, and these drivers don't request IRQ in shared mode.

How should we handle these IRQs now. One way i have been thinking of is to write a wrapper layer for this type of IRQs for our SOC, which will register actual IRQ numbers. Standard drivers can be provided virtual IRQ numbers for registration. Now this wrapper, based on source of interrupt can call the irq_handler for standard drivers.

Is this approach correct? Or is there any standard way to resolve these issues.

regards,
viresh kumar.

#1 lore raw
Quoted 2 lines · Viresh KUMAR

In our SOC (SPEArxxx), we have few peripherals which share common interrupt line.

how about set_irq_chained_handler ?

#2 lore raw
Quoted 4 lines · jassi brar
Quoted 2 lines · Viresh KUMAR

In our SOC (SPEArxxx), we have few peripherals which share common interrupt line.

how about set_irq_chained_handler ?

How about making drivers deal with shared irqs properly... most will, with a small amount of TLC support the usage of one interrupt line shared between more than one peripheral. PCs often share interrupts if the IRQ controller hasn't been put into an extended mode.

Signature · 4 lines
Ben

Q:      What's a light-year?
A:      One-third less calories than a regular year.
#3 lore raw
Quoted 11 lines · Ben Dooks
Quoted 4 lines · jassi brar
Quoted 2 lines · Viresh KUMAR

In our SOC (SPEArxxx), we have few peripherals which share common interrupt line.

how about set_irq_chained_handler ?

How about making drivers deal with shared irqs properly... most will, with a small amount of TLC support the usage of one interrupt line shared between more than one peripheral. PCs often share interrupts if the IRQ controller hasn't been put into an extended mode.

I feel that is the correct way. Just need to send some patchs for exiting drivers.

#4 lore raw
In reply to jassi brar
Quoted 4 lines · jassi brar
Quoted 2 lines · Viresh KUMAR

In our SOC (SPEArxxx), we have few peripherals which share common interrupt line.

how about set_irq_chained_handler ?

I think it is not for this purpose. Better to use IRQF_SHARED in normal request_irq. what do you say?

#5 lore raw
Quoted 8 lines · Viresh KUMAR
Quoted 4 lines · jassi brar
Quoted 2 lines · Viresh KUMAR

In our SOC (SPEArxxx), we have few peripherals which share common interrupt line.

how about set_irq_chained_handler ?

I think it is not for this purpose. Better to use IRQF_SHARED in normal request_irq. what do you say?

Of course, that is preferred if possible, as Ben already suggested. Btw, is your case not similar to having a common UART interrupt for Uart-Rx,Tx,Err irq ?

#6 lore raw
Quoted 5 lines · jassi brar
Quoted 4 lines · Viresh KUMAR
Quoted 3 lines · jassi brar
Quoted 2 lines · Viresh KUMAR

In our SOC (SPEArxxx), we have few peripherals which share common interrupt line.

Quoted 8 lines
Quoted 4 lines
Quoted 1 line

how about set_irq_chained_handler ?

I think it is not for this purpose. Better to use IRQF_SHARED in normal request_irq. what do you say?

Of course, that is preferred if possible, as Ben already suggested. Btw, is your case not similar to having a common UART interrupt for Uart-Rx,Tx,Err irq ?

We are now discussing two different things i suppose.
First: We have a common line for all type interrupts on UART.
This is handled well by the drivers (say - amba-pl011.c), and so we don't really have a issue here.

Second: Now UART, SDIO, SPI, I2S all have a common interrupt line, this is what we need to handle. For this IRQF_SHARED is a better way.

#7 lore raw
Quoted 2 lines · Viresh KUMAR

Second: Now UART, SDIO, SPI, I2S all have a common interrupt line, this is what we need to handle. For this IRQF_SHARED is a better way.

ok, I misunderstood.

#8 lore raw
In reply to Viresh KUMAR
Quoted 3 lines · Viresh KUMAR

Second: Now UART, SDIO, SPI, I2S all have a common interrupt line, this is what we need to handle. For this IRQF_SHARED is a better way.

No, chained handlers are the better way.

For example, your UARTs might be 16550-compatible. But you won't be able to use the already well-tested 16550 driver if it doesn't already use IRQF_SHARED. I haven't looked to see if it does, but that would be just one example...

b.g.

Signature · 4 lines
Bill Gatliff
Embedded systems training and consulting
http://billgatliff.com
bgat at billgatliff.com
#9 lore raw
In reply to Viresh KUMAR
Quoted 4 lines · Viresh KUMAR
Quoted 2 lines · jassi brar

On Mon, Mar 15, 2010 at 1:37 PM, Viresh KUMAR <[email protected]> wrote:

Quoted 9 lines
Quoted 5 lines
Quoted 3 lines

In our SOC (SPEArxxx), we have few peripherals which share common interrupt line.

how about set_irq_chained_handler ?

I think it is not for this purpose. Better to use IRQF_SHARED in normal request_irq. what do you say?

Actually, set_irq_chained_handler() is designed specifically for demultiplexing interrupt lines into independent descriptors, which is exactly what you want here. Otherwise, your drivers must know that they're sharing interrupts, which is a platform-specific assumption. You don't want that.

Take a look at how AT91 is handing their GPIO. Each bank has 32 pins, but only one shared interrupt signal. By demultiplexing that into 32 separate descriptors with set_irq_chained_handler(), drivers can all uniformly call request_irq() when one of their interrupt sources is tied to a GPIO--- same as if their interrupt source is a true IRQ line, an internal source, or whatever. That's what you want.

b.g.

Signature · 4 lines
Bill Gatliff
Embedded systems training and consulting
http://billgatliff.com
bgat at billgatliff.com
#10 lore raw
In reply to Viresh KUMAR
Quoted 5 lines · Viresh KUMAR

In our SOC (SPEArxxx), we have few peripherals which share common interrupt line. For example we can have GPIO (PL061), SPI (PL022) and SDIO (Arasan) sharing same physical IRQ line. Now there is a register in SOC which can give status of this interrupt line (i.e. source of interrupt). We have standard drivers for all of these, and these drivers don't request IRQ in shared mode.

Ultimately, we have all ARM peripherals sharing one interrupt line - because the CPU only has one IRQ-level interrupt signal. That doesn't mean that we hang all interrupt handlers off the same IRQ number though.

Quoted 5 lines

How should we handle these IRQs now. One way i have been thinking of is to write a wrapper layer for this type of IRQs for our SOC, which will register actual IRQ numbers. Standard drivers can be provided virtual IRQ numbers for registration. Now this wrapper, based on source of interrupt can call the irq_handler for standard drivers.

We do have a system for having a multi-level approach to interrupt decoding. Since you have a register which allows you to identify the source of the interrupt, I'd recommend for maximum system performance that you use it.

Shared interrupts have the disadvantage that you need to run each handler every time a device on the shared interrupt signals, which can be very wasteful both in terms of instruction cache lines and IO accesses.

Search arch/arm/ for set_irq_chained_handler to find examples of who to deal with multi-level handling of IRQs.

#11 lore raw
Quoted 10 lines · Russell King - ARM Linux

We do have a system for having a multi-level approach to interrupt decoding. Since you have a register which allows you to identify the source of the interrupt, I'd recommend for maximum system performance that you use it.

Shared interrupts have the disadvantage that you need to run each handler every time a device on the shared interrupt signals, which can be very wasteful both in terms of instruction cache lines and IO accesses.

Search arch/arm/ for set_irq_chained_handler to find examples of who to deal with multi-level handling of IRQs.

OK. So we need to create virtual irqs (defined by s/w), for shared irqs which are mapped on to the real irq (defined by the H/W) through set_irq_chained_handler, right?
thanks for your help.

regards
Shiraz