cancel
Showing results for 
Search instead for 
Did you mean: 

GPIO Interrupt / EXTI setup in device tree

scotty
Associate II

I have the following DTS file and I have not been able to get the GPIO external interrupt working correctly. I have read this document on interrupt overviews, and tried to enable the EXTI to have control of the GPIOB pin 12.

/dts-v1/;
 
#include "stm32mp157.dtsi"
#include "stm32mp15xa.dtsi"
#include "stm32mp15-pinctrl.dtsi"
#include "stm32mp15xxac-pinctrl.dtsi"
#include "stm32mp15xx-dkx.dtsi"
 
/ {
	model = "STMicroelectronics STM32MP157A-DK1 Discovery Board";
	compatible = "st,stm32mp157a-dk1", "st,stm32mp157";
 
	chosen {
		stdout-path = "serial0:115200n8";
	};
 
 
	button {
		compatible = "test,button";
		input-gpios = <&gpiob 12 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; //Works with pull-up once the driver is loaded. 
		interrupts-extended = <&gpiob 12 IRQ_TYPE_EDGE_FALLING>;
		interrupt-names = "qwerty";
		status = "okay";		
	};
 
	led {
		extern-led {
			compatible = "test,led";
			gpios = <&gpiob 10 GPIO_ACTIVE_HIGH>;
			linux,default-trigger = "cpu";
		};
	};
};

The problem I have is that for all my gpio_to_irq() calls, I get the following:

[   64.996864] platformdev: loading out-of-tree module taints kernel.
[   65.003005] mod_probe() function was called.
[   65.006308] mod_probe got miscdev minor id: 125
[   65.010898] gpio_to_irq(0) = 88
[   65.015773] stm32mp157-pinctrl soc:pin-controller@50002000: irq line 1 already requested.
[   65.022853] gpio_to_irq(1) = -6
[   65.025872] gpio_to_irq(2) = 89
[   65.028910] gpio_to_irq(3) = 90
[   65.032338] gpio_to_irq(4) = 91
[   65.035218] gpio_to_irq(5) = 92
[   65.038271] gpio_to_irq(6) = 93
[   65.041395] stm32mp157-pinctrl soc:pin-controller@50002000: irq line 7 already requested.
[   65.049669] gpio_to_irq(7) = -6
[   65.052846] gpio_to_irq(8) = 94
[   65.055812] gpio_to_irq(9) = 95
[   65.058943] gpio_to_irq(10) = 96
[   65.062249] stm32mp157-pinctrl soc:pin-controller@50002000: irq line 11 already requested.
[   65.070436] gpio_to_irq(11) = -6
[   65.073796] gpio_to_irq(12) = 97
[   65.076859] gpio_to_irq(13) = 98
[   65.080112] gpio_to_irq(14) = 99
[   65.083319] gpio_to_irq(15) = 100
[   65.086619] stm32mp157-pinctrl soc:pin-controller@50002000: irq line 0 already requested.
[   65.094764] gpio_to_irq(16) = -6
[   65.098248] stm32mp157-pinctrl soc:pin-controller@50002000: irq line 1 already requested.
[   65.106281] gpio_to_irq(17) = -6
[   65.109559] stm32mp157-pinctrl soc:pin-controller@50002000: irq line 2 already requested.
[   65.117624] gpio_to_irq(18) = -6
[   65.120821] stm32mp157-pinctrl soc:pin-controller@50002000: irq line 3 already requested.
[   65.128995] gpio_to_irq(19) = -6
[   65.132198] stm32mp157-pinctrl soc:pin-controller@50002000: irq line 4 already requested.
[   65.140258] gpio_to_irq(20) = -6
[   65.143562] stm32mp157-pinctrl soc:pin-controller@50002000: irq line 5 already requested.
[   65.151648] gpio_to_irq(21) = -6
[   65.154987] stm32mp157-pinctrl soc:pin-controller@50002000: irq line 6 already requested.
[   65.163127] gpio_to_irq(22) = -6
[   65.166210] gpio_to_irq(23) = 78
[   65.169463] stm32mp157-pinctrl soc:pin-controller@50002000: irq line 8 already requested.
[   65.177710] gpio_to_irq(24) = -6
[   65.180905] stm32mp157-pinctrl soc:pin-controller@50002000: irq line 9 already requested.
[   65.189071] gpio_to_irq(25) = -6
[   65.192273] stm32mp157-pinctrl soc:pin-controller@50002000: irq line 10 already requested.
[   65.200433] gpio_to_irq(26) = -6
[   65.203808] stm32mp157-pinctrl soc:pin-controller@50002000: irq line 11 already requested.
[   65.212052] gpio_to_irq(27) = -6
[   65.215234] stm32mp157-pinctrl soc:pin-controller@50002000: irq line 12 already requested.
[   65.223441] gpio_to_irq(28) = -6
[   65.226725] stm32mp157-pinctrl soc:pin-controller@50002000: irq line 13 already requested.
[   65.235007] gpio_to_irq(29) = -6
[   65.238204] stm32mp157-pinctrl soc:pin-controller@50002000: irq line 14 already requested.
[   65.246450] gpio_to_irq(30) = -6
[   65.249632] stm32mp157-pinctrl soc:pin-controller@50002000: irq line 15 already requested.
[   65.258245] gpio_to_irq(31) = -6
[   65.261203] stm32mp157-pinctrl soc:pin-controller@50002000: irq line 0 already requested.
[   65.269297] gpio_to_irq(32) = -6
[   65.272615] stm32mp157-pinctrl soc:pin-controller@50002000: irq line 1 already requested.
[   65.280607] gpio_to_irq(33) = -6
[   65.283951] stm32mp157-pinctrl soc:pin-controller@50002000: irq line 2 already requested.
[   65.292116] gpio_to_irq(34) = -6

