linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* Does gpio_to_irq() work for MPC52xx gpios?
@ 2009-12-22 20:40 Bill Gatliff
  2009-12-22 21:00 ` Peter Korsgaard
  0 siblings, 1 reply; 7+ messages in thread
From: Bill Gatliff @ 2009-12-22 20:40 UTC (permalink / raw)
  To: Linux/PPC Development

Guys:


Is it possible to specify an individual GPIO pin as an interrupt source
with the current MPC52xx code?

I don't see anything in mpc52xx_gpio.c that registers an interrupt
handler, which I think would be a necessary step towards demultiplexing
the GPIO interrupt event.  So I'm thinking that code to allow me to
register an interrupt handler for a specific GPIO pin just isn't there...


b.g.

-- 
Bill Gatliff
bgat@billgatliff.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Does gpio_to_irq() work for MPC52xx gpios?
  2009-12-22 20:40 Does gpio_to_irq() work for MPC52xx gpios? Bill Gatliff
@ 2009-12-22 21:00 ` Peter Korsgaard
  2009-12-23 16:47   ` Bill Gatliff
  2009-12-30  6:27   ` Bill Gatliff
  0 siblings, 2 replies; 7+ messages in thread
From: Peter Korsgaard @ 2009-12-22 21:00 UTC (permalink / raw)
  To: Bill Gatliff; +Cc: Linux/PPC Development

>>>>> "Bill" == Bill Gatliff <bgat@billgatliff.com> 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/

-- 
Bye, Peter Korsgaard

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Does gpio_to_irq() work for MPC52xx gpios?
  2009-12-22 21:00 ` Peter Korsgaard
@ 2009-12-23 16:47   ` Bill Gatliff
  2009-12-23 20:39     ` Bill Gatliff
  2009-12-30  6:27   ` Bill Gatliff
  1 sibling, 1 reply; 7+ messages in thread
From: Bill Gatliff @ 2009-12-23 16:47 UTC (permalink / raw)
  To: Peter Korsgaard; +Cc: Linux/PPC Development

Peter Korsgaard wrote:
>
> 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.  I'm taking a look at that code now, planning to adapt it for the
MPC52xx unless someone raises any objections.


b.g.

