Colibri PXA 270 GPIO / Interrupts / long, sorry!

Steve Letter <[email protected]>
Newsgroups gmane.linux.ports.arm.general
Message-ID <[email protected]>
I'm having trouble with how to set up and use GPIO interrupts.  We have devices connected via the SPI bus.  The driver for the bus is not suitable for the application.  I use it to configure the devices, which then stream data through the bus.

I am using kernel 2.6.26.  I have set up the SPI device, it works just fine.  I am having the "first" device on the bus generate an interrupt, using the GPIO interrupts.  I do this for 2 of the three buses.  I have a thread waiting on the interrupt, which simply disables further interrupts, and wakes up a thread that reads off the data (directly from the SPI registers).  Since the MISO generates the interrupt and also carries the data, I have to disable the interrupt.  Once the thread is done reading, it re-enables the interrupt and waits for the next wake up.

Here is what I am doing.  First my startup (in my open()).  All code is simplified or pseudocode.

irq = gpio_to_irq(gpio_num);
status = request_irq(irq, irq_handler, 
        IRQF_TRIGGER_FALLING | IRQF_DISABLED,
        "SPI Interrupt", &control);
disable_irq(irq);

My kernel thread runs to the end (past the wait the first time) where it enables the interrupt.  It passes the wait because a condition variable is set.  The wait looks pretty standard.

Pseudocode looks like:

lock;
while test condition unset {
        unlock
        wait for condition to set
        lock
}

At the end, I unset the condition and enable the interrupt.

set condition
enable_irq(irq);


The interrupt sets the condition and wakes up the wait.

My problem is that disable_irq()  seems to have no effect.  I'm not sure what I am doing wrong.  I can get the code working if I go directly to the GPIO registers but I know that is not the way I should be doing it.  Am I mixing interfaces or something?

Going direct looks like GFER(gpio_num) = GFER(gpio_num) | (1 << (gpio_num % 32));  to enable and
GFER(gpio_num) = GFER(gpio_num) & ~(1 << (gpio_num % 32)); to disable.

Sorry if this seems like a newbie issue, I am new to this particular SOC and still haven't quite "got it".

I'm also having difficulty writing out the SPI bus too.  No problems reading from it though.  I simply write to the data register but it never SEEMS to arrive off the bus onto the device.

I appreciate any suggestions, RFTM suggestions or otherwise.  Pointers to any good documentation appreciated also.

 Steve Letter



      


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm
FAQ:        http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette:  http://www.arm.linux.org.uk/mailinglists/etiquette.php
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.