When I perform the IRQ request for the EXTI pin 12 input, with the gpio_to_irq number, provided above (#97) I get the IRQ, but it is not firing, because I believe the EXTI controller is not properly listening to GPIOB pin 12.

I want to connect to the gpio 28 (GPIOB pin 12), but the interrupt has already been claimed by GPIOA pin 12. So how do I change the EXTI controller to follow what I have defined in the DTS file and listen for GPIOB 12 instead?

I have tried the following DTS edits:

interrupts-extended = <&exti 28 IRQ_TYPE_EDGE_FALLING>;

------

interrupts-extended = <&gpiob 12 IRQ_TYPE_EDGE_FALLING>;

------

interrupt-parent = <&gpiob>;

interrupts = <12 IRQ_TYPE_EDGE_FALLING>;

------

If someone can explain what my DTS file should read I would appreciate it.

EDIT: I have temporarily connected the input pushbutton to the GPIO A12 pin, and the linux interrupt is working as expected, so what is misconfigured such that the EXTI isn't connected to GPIO port B? I cannot use pin A12, and I would much prefer to understand how this peripheral is configured.

1 ACCEPTED SOLUTION

Accepted Solutions
scotty
Associate II

I have fixed the issue, and it's rather subtle. My code was iterating through all the GPIOs from 0-100 and I was looking for a change in the IRQ number to indicate that the IRQ could be used. However, none of that seems necessary. When your driver is probed, when requesting a pin with gpiod_to_irq, the EXTI interface assigns the first pin on the first requested bank to the EXTI interface. So by changing my iteration from 0-100 to 16-32, all of my interrupts are now on port B.

For example, if I want GPIO B12 for a pushbutton, I can call gpiod_to_irq(28), and successive calls to any of the following will return -6 (irq already requested):

gpiod_to_irq(12) // GPIO A12

gpiod_to_irq(44) // GPIO C12

gpiod_to_irq(60) // GPIO D12

...

I am not sure if this can be changed. For example, if I wanted to change this during operation, would I have to request the IRQ, then free the IRQ before calling gpiod_to_irq again for a different bank? I will update if I find out.

View solution in original post

2 REPLIES 2
scotty
Associate II

@OlivierK​ You were knowledgeable on my previous DTS question. Any chance you know why this DTS change isn't being reflected in the EXTI interrupt system?

scotty
Associate II

I have fixed the issue, and it's rather subtle. My code was iterating through all the GPIOs from 0-100 and I was looking for a change in the IRQ number to indicate that the IRQ could be used. However, none of that seems necessary. When your driver is probed, when requesting a pin with gpiod_to_irq, the EXTI interface assigns the first pin on the first requested bank to the EXTI interface. So by changing my iteration from 0-100 to 16-32, all of my interrupts are now on port B.

For example, if I want GPIO B12 for a pushbutton, I can call gpiod_to_irq(28), and successive calls to any of the following will return -6 (irq already requested):

gpiod_to_irq(12) // GPIO A12

gpiod_to_irq(44) // GPIO C12

gpiod_to_irq(60) // GPIO D12

...

I am not sure if this can be changed. For example, if I wanted to change this during operation, would I have to request the IRQ, then free the IRQ before calling gpiod_to_irq again for a different bank? I will update if I find out.