-- 
Bill Gatliff
bgat@billgatliff.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Does gpio_to_irq() work for MPC52xx gpios?
  2009-12-23 16:47   ` Bill Gatliff
@ 2009-12-23 20:39     ` Bill Gatliff
  2009-12-24  5:38       ` Bill Gatliff
  0 siblings, 1 reply; 7+ messages in thread
From: Bill Gatliff @ 2009-12-23 20:39 UTC (permalink / raw)
  To: Peter Korsgaard; +Cc: Linux/PPC Development

Bill Gatliff wrote:
> Peter Korsgaard wrote:
>   
>> 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.  I'm taking a look at that code now, planning to adapt it for the
> MPC52xx unless someone raises any objections.
>   

Ok, working on this now.  I'm pretty far along, but I'm stopped at what
I think is a device tree source file problem.

I have an external device that generates two interrupt outputs.  One of
them is connected to IRQ2, the other to GPIO_WKUP_7.  I'm describing the
device like this:

    ...
    soc5200@f0000000 {
        #address-cells = <1>;
        #size-cells = <1>;
        compatible = "fsl,mpc5200b-immr","simple-bus";
        ranges = <0 0xf0000000 0x0000c000>;
        reg = <0xf0000000 0x00000100>;
        bus-frequency = <0>;        // from bootloader
        system-frequency = <0>;        // from bootloader
    ...
        mpc5200_pic: interrupt-controller@500 {
            // 5200 interrupts are encoded into two levels;
            interrupt-controller;
            gpio-controller;
            #interrupt-cells = <3>;
            #address-cells = <0>;
            #size-cells = <0>;
            compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic";
            reg = <0x500 0x80>;
            interrupts = < 0 0 3  1 1 3  2 2 2  3 3 2 >;
        };
        gpio_wkup: gpio@c00 {
            compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup";
            #gpio-cells = <2>;
            #interrupt-cells = <2>;
            #address-cells = <0>;
            #size-cells = <0>;
            reg = <0xc00 0x40>;
            interrupts = <1 8 0  0 3 0>;
            interrupt-parent = <&mpc5200_pic>;
            gpio-controller;
            interrupt-controller;
        };
    ...
    };
    ...
    system {
        compatible = "simple-bus";

        rotary-encoder {
            compatible = "linux,rotary-encoder","rotary-encoder";
            interrupts = <&mpc5200_pic 2 3  &gpio_wkup 0 0>;
            //interrupts = <&mpc5200_pic 2 3>;
            //gpios = <&gpio_wkup 0 0>;
            type = <1>;
            val-ccw = <0x4a>;
            val-cw = <78>;
        };
    };

When I use the "gpios" property instead of the above, I get a useful
gpio number and I can see the signal using sys/class/gpio.  And I also
know the hardware is working because an ancient, pre-device-tree kernel
is working fine.  :)

The problem is that I'm not getting a valid number out for the second
interrupt specification, presumably because the dts compiler doesn't
have any idea how to generate the data--- and I have no idea how to fix
that.

I captured some dmesg information which shows the problem.  The first
line is for IRQ2, which is correct.  The second is for GPIO_WKUP_7,
which the kernel chokes on:

...
irq: irq_create_mapping(0xcf814000,
0x42)                                         
irq: -> using host
@cf814000                                                      
  alloc irq_desc for 66 on node
0                                                 
  alloc kstat_irqs on node
0                                                      
mpc52xx_irqhost_map: External IRQ2 virq=42, hw=42.
type=8                         
irq: irq 66 on host /soc5200@f0000000/interrupt-controller@500 mapped to
virtual irq
66                                                                              

mpc52xx_extirq_set_type: irq=42. l2=2
flow_type=8                                 
linux,rotary-encoder rotary-encoder.3: irq[0] 66 gpio[0] -2  <- my
driver's output, the "magic number" was 66
return 0, l1=4,
l2=0                                                              
irq: irq_create_mapping(0xcf814000,
0x0)                                          
irq: -> using host
@cf814000                                                      
  alloc irq_desc for 16 on node
0                                                 
  alloc kstat_irqs on node
0                                                      
mpc52xx_irqhost_map: External IRQ0 virq=10, hw=0.
type=8                          
irq: irq 0 on host /soc5200@f0000000/interrupt-controller@500 mapped to
virtual irq
16                                                                               

mpc52xx_extirq_set_type: irq=0. l2=0
flow_type=8                                  
linux,rotary-encoder rotary-encoder.3: irq[1] 16 gpio[1] -2         <-
my driver's "magic number" was 16
...


The device tree has the magic number "66" for IRQ2, which
mpc52xx_irqhost_map gets right.  But it doesn't know what to do with the
magic number "16" that's fed to it from the other interrupt
specification.  And I don't yet, either...  :)

Any ideas?  Basically, what I think this boils down to is somewhere I
need to translate that 16 to yet another virtual number for the
demultiplexed interrupt descriptor.  But I'm getting a little lost in
the virtual-ness of everything!


b.g.

-- 
Bill Gatliff
bgat@billgatliff.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Does gpio_to_irq() work for MPC52xx gpios?
  2009-12-23 20:39     ` Bill Gatliff
@ 2009-12-24  5:38       ` Bill Gatliff
  2009-12-24  6:52         ` Bill Gatliff
  0 siblings, 1 reply; 7+ messages in thread
From: Bill Gatliff @ 2009-12-24  5:38 UTC (permalink / raw)
  To: Peter Korsgaard; +Cc: Linux/PPC Development

Guys:


