Cannot get FIQ to work properly on raspberry zero

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

 



  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@xxxxxxxxxxxxxxxxx
https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies



[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