Skip to contentSkip to conversation

Handling multiple GPIO controllers in 8xxx GPIO driver

DISCUSSION Felix Radensky 3 participants 8 messages Sep 27, 2011 – Sep 30, 2011

lore
Share & tools
lore
#0 lore raw

Hi,

Looks like 8xxx GPIO driver cannot properly handle interrupts when multiple GPIO controllers exist in the system.

On Freescale P1022 there are 3 GPIO controllers. All 3 use the same interrupt line, internal interrupt 31. If all controllers are defined in device tree set_irq_chained_handler() is invoked 3 times with same hardware irq number. The result is interrupt storm, mpc8xxx_gpio_irq_cascade() is invoked indefinitely.

What would be the best way to fix the problem ?

Thanks.

Felix Radensky.

#1 lore raw
Quoted 5 lines · Felix Radensky

Hi,

Looks like 8xxx GPIO driver cannot properly handle interrupts when multiple GPIO controllers exist in the system.

Quoted 7 lines

On Freescale P1022 there are 3 GPIO controllers. All 3 use the same interrupt line, internal interrupt 31. If all controllers are defined in device tree set_irq_chained_handler() is invoked 3 times with same hardware irq number. The result is interrupt storm, mpc8xxx_gpio_irq_cascade() is invoked indefinitely.

What would be the best way to fix the problem ?

The solution is to make the gpio driver register as a regular interrupt handler, and not as a chained handler.

g.

#2 lore raw

Hi Grant,

Quoted 12 lines · Grant Likely
Quoted 11 lines · Felix Radensky

Hi,

Looks like 8xxx GPIO driver cannot properly handle interrupts when multiple GPIO controllers exist in the system.

On Freescale P1022 there are 3 GPIO controllers. All 3 use the same interrupt line, internal interrupt 31. If all controllers are defined in device tree set_irq_chained_handler() is invoked 3 times with same hardware irq number. The result is interrupt storm, mpc8xxx_gpio_irq_cascade() is invoked indefinitely.

Quoted 6 lines
Quoted 1 line

What would be the best way to fix the problem ?

The solution is to make the gpio driver register as a regular interrupt handler, and not as a chained handler.

g.

You mean interrupt handler per GPIO pin ?

Felix.

#3 lore raw
In reply to Grant Likely

On Tue, Sep 27, 2011 at 1:29 PM, Grant Likely <[email protected]> w= rote:

Quoted 2 lines

The solution is to make the gpio driver register as a regular interrupt handler, and not as a chained handler.

I was wondering about that.

What exactly is a chained handler? How is it different from a regular hand= ler?

--=20
Timur Tabi
Linux kernel developer at Freescale=

#4 lore raw
Quoted 8 lines · On Wed, Sep 28, 2011 at 08:52:30PM +0000, Tabi Timur-B04825 wrote:
Quoted 2 lines · Grant Likely

The solution is to make the gpio driver register as a regular interrupt handler, and not as a chained handler.

I was wondering about that.

What exactly is a chained handler? How is it different from a regular handler?

A chained handler has an expedited path through the interrupt code for handling it (basically, it skips handling it at the parent controller and passes through to the child, but it cannot handle multiple chained children on a single irq input.

g.

#5 lore raw
Quoted 4 lines · Grant Likely

A chained handler has an expedited path through the interrupt code for handling it (basically, it skips handling it at the parent controller and passes through to the child, but it cannot handle multiple chained children on a single irq input.

So you can't do a shared chained handler? If the chained handler returns=20 IRQ_NONE, the interrupt code just gives up?

Why is it called a "chained" handler? Where's the chain?

I'm trying to understand the core interrupt code, and I can't seem to find= =20
any descriptions of it.

--=20
Timur Tabi
Linux kernel developer at Freescale=

#7 lore raw
In reply to Grant Likely

Hi Grant,

Quoted 7 lines · Grant Likely
Quoted 6 lines · On Wed, Sep 28, 2011 at 08:52:30PM +0000, Tabi Timur-B04825 wrote:
Quoted 2 lines · Grant Likely

The solution is to make the gpio driver register as a regular interrupt handler, and not as a chained handler.

I was wondering about that.

Quoted 8 lines
Quoted 1 line

What exactly is a chained handler? How is it different from a regular handler?

A chained handler has an expedited path through the interrupt code for handling it (basically, it skips handling it at the parent controller and passes through to the child, but it cannot handle multiple chained children on a single irq input.

g.

I may be missing something, but please see this discussion:
http://comments.gmane.org/gmane.linux.ports.arm.kernel/76025

Chained handler is suggested as the solution for very similar problem. (several peripherals sharing the same hardware IRQ line. If it's possible on ARM, it should be doable on powerpc, right ?

Felix.

#6 lore raw
In reply to Tabi Timur-B04825
Quoted 8 lines · On Thu, Sep 29, 2011 at 08:22:06PM +0000, Tabi Timur-B04825 wrote:
Quoted 4 lines · Grant Likely

A chained handler has an expedited path through the interrupt code for handling it (basically, it skips handling it at the parent controller and passes through to the child, but it cannot handle multiple chained children on a single irq input.

So you can't do a shared chained handler? If the chained handler returns IRQ_NONE, the interrupt code just gives up?

No, you can do one or more regular handlers which acks or masks the irq in the upstream controller, or you can do a single chained handler which bypasses any ack/mask. It's an optimization. The code *could* be modified to allow multiple chained handlers, but I cannot comment on if it would be worthwhile.

Basically, a chained handler replaces the regular edge or level irq handler. Take a look at __irq_set_handler(). Chained in this case is really a synonym for a cascaded irq handler. Also, I believe it only really works if the irq is level sensitive because an edge sensitive irq would still need to be acked. It would also need to be an irq controller that can be accessed immediately since it depends on the child controller to ack/mask it's inputs. Something on an i2c bus wouldn't work so well because the irq would remain asserted until after several slow i2c transactions.

g.