All of lore.kernel.org
 help / color / mirror / Atom feed
* Can't get FIQ interrupt to work on i.mx233
@ 2013-07-16  1:59 Juha Lumme
  2013-07-16  8:11 ` Russell King - ARM Linux
  0 siblings, 1 reply; 6+ messages in thread
From: Juha Lumme @ 2013-07-16  1:59 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

I'm trying to get my head around FIQ's on imx233, with Maxime Ripard's
article at free electrons (
http://free-electrons.com/blog/fiq-handlers-in-the-arm-linux-kernel/ )
as my original inspiration.

Unfortunately, for some reason I'm unable to get similar results on my
board (Olimex olinuxino maxi), even though the cpu is very close to
his (he was using imx28).

Im working with 3.10 kernel (Freescales mainline), and I had to add
some code to drivers/irqchip/irq-mxs.c for mxs_icoll_set_irq_fiq. This
is the code I added:
http://codetidy.com/6195/

Maxime used timer 2 to trigger interrupts in his design, but it seems
that in imx233, timer 0 and 2 are being used by the kernel, so I chose
timer3 for my purpose.
According to the reference manual, the mx233 timer3 uses interrupt 31.

As a first step, I'm now just trying to trigger FIQ once, and in FIQ I
want to acknowledge the interrupt, and set GPIO state high.
My driver code looks like this:
http://codetidy.com/6194/

I have carried over a simple header file from 2.6 kernel, that has
register addresses defined, it can be seen here:
http://codetidy.com/6192/

In the driver I:
1. map memory areas for HW_PINCTRL_DOUT1 (to trigger GPIO)
HW_TIMROT_TIMCTRL3 (to initalize timer3 settings) HW_TIMROT_TIMCOUNT3
(setup the actual timer values) HW_ICOLL_INTERRUPT31 (directly access
interrupt 31 register)
2. Reserve and setup the GPIO 38 as output (the pin I want to
trigger), and initialize the timer3 settings.
3. Claim the FIQ, setup it's assembly handler, and pass mapped memory
pointers of HW_PINCTRL_DOUT1 (to trigger gpio) and HW_TIMROT_TIMCTRL3
(to acknowledge the interrupt bit) to the handler via pt_regs struct.
4. Call mxs_icoll_set_irq_fiq(irq) and enable_fiq(irq) to enable the IRQ/FIQ.

For now the assembly handler is only 6 instructions: http://codetidy.com/6193/
I first want to just clear the interrupt bit in HW_ICOLL_INTERRUPT31,
and then I write 0xFF to HW_PINCTRL_DOUT1

Now when I compile this driver to the kernel, I see during the boot
that driver is initialized, and from the register printouts I can see
that timer3 is initialized as I request.
When I cat /proc/interrupts, I can see that my FIQ handler appears installed:
# cat /proc/interrupts
           CPU0
 16:       2082         -  MXS Timer Tick
 17:          0         -  mxs-spi
 18:       2147         -  mxs-dma
118:          0         -  mxs-spi
119:          0         -  mxs-dma
120:          0         -  RTC alarm
124:          0         -  8006c000.serial
127:         76         -  uart-pl011
128:        258         -  ci13xxx_imx
FIQ:              beagle_fiq_handler
Err:          0

In user space, I made a simple register reading application, and when
I read HW_TIMROT_TIMCOUNT3, I can see that as requested first 16 bits
of the register (fixed count part), is set to 4096 (bit 12), and bits
16-31(running count part) vary all the time, so the timer appears
running.
Also, when I read HW_TIMROT_TIMCTRL3 in userspace, I can see that IRQ
bit (bit 15) is now set, implying that timer3 has decremented to 0.
This bit was not set during the initial driver loading. Now because of
this, I am assuming that my assembly handler is never called, since
the first task is to clear this bit:
lsl r11, r11, #15?
str r11, [r9, #BIT_CLR]

This is basically where I am now, I don't know why my FIQ handler is
never called, even though the IRQ bit is triggered in interrupt 31,
and my handler appears to be created.

I did try to do a bit of debugging in the IRQ setup part, and it seems
that when I call mxs_icoll_set_irq_fiq(31); in the function it calls
__raw_writel(BM_ICOLL_INTERRUPTn_FIQ_ENABLE, icoll_base +
HW_ICOLL_INTERRUPTn_SET(d->hwirq));
Now this d->hwirq is actually a value "8", not "31" as I thought it
should be ? Im not exactly sure though here.
Also enable_fiq(31) will use same irq_desc in kernel/irq/manage.c that
has incorrect (?) value for hwirq.. but, again, I'm not sure this is
the cause.

If in user-space I check the value in HW_ICOLL_INTERRUPT31 I do NOT
see the bit 4 (ENFIQ) set, it actually seems to be 0.
Should the HW_ICOLL_INTERRUPT31 have bits 2 (enable) and 4 (enfiq) set ?

Another difference with Maxime's code is that currently I do not have
definition for my "HW" (gpio pin) and driver in dts file, I have
hardcoded the values for now to the driver.

I wonder what I might be doing wrong now, and where I should look more
closer with this ? I'm a newbie with IRQ's and FIQ's, so please don't
hesitate to confirm even some simple stuff I might have overlooked..
Thank you for any advice,
Juha Lumme

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

* Can't get FIQ interrupt to work on i.mx233
  2013-07-16  1:59 Can't get FIQ interrupt to work on i.mx233 Juha Lumme
@ 2013-07-16  8:11 ` Russell King - ARM Linux
  2013-07-16 11:44   ` Juha Lumme
  0 siblings, 1 reply; 6+ messages in thread
From: Russell King - ARM Linux @ 2013-07-16  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 16, 2013 at 10:59:22AM +0900, Juha Lumme wrote:
> For now the assembly handler is only 6 instructions: http://codetidy.com/6193/
> I first want to just clear the interrupt bit in HW_ICOLL_INTERRUPT31,
> and then I write 0xFF to HW_PINCTRL_DOUT1

Unfortunately, the code doesn't match your description.  You set r10 to
0xff, and then _load_ the value from the address at r8 into r10.

Maybe that ldr r10, [r8] should be str r10, [r8] ?

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

* Can't get FIQ interrupt to work on i.mx233
  2013-07-16  8:11 ` Russell King - ARM Linux
@ 2013-07-16 11:44   ` Juha Lumme
  2013-07-16 16:16     ` Dave Martin
  0 siblings, 1 reply; 6+ messages in thread
From: Juha Lumme @ 2013-07-16 11:44 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Russel,

Thanks for your reply.
And thanks for pointing out the wrong instruction there with the ldr 
instruction.

However, unfortunately the code still doesn't seem to trigger anything 
(neither to clear the IRQ bit in the timer, nor the GPIO output).. It 
seems to me as if the handler never gets called. Is there a good way to 
confirm that any activity is actually triggered when timer3 reaches 0, 
and the IRQ bit is set to 1 ?

Best regards,
Juha

On 07/16/2013 05:11 PM, Russell King - ARM Linux wrote:
> On Tue, Jul 16, 2013 at 10:59:22AM +0900, Juha Lumme wrote:
>> For now the assembly handler is only 6 instructions: http://codetidy.com/6193/
>> I first want to just clear the interrupt bit in HW_ICOLL_INTERRUPT31,
>> and then I write 0xFF to HW_PINCTRL_DOUT1
> Unfortunately, the code doesn't match your description.  You set r10 to
> 0xff, and then _load_ the value from the address at r8 into r10.
>
> Maybe that ldr r10, [r8] should be str r10, [r8] ?

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

* Can't get FIQ interrupt to work on i.mx233
  2013-07-16 11:44   ` Juha Lumme
@ 2013-07-16 16:16     ` Dave Martin
  2013-07-17 13:42       ` Juha Lumme
  0 siblings, 1 reply; 6+ messages in thread
From: Dave Martin @ 2013-07-16 16:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 16, 2013 at 08:44:43PM +0900, Juha Lumme wrote:
> Hi Russel,
> 
> Thanks for your reply.
> And thanks for pointing out the wrong instruction there with the ldr
> instruction.
> 
> However, unfortunately the code still doesn't seem to trigger
> anything (neither to clear the IRQ bit in the timer, nor the GPIO
> output).. It seems to me as if the handler never gets called. Is
> there a good way to confirm that any activity is actually triggered
> when timer3 reaches 0, and the IRQ bit is set to 1 ?
> 

A brutal, but simple, way to confirm that your handler is being called
is to try putting an infinite loop in there:

	b	.

If your board then locks up, the handler is almost certainly getting
called.

Cheers
---Dave

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

* Can't get FIQ interrupt to work on i.mx233
  2013-07-16 16:16     ` Dave Martin
@ 2013-07-17 13:42       ` Juha Lumme
  2013-07-18 14:19         ` Dave Martin
  0 siblings, 1 reply; 6+ messages in thread
From: Juha Lumme @ 2013-07-17 13:42 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Dave,

Thanks for the idea, that's indeed a dead simple way to find out.
Being sure that I will get stuck in FIQ handler, I started experimenting 
different things, and it seems that if instead of calling 
mxs_icoll_set_irq_fiq(31) (which only sets FIQ bit), I directly set bits 
4 (FIQ) and 2 (ENABLE) in HW_ICOLL_INTERRUPT31 register, my interrupt 
starts working as expected. Maybe I can also leave enable_fiq out this way.

So it currently seems like mxs_icoll_set_irq_fiq (which I patched in) 
and enable_fiq (already there) are not working as expected currently in 
freescale's mainline 3.10.
I will try to find out the reason, and create patches for this - but if 
you have any pointers on what might help me on a right path, I would 
appreciate it.

Anyway, thanks for helping me this far already,
Juha

On 07/17/2013 01:16 AM, Dave Martin wrote:
> On Tue, Jul 16, 2013 at 08:44:43PM +0900, Juha Lumme wrote:
>> Hi Russel,
>>
>> Thanks for your reply.
>> And thanks for pointing out the wrong instruction there with the ldr
>> instruction.
>>
>> However, unfortunately the code still doesn't seem to trigger
>> anything (neither to clear the IRQ bit in the timer, nor the GPIO
>> output).. It seems to me as if the handler never gets called. Is
>> there a good way to confirm that any activity is actually triggered
>> when timer3 reaches 0, and the IRQ bit is set to 1 ?
>>
> A brutal, but simple, way to confirm that your handler is being called
> is to try putting an infinite loop in there:
>
> 	b	.
>
> If your board then locks up, the handler is almost certainly getting
> called.
>
> Cheers
> ---Dave

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

* Can't get FIQ interrupt to work on i.mx233
  2013-07-17 13:42       ` Juha Lumme
@ 2013-07-18 14:19         ` Dave Martin
  0 siblings, 0 replies; 6+ messages in thread
From: Dave Martin @ 2013-07-18 14:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 17, 2013 at 10:42:26PM +0900, Juha Lumme wrote:
> Hi Dave,
> 
> Thanks for the idea, that's indeed a dead simple way to find out.
> Being sure that I will get stuck in FIQ handler, I started
> experimenting different things, and it seems that if instead of
> calling mxs_icoll_set_irq_fiq(31) (which only sets FIQ bit), I
> directly set bits 4 (FIQ) and 2 (ENABLE) in HW_ICOLL_INTERRUPT31
> register, my interrupt starts working as expected. Maybe I can also
> leave enable_fiq out this way.
> 
> So it currently seems like mxs_icoll_set_irq_fiq (which I patched
> in) and enable_fiq (already there) are not working as expected
> currently in freescale's mainline 3.10.
> I will try to find out the reason, and create patches for this - but
> if you have any pointers on what might help me on a right path, I
> would appreciate it.

It sounds like you're on the right track -- I can't comment on the
details though, since I'm not familiar with this board.

Cheers
---Dave

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

end of thread, other threads:[~2013-07-18 14:19 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-16  1:59 Can't get FIQ interrupt to work on i.mx233 Juha Lumme
2013-07-16  8:11 ` Russell King - ARM Linux
2013-07-16 11:44   ` Juha Lumme
2013-07-16 16:16     ` Dave Martin
2013-07-17 13:42       ` Juha Lumme
2013-07-18 14:19         ` Dave Martin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.