Kernel Newbies archive on
 help / color / Atom feed
* Cannot get FIQ to work properly on raspberry zero
@ 2020-06-17 13:03 Sietse Achterop
  0 siblings, 0 replies; only message in thread
From: Sietse Achterop @ 2020-06-17 13:03 UTC (permalink / raw)
  To: kernelnewbies

   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

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,

====== 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;

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

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

	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

Kernelnewbies mailing list

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, back to index

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-17 13:03 Cannot get FIQ to work properly on raspberry zero Sietse Achterop

Kernel Newbies archive on

Archives are clonable:
	git clone --mirror kernelnewbies/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 kernelnewbies kernelnewbies/ \
	public-inbox-index kernelnewbies

Example config snippet for mirrors

Newsgroup available over NNTP:

AGPL code for this site: git clone