Linux on the LS1046a: how do I make IRQ00..IRQ02 active low?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Linux on the LS1046a: how do I make IRQ00..IRQ02 active low?

Jump to solution
778 Views
AbelianMeme
Contributor III

We have a custom board using the LS1046a.  We have several devices connected to the dedicated IRQ lines that are level triggered, active low.

We are using the Linux 5.4 version of the LSDK.  The problem is that when I try to enable the IRQ I get the following error:

genirq: Setting trigger mode 8 for irq 72 failed (gic_set_type+0x0/0xb0)

(I have no idea how it calculated 72 in this error message, the LS1046a internal interrupt is actually 163, but let's ignore that)

Upon examining the Linux source code (gic_set_type in irq-gic.c) I see the following code at or around line 302:

	/* SPIs have restrictions on the supported types */
	if (gicirq >= 32 && type != IRQ_TYPE_LEVEL_HIGH &&
			    type != IRQ_TYPE_EDGE_RISING) 
		return -EINVAL;

 

SPI in this case means "Shared Processor Interrupt" (from the ARM GIC manual...I had to look up what it meant), but I can not find any restriction in the ARM manual about limits in supported types. It specifically talks about level sensitive interrupts which may be active high or active low. So I have no idea where this restriction is coming from. Can anyone point me to a document that explains the origin of this?

Moving on, I notice that in the LS1046A Reference Manual, section 11.3.28 on p. 421, it defines the following register:

11.3.28 Interrupt Polarity Register (SCFG_INTPCR)

IRQ0INTP    0: IRQ0 is active high 1: IRQ0 is active low

IRQ1INTP    0: IRQ1 is active high 1: IRQ1 is active low

etc...

I assume, if I am going to make this work, that I need to setup this register appropriately through PBI commands. This is fine by itself, but what EXACTLY does this register do?  Does it actually invert the signal before passing it to the GIC, implying I should declare the interrupt as active high and use the existing irq-gic driver?  Or does it just change the pullups so that the silicon behaves properly?

And in that case, is there a custom driver I should be using for interrupts rather than the Linux default irq-gic?

Or can I simply comment out the lines above and expect everything to work properly?

Here is the relevant part of the DTS tree where I create one of the external active low nodes:

&i2c2 {
	status = "okay";
	dma-coherent;

	rv3028: rtc@52 {
		compatible = "microcrystal,rv3028";
		reg = <0x52>;
		status = "okay";
		interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_LOW>;
	};
};

 

Is there any example code which shows how to configure this so it works properly for active low external IRQ lines?

 

If anyone understands this issue and can give me some guidance on how to proceed, I would appreciate the assist. (Sidenote: we have severely customized this kernel and really, strongly do not want to change versions. Maybe when we are ready to release v2.0 of the product, but not now.)

Thanks in advance for sharing your wisdom.

 

 

0 Kudos
1 Solution
738 Views
stadium_aquino
Contributor IV

You need to use the fsl,ls1046a-extirq driver. In my device tree I do

		interrupts-extended = <&extirq 2 IRQ_TYPE_LEVEL_LOW>;

 

View solution in original post

0 Kudos
3 Replies
739 Views
stadium_aquino
Contributor IV

You need to use the fsl,ls1046a-extirq driver. In my device tree I do

		interrupts-extended = <&extirq 2 IRQ_TYPE_LEVEL_LOW>;

 

0 Kudos
732 Views
AbelianMeme
Contributor III

Thanks.

My kernel didn't include this driver, but I found it online and was able to backport it into my kernel.

 

0 Kudos
758 Views
yipingwang
NXP TechSupport
NXP TechSupport

SPIs interrupt only support low-to-high rising edge triggered and active high triggered.
You can check this in "linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml"

bits[3:0] trigger type and level flags.
1 = low-to-high edge triggered
2 = high-to-low edge triggered (invalid for SPIs)
4 = active high level-sensitive
8 = active low level-sensitive (invalid for SPIs).

You can also find some description about it in ARM GIC document:
"SPIs...., You can configure whether each SPI is triggered on a rising edge or is active-HIGH level-sensitive."

For customers who design their boards only support active-low interrupt, they can configure the interrupt PIN to GPIO mode and active low is supported by GPIO. interrupt.

0 Kudos