Ok, I have gpio_to_irq() more-or-less showing signs of life for the
MPC5200.  But I'm having some trouble using it the way I want to.

Recall that I have a rotary encoder that's tied to IRQ2 and
GPIO_WKUP_7.  I want to be able to describe it something like this:

    rotary-encoder {
        compatible = "linux,rotary-encoder","rotary-encoder";
        interrupts = <&mpc5200_pic 2 3 &gpio_wkup 0 1>; // "IRQ2 on the
MPC5200 PIC,
                                                                                               
// and pin 0 on GPIO_WKUP"
        type = <1>; // what event signal to generate
        val-ccw = <0x4a>; // what code to use for counter-clockwise rotation
        val-cw = <78>; // what code to use for clockwise rotation
    };

I've had some limited success with this, but not for any good reason. 
It turns out that the explanation for why I was getting a valid number
for the first interrupt specification was because the device tree
compiler was assuming that the interrupt-parent was the mpc5200_pic; my
reference to the node in that list was utterly meaningless.  The dtc
also appears to have ignored the &gpio_wkup word, and interpreted the
following zero as being the zero-th interrupt channel in the
mpc5200_pic.  Or something like that.  Clearly, I don't understand the
device tree syntax at all yet.

Anyway, when I change the statement to this:

    rotary-encoder {
        compatible = "linux,rotary-encoder","rotary-encoder";
        interrupt-parent = <&gpio_wkup>;
        interrupts = <0 0>;
        type = <1>;
        val-ccw = <0x4a>;
        val-cw = <78>;
        };

... then the magic number that the dtc comes up with is causing my new
chained interrupt handler for the gpio_wkup peripheral to come alive. 
(Of course it doesn't actually work yet, but that's not the point!)

So here's my question: does the device tree compiler/syntax limit you to
only one interrupt parent?

I think the answer is no, because what I'm trying to do doesn't seem
that much different from how one specifies GPIO pins coming from
different controllers.

Any suggestions?


b.g.

-- 
Bill Gatliff
bgat@billgatliff.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Does gpio_to_irq() work for MPC52xx gpios?
  2009-12-24  5:38       ` Bill Gatliff
@ 2009-12-24  6:52         ` Bill Gatliff
  0 siblings, 0 replies; 7+ messages in thread
From: Bill Gatliff @ 2009-12-24  6:52 UTC (permalink / raw)
  To: Peter Korsgaard; +Cc: Linux/PPC Development

Bill Gatliff wrote:
> Guys:
>
>
> Ok, I have gpio_to_irq() more-or-less showing signs of life for the
> MPC5200.  But I'm having some trouble using it the way I want to.
>   

I think I've got the idea all of a sudden.

In order to describe the inputs to my rotary encoder using the syntax I
want, I have to implement something similar to of_get_gpio_flags(), right?


b.g.

-- 
Bill Gatliff
bgat@billgatliff.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Does gpio_to_irq() work for MPC52xx gpios?
  2009-12-22 21:00 ` Peter Korsgaard
  2009-12-23 16:47   ` Bill Gatliff
@ 2009-12-30  6:27   ` Bill Gatliff
  1 sibling, 0 replies; 7+ messages in thread
From: Bill Gatliff @ 2009-12-30  6:27 UTC (permalink / raw)
  To: Peter Korsgaard; +Cc: Linux/PPC Development

Peter Korsgaard wrote:
>>>>>> "Bill" == Bill Gatliff <bgat@billgatliff.com> 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
bgat@billgatliff.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2009-12-30  6:27 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-12-22 20:40 Does gpio_to_irq() work for MPC52xx gpios? Bill Gatliff
2009-12-22 21:00 ` Peter Korsgaard
2009-12-23 16:47   ` Bill Gatliff
2009-12-23 20:39     ` Bill Gatliff
2009-12-24  5:38       ` Bill Gatliff
2009-12-24  6:52         ` Bill Gatliff
2009-12-30  6:27   ` Bill Gatliff

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).