Subject: Re: Does gpio_to_irq() work for MPC52xx gpios?

From: Bill Gatliff <[email-masked]>
Date: Wed, 30 Dec 2009 00:27:16 -0600

Peter Korsgaard wrote:
>>>>>> "Bill" == Bill Gatliff <[email-masked]> writes:
>>>>>>             
>
>  Bill> Guys:
>  Bill> Is it possible to specify an individual GPIO pin as an interrupt source
>  Bill> with the current MPC52xx code?
>
> No (not yet). In Ben's latest pull request there's a patch from me to
> add basic infrastructure for gpio_to_irq(). I've recently added irq
> support to the mpc8xxx driver, but so far nothing has been written for
> 52xx.
>
> http://patchwork.ozlabs.org/patch/41550/
>   

Ok, after looking at your code for a few days I'm even more lost than
when I started!

On the MPC5200, all the GPIO_WKUP pins are multiplexed into a single
interrupt line, which is Main_Mask8. As currently defined by
mpc52xx_pic.c, that's a virtual interrupt number of 72. So generally
speaking, if I do a request_irq() on 72, I'll get an interrupt any time
an enabled GPIO_WKUP pin changes state.

What I want to be able to do is a request_irq(gpio_to_irq(GPIO_WKUP_7),
...), so that I can have a single interrupt handler for each GPIO_WKUP
pin. To do this, I think the general idea is as follows:

1. create a virtual interrupt number for each GPIO_WKUP line
2. install a chained interrupt handler on interrupt 72
3. inside the chained handler, map each active GPIO_WKUP pin to its
associated virtual interrupt number, and invoke the associated interrupt
handler by passing that virtual interrupt number to generic_handle_irq()
4. provide a gpio_to_irq that can map GPIO offsets to their associated
virtual interrupt numbers

I'm trying to implement the above, but I'm getting lost in all the IRQ
mapping and virtualization. Can someone show me what I'm doing wrong in
my code?

I've put a complete copy of my modified mpc52xx_gpio.c on pastebin, with
my portions highlighted:

http://pastebin.com/f4c074ab8

A kernel message buffer log is here, also with the interesting lines
highlighted:

http://pastebin.com/f378d3c61

I get a mapping from hwirq 72 to a virq of 16. That seems fine. But
that's the extent of the good news. :)

The two GPIO pins I'm interested in are 222 and 223, which are
GPIO_WKUP_6 and GPIO_WKUP_7. In my gpio_to_irq() I'm doing this:

static int mpc52xx_wkup_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
{
struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
struct mpc52xx_gpiochip *c = to_mpc52xx_gpiochip(mm);

pr_err("%s mapping offset %d\n", __func__, offset);

if (c->irqhost && offset < MPC52XX_WKUP_GPIO_PINS)
return irq_create_mapping(c->irqhost, c->irq);
return -ENXIO;
}

That's not giving me what I want, it's just creating another mapping to
virtual irq 16. I know that code is wrong, I just don't know what the
right code should be...

Help, I'm lost! :)

Kindest regards,

b.g.

-- 
Bill Gatliff
Embedded systems training and consulting
http://billgatliff.com
[email-masked]