Re: question on generic gpio interface

From: David Brownell
Date: Fri Apr 13 2007 - 18:44:05 EST


On Friday 13 April 2007 1:51 pm, Francis Moreau wrote:
> Hi,
>
> I'm trying to port my old gpio code to the generic one to see if it
> can fit my needs.

Good .. this is more like an IRQ question though.


> The gpio controller is a home made one and has a really weird
> interface. It has several registers to read the gpio status, to
> configure gpio directions, or to configure if a gpio can trigger an
> interrupt and on which event (level or edge). All gpios use the same
> IRQ and a gpio controller register allows to read which gpio has
> triggered the interrupt.

I'll trust you on "weird", but that sounds quite typical in
terms of functionality. You'll find that most system-on-chip
GPIO controllers act the same way.

IRQ logic on that platform must do a few things, like:

- NR_IRQS includes the N interrupts triggered from that chip,
and their numbers probably fit right sometimes after the
core set of IRQs (which might include SOC GPIO irqs);

- You'll provide an irq_chip for this controller, and it will
handle the relevant irq operations (set trigger type, mask,
unmask etc);

- When configuring the IRQ handler for that "same IRQ", you'll
set it up to use a chained handler that you provide, which
reads the register to see which gpio(s) triggered the IRQ,
maybe acks it (if just reading that register isn't enough),
and then calls whatever handler was instaled for that GPIO.

If that's not familiar to you, look at arch/arm/mach-at91/gpio.c
or arch/arm/mach-pxa/irq.c or arch/arm/plat-omap/gpio.c or a
number of other similar files showing how the "toplevel" IRQ
logic will demux from a "one of these N GPIOs" interrupt down
to the handler for that particular IRQ.


> Now the question is how should irq_to_gpio() work ?

Normally irq_to_gpio() and gpio_to_irq() are simple arithmetic
operations. If both identifiers start at zero, irq_to_gpio()
would probably subtract a constant, and gpio_to_irq() would add
the same constant.


> Is it supposed to be called only when a gpio interrupt occure ?

It's not the most commonly used operation, and exactly when
it's used would be the choice of whatever code uses it. That
would be one common answer ... e.g. for GPIOs that only allow
"both edges" triggering, the driver may actually care about the
level so it's got to check that with gpio_get_value().

If the IRQ handler doesn't like the notion of subtracting that
constant at that time, it's easy to cache the answer ahead of
time. (Though it might not be a net win to spend extra memory
that way.)


> Another question is how can I specify if a gpio interrupt trigger on
> level or on edge ?

That's handled in the irq_chip.set_type() method. See the above
referenced source files for examples.

- Dave


> thanks
> --
> Francis
>
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/