I am then stuck with needing a gpio that I can use as an interrupt that can also have its cpu affinity changed. From the freescale imx6 documentation it list several gpio interrupts within the 255 limit. See this previous post for info on why I want a interrupt below 255: https://community.freescale.com/thread/301130.
*** In the below I am referencing Rev. 0, 11/2012 of the i.MX 6Dual/6Quad Applications Processor Reference Manual.
I can not find any indication in either the interrupt or the GPIO chapter how the GPIO1 is configured to deliver these interrupts.
Here is a table for the reference manual that shows the IRQ number and source. However it lists the source as just GPIO1. I am not sure what GPIO in GPIO1 maps to which INT0-7. For example does GPIO1_1 map to INT1? It is also possible I just don't understand how the gpio's work with the interrupts in general. There seems very little information about this subject in the documentation.
---------------------------------------------
Table 3-1.
.
.
90 GPIO1 INT7 interrupt request.
91 GPIO1 INT6 interrupt request.
92 GPIO1 INT5 interrupt request.
93 GPIO1 INT4 interrupt request.
94 GPIO1 INT3 interrupt request.
95 GPIO1 INT2 interrupt request.
96 GPIO1 INT1 interrupt request.
97 GPIO1 INT0 interrupt request.
.
.
---------------------------------------------
I also see that in mx6.h I have the following. Which matches up with documentation.
#define MXC_INT_GPIO1_INT7_NUM | 90 | |
#define MXC_INT_GPIO1_INT6_NUM | 91 | |
#define MXC_INT_GPIO1_INT5_NUM | 92 | |
#define MXC_INT_GPIO1_INT4_NUM | 93 | |
#define MXC_INT_GPIO1_INT3_NUM | 94 | |
#define MXC_INT_GPIO1_INT2_NUM | 95 | |
#define MXC_INT_GPIO1_INT1_NUM | 96 | |
#define MXC_INT_GPIO1_INT0_NUM | 97 | |
#define MXC_INT_GPIO1_INT15_0_NUM | 98 | |
#define MXC_INT_GPIO1_INT31_16_NUM | 99 | |
#define MXC_INT_GPIO2_INT15_0_NUM | 100 | |
#define MXC_INT_GPIO2_INT31_16_NUM | 101 | |
#define MXC_INT_GPIO3_INT15_0_NUM | 102 | |
#define MXC_INT_GPIO3_INT31_16_NUM | 103 | |
#define MXC_INT_GPIO4_INT15_0_NUM | 104 | |
#define MXC_INT_GPIO4_INT31_16_NUM | 105 | |
#define MXC_INT_GPIO5_INT15_0_NUM | 106 | |
#define MXC_INT_GPIO5_INT31_16_NUM | 107 | |
#define MXC_INT_GPIO6_INT15_0_NUM | 108 | |
#define MXC_INT_GPIO6_INT31_16_NUM | 109 | |
#define MXC_INT_GPIO7_INT15_0_NUM | 110 | |
#define MXC_INT_GPIO7_INT31_16_NUM | 111 |
The manual also has this tidbit about how the GPIO's and Interrupts work. However I not sure I gain any more insight.
---------------------------------------------
28.2 General Overview
.
.
Each GPIO input has a dedicated edge-detect circuit which can be configured through
software to detect rising edges, falling edges, logic low-levels or logic high-levels on the
input signals. The outputs of the edge detect circuits are optionally masked by setting the
corresponding bit in the interrupt mask register (GPIO_IMR). These qualified outputs are
OR'ed together to generate two one-bit interrupt lines:
• Combined interrupt indication for GPIOx signals 0 - 15
• Combined interrupt indication for GPIOx signals 16 - 31
In addition, GPIO1 provides visibility to each of its 8 low order interrupt sources (i.e.
GPIO1 interrupt n, for n = 0 – 7). However, individual interrupt indications from other
GPIOx are not available.
---------------------------------------------
The last paragraph is the most helpful (in bold) but it doesn't seem to say anything different then table 3-1 except that it kinda seems to indicate a 0-0, 1-1 mapping but not sure.
I have a driver with a "normal" interrupt working already. The problem is that these interrupts are registered outside of the irq 255 limit for moving to different cores.
I have a driver registering irq 92 (GPIO1 INT5) but the system does not ever raise this interrupt when I trigger GPIO1_5. I also tried registering both irq 92 and the "normal" GPIO1_5 interrupt (irq number 292) with the same result.
Is there somewhere I can get more information or does someone have examples on how to use these gpio irqs?
thanks,
Ben Anderson
Solved! Go to Solution.
Ben,
Kevin Anderle has asked me to take a look at this question. We are very sorry for the delay!
This is my understanding of how the MX6Q GPIO interrupts work:
a) GPIO1 (32 pins) through GPIO7 (32 pins) can be configured to generate interrupts when the pins are set to inputs
b) GPIO2 through GPIO7 do not have an "ARM interrupt" for each pin, but rather for the OR'ed results of 16 pins
==> e.g. GPIO2 will cause an "ARM IRQ 100" if there is a valid interrupt on any pin within 0-15
==> e.g. GPIO2 will cause an "ARM IRQ 101" if there is a valid interrupt on any pin within 16-31
==> So even though GPIO2 can monitor 32 pins for activity, the ARM Core will only see 1 of 2 IRQs happen (#100 or #101)
c) GPIO1 has the same functionality as described in b), but also some further granularity: its bottom 8 pins (0-7) will cause 8 specific "ARM interrupts"
==> GPIO1_0 will cause an "ARM IRQ 97", and so on for pins 1,2,3,4,5,6; GPIO1_7 will cause an "ARM IRQ 90"
==> for GPIO1_8 through GPIO1_31, these can only be seen through "ARM IRQ98" for pins 0-15, or "ARM IRQ99" for pins 16-31
d) In addition, all the 8 registers for the specific GPIOx need to be configured correctly:
- GPIOx_IMR: the appropriate bits need to be set to 1 to enable those interrupts
- GPIOx_ISR: the interrupt routine must write a 1 to the appropriate bit to clear the interrupt flag
- GPIOx_ICR1 and GPIOx_ICR2: these allow you to select between level (low or high) or edge (rising or falling) for the given interrupt pin
- GPIOx_EDGE_SEL: this allows you to override GPIOx_ICR1 and GPIOx_ICR2 for historical reasons
- GPIOx_GDIR: the appropriate pin must be set to an input (bit=0) to allow for interrupts
- GPIOx_DR and GPIO_PSR: not relevant here
e) Finally, you need to use the IOMUX Controller to set the specific pins to be in GPIO mode
Now, based on what you say (you do not see GPIO1_5 create IRQ 92), I have a few questions:
1) Can you see if GPIO1_5 generates interrupt IRQ 98 (pins 0-7)? If that works, I would try IRQ 95 (in case the list was input backwards)
2) If 1) does not work, I would check to see that all the configurations in d) here above are correct
Please let us know how it goes, or if you have further questions.
Thanks,
Rod.
Sorry for the thread jack.
Where can the interrupt and register values be found for a given gpio?
I'm trying to update the linux dtsi file for the imx6 SabreLite board to enable gpio9 (which is exposed on jumper 7 of the SabreLite board).
Thanks,
Michael Richmond
Ben,
Kevin Anderle has asked me to take a look at this question. We are very sorry for the delay!
This is my understanding of how the MX6Q GPIO interrupts work:
a) GPIO1 (32 pins) through GPIO7 (32 pins) can be configured to generate interrupts when the pins are set to inputs
b) GPIO2 through GPIO7 do not have an "ARM interrupt" for each pin, but rather for the OR'ed results of 16 pins
==> e.g. GPIO2 will cause an "ARM IRQ 100" if there is a valid interrupt on any pin within 0-15
==> e.g. GPIO2 will cause an "ARM IRQ 101" if there is a valid interrupt on any pin within 16-31
==> So even though GPIO2 can monitor 32 pins for activity, the ARM Core will only see 1 of 2 IRQs happen (#100 or #101)
c) GPIO1 has the same functionality as described in b), but also some further granularity: its bottom 8 pins (0-7) will cause 8 specific "ARM interrupts"
==> GPIO1_0 will cause an "ARM IRQ 97", and so on for pins 1,2,3,4,5,6; GPIO1_7 will cause an "ARM IRQ 90"
==> for GPIO1_8 through GPIO1_31, these can only be seen through "ARM IRQ98" for pins 0-15, or "ARM IRQ99" for pins 16-31
d) In addition, all the 8 registers for the specific GPIOx need to be configured correctly:
- GPIOx_IMR: the appropriate bits need to be set to 1 to enable those interrupts
- GPIOx_ISR: the interrupt routine must write a 1 to the appropriate bit to clear the interrupt flag
- GPIOx_ICR1 and GPIOx_ICR2: these allow you to select between level (low or high) or edge (rising or falling) for the given interrupt pin
- GPIOx_EDGE_SEL: this allows you to override GPIOx_ICR1 and GPIOx_ICR2 for historical reasons
- GPIOx_GDIR: the appropriate pin must be set to an input (bit=0) to allow for interrupts
- GPIOx_DR and GPIO_PSR: not relevant here
e) Finally, you need to use the IOMUX Controller to set the specific pins to be in GPIO mode
Now, based on what you say (you do not see GPIO1_5 create IRQ 92), I have a few questions:
1) Can you see if GPIO1_5 generates interrupt IRQ 98 (pins 0-7)? If that works, I would try IRQ 95 (in case the list was input backwards)
2) If 1) does not work, I would check to see that all the configurations in d) here above are correct
Please let us know how it goes, or if you have further questions.
Thanks,
Rod.
Hello,
I read your repply about "Interrupts with GPIO1 INT0-7", I am having a problem with GPIO1_5, I am using it as interrupt, IRQ 92. It work fine if I set the following registers inside the driver (dm9000) :
0x209C00C = 0x0400; // Active High
0x209C014 = 0x20 // INT5 on
My problem is I did not find how to do that from the device tree.
From the bellow device tree line
"interrupts = <0 60 4>; "
driver dm900 can get irq 92 (60) but not active high level-sensitive (4)
and I canot find how to setup GPIO1 as intterupt for dm9000
Any help is welcome, I am a beginner with device tree
Regards
Jean-marc
Thanks for reply!
It is working now!
I went over everything above and determined that the interrupt was not being enabled. I had thought I had checked it several times before but I think it was a combinations of errors on my part that caused the interrupt not to work. I had assumed from the start that requesting irq92 would not in itself enable the interrupt in the GPIO module. So I had also requested another interrupt from the GPIO interrupt controller knowing that it does enable the interrupt because I had gotten it to work in that mode before. However I requested the wrong GPIO interrupt and somehow when I had check the IMR it looked fine. I am guessing I double checked the wrong IMR. I also found that my hardware to test the interrupt was not as dependable as well.
Results:
So I have determined that indeed gpio1_5 maps to interrupt 92 which is the gpio1 INT5. I am assuming the other gpio pin 0-7 map directly as well. I am also assuming that only gpio1_5 causes an interrupt 92. I didn't test the combined interrupts as that is not what is needed and I have the single pin interrupt working.
For completeness I am posting the salient code I used to get it to work.
---------------------------------------------------------------------------------------------------
///*** Assume that the board file does the correct muxing for gpio1_5
// Request gpio1_5 and set as input
gpio_request(IMX_GPIO_NR(1, 5), "itest");
gpio_direction_input(IMX_GPIO_NR(1, 5));
//Request irq92
request_irq(MXC_INT_GPIO1_INT5_NUM, itest_irq_handler,0 ,"itest", &itest_device);
//write directly to gpio1 imr reg
//Test only! normally don't do this way as it clears all the other irqs that may have been enabled)
__raw_writel(0x20,MX6_IO_ADDRESS(GPIO1_BASE_ADDR+0x14))
---------------------------------------------------------------------------------------------------
From userspace after loading driver I can see that it has requested irq. I can also trigger the interrupt and see the count go up on the cpu.
>cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
92: 107826 2 0 0 GIC itest
I can also switch the affinity to cpu1 and the count goes up on that cpu.
Thanks,
Ben
is there any APIs to use?like set_irq_type?
Hello Ben !
I am very interesting in your work since I have to do approximately the same thing. But I don't know anything in GPIO so I am requesting some help. My board is an imx6q sabrelite.
Thanks a lot!