Colibri PXA 270 GPIO / Interrupts / long, sorry!

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


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

[Linux ARM]     [Linux ARM MSM]     [Linux ARM Kernel]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

Add to Google Follow linuxarm on Twitter