IRQF_TRIGGER on AVR32

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

 



From: Jason Nymble <jason.nymble@xxxxxxxxx>
Date: 2009/10/20
Subject: Re: IRQF_TRIGGER on AVR32
To: kernelnewbies <kernelnewbies@xxxxxxxxxxxx> On 20 Oct 2009, at 3:41 PM, Matze wrote:
From: Jason Nymble <jason.nymble@xxxxxxxxx>
Date: 2009/10/16
Subject: Re: IRQF_TRIGGER on AVR32
To: kernelnewbies <kernelnewbies@xxxxxxxxxxxx>  On 16 Oct 2009, at 11:53 AM, Matze wrote:

Hi all,
I'm implementing a device driver on a custom board with AVR32 (AP7000) and I observed that the isr executes on rising edge and on high state of interrupt pin.
So I tried to request irq like this:
status = request_irq(spiaccel->irq, accel_interrupt, IRQF_TRIGGER_RISING|IRQF_DISABLED, "accel-driver", spiaccel);
but it does not seem to have any effect on the behaviour on calling isr.
Is there another place, where the trigger is set globaly?
Is there any possibility to determine inside the isr in which trigger event it has been executed?
Regards,
Matthias
I'm not familiar with that exact platform, but have done Linux kernel
work on other atmel chips. There is generally a status register
(containing some bits corresponding to interrupt flags) you need to
read, and an interrupt mask register (which has mask bits
corresponding to the interrupts which are actually enabled). You then
do a bitwise AND on the two to determine which bit/s caused the
interrupt. In some cases reading the status register is enough to
clear that particular interrupt on the processor (e.g. bits which are
of the form "indicates event x happened since last time status was
read"), in other case you need to resolve some sort of scenario to
clear the interrupt status (e.g. setup a new peripheral dma controller
register to point to a dma buffer). If you do not clear the interrupt
condition inside the handler, the handler will be called again
immediately (possibly causing a softlockup), so if there is some
scenario in which you cannot clear the condition you need to disable
that interrupt. Hope some of this rambling helps, even though it
doesn't directly answer your question. AFAIK, you cannot change the
way the interrupt is triggered in the request_irq(), you need to do
that in a processor-specific way using control registers (I might be
wrong about this).

Hi Jason,
thanks for your advices, but I assume reading the registers only makes sense if your interrupt is bound to an external-interrupt pin of your processor (PB26 to 28 in my case). Right?
In my case I you as gpio for triggering the interrupt, so I can't use the register:
/proc # cat interrupts
        CPU0
0:         51      intc  avr32_comparator
2:       1230      intc  dmaca
3:     845357      intc  atmel_spi.0
4:      25558      intc  atmel_spi.1
5:          0      intc  twi
6:       3032      intc  ttyS0
22:     812339      intc  tc_clkevt
25:      18490      intc  eth0
28:     118296      intc  mmci
31:          0      intc  atmel_usba_udc
115:          0      gpio  atmel_mci
145:      25389      gpio  accel-driver <-- the interrupt mentioned
154:        730      gpio  nanoloc-driver
I tried to read through the kernel source code to understand how triggers are configured (2.6.25.10):
in kernel/irq/manage.c
request_irq -> calls:
setup_irq -> checks if IRQF_TRIGGER flags are set and calls:
set_type -> callback routine of the intc, which I wasn't able to locate inside the source tree...
can anyone give me a hint, how a gpio-interrupt will be registered inside the kernel code?
I realized, that interrupt handling code changed quiet a lot in newer kernel version (2.6.31). Does anybody know if it's possible to use the IRQF_TRIGGER flags for gpio-interrupts in there?
Best regards,
Matthias

AFAIK, you need to just read the GPIO pin to clear the interrupt
condition, so this doesn't only apply to the external interrupt pins.
Also, if your ARM also has an AIC (advanced interrupt controller), you
can program that to decide between edge and level triggered.

For clarification:
I have a sensor which triggers irq-line high in a fixed interval. After that I have to read several registers to clear the interrupt in the sensor. But if I don't do that, the interrupt line will stay high all the time. But after reading the pin input with (gpio_get_value()) I realize that I get the first interrupt with irq line set to low and the second with irq line set to high. It seems that reading the GPIO doesn't clear the interrupt inside the kernel, as I still just get 2 interrupts (when I don't clear the irq reading the sensor registers).
Regards,
Matthias

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux