Hello List,
I have asked this before on several mailing lists, but still no solution,
so I am trying again here.

I'm having trouble with using FIQ interrupts with the ARM timer on raspberypi 
zero, (BCM2835 chip).
I created a kernel module, and the test version of this driver can be found in

  
https://github.com/SietseAchterop/Batradio/blob/master/batradio_module/fiqtest_4.c

I made sure that FIQ is not used by USB by adding
   dwc_otg.fiq_fsm_enable=0 dwc_otg.fiq_enable=0 dwc_otg.nak_holdoff=0
to cmdline.txt in /boot

I first tried to use the regular sequence of functions to use.
In the init function:
  claim_fiq, set_fiq_regs, enable_fiq
In the exit function
  disable_fiq, release_fiq.

But I cannot find which irq number to use, e.g. using irq_of_parse_and_map
I tried several values. 0, 64, but nothing works.
So instead of the enable/disable functions I directly set the timer interrupt 
via the IRQFIQ register.

This works; a bit.
The fiq_handler only resets the ARM timer, increments a timer and toggles a LED.
I see the timer counting, the fiq being called.
But the rpi fairly quickly crashes.
In the, sometimes, 10 seconds that it runs I see the led flashing very 
irregular.

What is wrong here?
Has the irregularity something to do with suspend/resume?
Please find below the relevant snippets from the init and exit function of the 
driver.
And also the fiq_handler.

   Thanks in advance,
       Sietse

====== init_bat
      .....
  // directly set ARM timer registers
  TIMCNTR = 0x0000000;   // stop timer
  TIMLOAD = 100000-1;    // load value
  TIMCINT = 0;           // clear interrupt

  ret = claim_fiq(&bat_fh);
  if (ret) {
    printk("batradio: claim_fiq failed.\n");
    return ret;
  }
set_fiq_handler(&batradio_handler, &batradio_handler_end - &batradio_handler);

  regs.ARM_r8  = (long)gpiospi;
  regs.ARM_r9  = (long)irqtimer;
  regs.ARM_r10 = (long)0;
  set_fiq_regs(&regs);

  TIMCNTR = 0x000000A2;   // start timer with interrupt, 23 bit counter
  IRQFIQ = 0xC0;          // timer interrupt to fiq directly via register
  //enable_fiq(64);
      ....

======  exit_bat
        ....
  IRQFIQ  = 0x00;         // stop fiq interrupts
  TIMCNTR = 0x003E0000;   // stop ARM timer
  //disable_fiq(64);
        ....
        
======  batradio fiq handler
        .text
        .global batradio_handler
        .global batradio_handler_end

batradio_handler:
        stmdb sp!, {r6-r7}
        mov  r6, #0
        str r6, [r9, #0x40C]    // TIMCINT = 0 // clear interrupt

        mov r7, #0x2000         // 1 << CNVST
        add r10, r10, #1
        ands r6, r10, #0x0001   // set toggle speed
        bne off
        str r7, [r8, #40]       // led on
        ldmia sp!, {r6-r7}
        subs pc, lr, #4
off:    str r7, [r8, #28]       // led off
        ldmia sp!, {r6-r7}
        subs pc, lr, #4
batradio_handler_end:

_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@kernelnewbies.org
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

Reply via email to