<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>i.MX ProcessorsのトピックRe: Proper GPIO interrupt handling in iMX6</title>
    <link>https://community.nxp.com/t5/i-MX-Processors/Proper-GPIO-interrupt-handling-in-iMX6/m-p/351397#M48874</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Nathan&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I would suggest to look at attached Linux Manual (L3.0.35_4.1.0)&lt;/P&gt;&lt;P&gt;sect.2.2.4 Interrupt Source Code Structure and files where implemented&lt;/P&gt;&lt;P&gt;interrupt processing, for example struct irq_chip gpio_irq_chip, gpio.c&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Best regards&lt;/P&gt;&lt;P&gt;igor&lt;/P&gt;&lt;P&gt;-----------------------------------------------------------------------------------------------------------------------&lt;/P&gt;&lt;P&gt;Note: If this post answers your question, please click the Correct Answer button. Thank you!&lt;/P&gt;&lt;P&gt;-----------------------------------------------------------------------------------------------------------------------&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Thu, 26 Mar 2015 10:00:55 GMT</pubDate>
    <dc:creator>igorpadykov</dc:creator>
    <dc:date>2015-03-26T10:00:55Z</dc:date>
    <item>
      <title>Proper GPIO interrupt handling in iMX6</title>
      <link>https://community.nxp.com/t5/i-MX-Processors/Proper-GPIO-interrupt-handling-in-iMX6/m-p/351396#M48873</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I am using the iMX6 BSP and have a question about interrupt handling.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;As I understand the flow in the BSP, the following happens on GPIO interrupt (assuming a handler is installed with register_interrupt_routine(IRQ, ISR):&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;1. ARM Core takes IRQ Exception and globally masks the IRQ bit in the CPSR (Disables IRQ interrupts)&lt;/P&gt;&lt;P&gt;2. The Freescale IRQ_HDLR() is called because it is in the ARM vector for IRQ exception&lt;/P&gt;&lt;P&gt;3. The GIC is checked for the highest priority interrupt pending and the GIC is ACKed&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;4. That interrupt is called by looking up the address (in this case, handle_GPIO())&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;5. The GIC is signafied that the interrupt is handled&lt;/P&gt;&lt;P&gt;6. ARM core is restored to resume "mainline" execution&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;My question is: What should happen in &lt;SPAN style="font-size: 13.3333330154419px;"&gt;handle_GPIO() to ensure safe interrupt handling? &lt;/SPAN&gt;&lt;SPAN style="font-size: 10pt; line-height: 1.5em;"&gt;Specifically, when should I ACK the status in the GPIO_ISR register to make sure interrupts are not missed, and should I mask the GPIO_IMR register while &lt;/SPAN&gt;handling&lt;SPAN style="font-size: 10pt; line-height: 1.5em;"&gt; the interrupt?&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Currently i am doing this:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #3366ff; font-family: 'andale mono', times;"&gt;&amp;nbsp; uint32_t mask = HW_GPIO_IMR_RD(port);&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'andale mono', times; color: #3366ff;"&gt;&amp;nbsp; HW_GPIO_IMR_WR(port, mask &amp;amp; ~(1UL &amp;lt;&amp;lt; pin)); // Mask the interrupt&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'andale mono', times; color: #3366ff;"&gt;&amp;nbsp; uint32_t status = HW_GPIO_ISR_RD(port) ; // Read the status&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'andale mono', times; color: #3366ff;"&gt;&amp;nbsp; HW_GPIO_ISR_WR(port, (1UL &amp;lt;&amp;lt; pin)); // ACK the status&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'andale mono', times; color: #3366ff;"&gt;&amp;nbsp; if (status &amp;amp; mask &amp;amp; (1UL &amp;lt;&amp;lt; pin) ) {&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'andale mono', times; color: #3366ff;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Call the ISR function that is assigned to this pin&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'andale mono', times; color: #3366ff;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; gpio_irqs_in_use[i].isr_func();&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'andale mono', times; color: #3366ff;"&gt;&amp;nbsp; }&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #3366ff; font-family: 'andale mono', times;"&gt;&amp;nbsp; HW_GPIO_IMR_WR(port, mask); // Un-mask the interrupt&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;But I don't know if it is correct.&amp;nbsp; Also, I would like to be able to mask the interrupt FROM the isr_func() which is impossible with this approach.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 25 Mar 2015 21:58:33 GMT</pubDate>
      <guid>https://community.nxp.com/t5/i-MX-Processors/Proper-GPIO-interrupt-handling-in-iMX6/m-p/351396#M48873</guid>
      <dc:creator>nathanpalmer</dc:creator>
      <dc:date>2015-03-25T21:58:33Z</dc:date>
    </item>
    <item>
      <title>Re: Proper GPIO interrupt handling in iMX6</title>
      <link>https://community.nxp.com/t5/i-MX-Processors/Proper-GPIO-interrupt-handling-in-iMX6/m-p/351397#M48874</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Nathan&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I would suggest to look at attached Linux Manual (L3.0.35_4.1.0)&lt;/P&gt;&lt;P&gt;sect.2.2.4 Interrupt Source Code Structure and files where implemented&lt;/P&gt;&lt;P&gt;interrupt processing, for example struct irq_chip gpio_irq_chip, gpio.c&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Best regards&lt;/P&gt;&lt;P&gt;igor&lt;/P&gt;&lt;P&gt;-----------------------------------------------------------------------------------------------------------------------&lt;/P&gt;&lt;P&gt;Note: If this post answers your question, please click the Correct Answer button. Thank you!&lt;/P&gt;&lt;P&gt;-----------------------------------------------------------------------------------------------------------------------&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 26 Mar 2015 10:00:55 GMT</pubDate>
      <guid>https://community.nxp.com/t5/i-MX-Processors/Proper-GPIO-interrupt-handling-in-iMX6/m-p/351397#M48874</guid>
      <dc:creator>igorpadykov</dc:creator>
      <dc:date>2015-03-26T10:00:55Z</dc:date>
    </item>
    <item>
      <title>Re: Proper GPIO interrupt handling in iMX6</title>
      <link>https://community.nxp.com/t5/i-MX-Processors/Proper-GPIO-interrupt-handling-in-iMX6/m-p/351398#M48875</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Thanks, that is actually the code I looked at to get my implementation (from the current Kernel git repo).&amp;nbsp; However, I was unclear about the chained_irq_enter(chip, desc); and chained_irq_exit(chip, desc) functions.&amp;nbsp; They appear to mask the specific pin interrupt (GPIO_IMR) while handling it and then restore IMR when done.&amp;nbsp; I was wondering if that is necessary, since interrupts are globally masked while in IRQ exception mode (correct?).&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The reason I ask is that I need to be able to mask a GPIO interrupt from a GPIO ISR.&amp;nbsp; For example, wait for a rising edge and then when it happens stop looking for more edges.&amp;nbsp; I am tempted to not mask/restore the IMR while handling the ISR, that way I can mask the IMR in the ISR. I just want to make sure I am following best practices to prevent ISR problems.&amp;nbsp; &lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 26 Mar 2015 15:29:25 GMT</pubDate>
      <guid>https://community.nxp.com/t5/i-MX-Processors/Proper-GPIO-interrupt-handling-in-iMX6/m-p/351398#M48875</guid>
      <dc:creator>nathanpalmer</dc:creator>
      <dc:date>2015-03-26T15:29:25Z</dc:date>
    </item>
    <item>
      <title>Re: Proper GPIO interrupt handling in iMX6</title>
      <link>https://community.nxp.com/t5/i-MX-Processors/Proper-GPIO-interrupt-handling-in-iMX6/m-p/351399#M48876</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;What is the purpose of masking the interrupt (IMR register) while calling the ISR&lt;SPAN style="font-size: 13.3333330154419px; line-height: 1.5em;"&gt; &lt;/SPAN&gt;&lt;SPAN style="font-size: 13.3333330154419px; line-height: 1.5em;"&gt;(call to generic_handle_irq(...)&lt;/SPAN&gt;&lt;SPAN style="font-size: 10pt; line-height: 1.5em;"&gt;?&amp;nbsp; This appears to be what the Linux code you attached is doing, but it is a little unclear.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I am not masking the IMR while handling the ISR and I would like to make sure that is OK for this chip.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 09 Apr 2015 18:49:15 GMT</pubDate>
      <guid>https://community.nxp.com/t5/i-MX-Processors/Proper-GPIO-interrupt-handling-in-iMX6/m-p/351399#M48876</guid>
      <dc:creator>nathanpalmer</dc:creator>
      <dc:date>2015-04-09T18:49:15Z</dc:date>
    </item>
    <item>
      <title>Re: Proper GPIO interrupt handling in iMX6</title>
      <link>https://community.nxp.com/t5/i-MX-Processors/Proper-GPIO-interrupt-handling-in-iMX6/m-p/351400#M48877</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Nathan,&lt;/P&gt;&lt;P&gt;&amp;nbsp; I have exactly the same problem like yours.&lt;/P&gt;&lt;P&gt;I found the solution changing the default IRQ flow handler for the GPIO-MXC IRQ controller from "level flow" to "&lt;STRONG&gt;egde flow&lt;/STRONG&gt;".&lt;/P&gt;&lt;P&gt;In the file gpio-mxc.c (at &amp;lt;kernel-build-dir&amp;gt;/drivers/gpio) there is the function responsible for the gpio interrupt controller initialization:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;static void __init mxc_gpio_init_gc(struct mxc_gpio_port *port, int irq_base)&lt;/P&gt;&lt;P&gt;{&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; struct irq_chip_generic *gc;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; struct irq_chip_type *ct;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; gc = irq_alloc_generic_chip("gpio-mxc", 1, irq_base,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; port-&amp;gt;base, handle_level_irq);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; ...&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;change this initialization with the following one:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; gc = irq_alloc_generic_chip("gpio-mxc", 1, irq_base,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; port-&amp;gt;base, handle_edge_irq);&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;In this way everytime an edge interrupt is detected it will be properly handled by the function handle_edge_irq (file: &amp;lt;kernel-build-dir&amp;gt;/kernel/irq/chip.c).&lt;/P&gt;&lt;P&gt;&lt;A href="https://www.kernel.org/doc/htmldocs/genericirq/Highlevel_IRQ_flow_handlers.html"&gt;https://www.kernel.org/doc/htmldocs/genericirq/Highlevel_IRQ_flow_handlers.html&lt;/A&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;The interrupt is kept enabled and is masked in the flow handler when an interrupt event happens. This prevents losing edge interrupts on hardware which does not store an edge interrupt event while the interrupt is disabled at the hardware level. When an interrupt arrives while the IRQ_DISABLED flag is set, then the interrupt is masked at the hardware level and the IRQ_PENDING bit is set. When the interrupt is re-enabled by enable_irq() the pending bit is checked and if it is set, the interrupt is resent either via hardware or by a software resend mechanism. (It's necessary to enable CONFIG_HARDIRQS_SW_RESEND when you want to use the delayed interrupt disable feature and your hardware is not capable of retriggering.&lt;/EM&gt;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Mon, 24 Aug 2015 10:51:20 GMT</pubDate>
      <guid>https://community.nxp.com/t5/i-MX-Processors/Proper-GPIO-interrupt-handling-in-iMX6/m-p/351400#M48877</guid>
      <dc:creator>andreatessadri</dc:creator>
      <dc:date>2015-08-24T10:51:20Z</dc:date>
    </item>
  </channel>
</rss>

