Zack's Kernel News
Improving GPIO Interrupt Handling
Jerome Brunet asked Linus Torvalds and a lot of other people for guidance on some patches he wanted to write. The problem was how to have general-purpose input/output (GPIO) controllers provide a working IRQ to all GPIOs simultaneously. GPIO is a physical pin on a chip, with no particular purpose hard-coded into it, except that it can be used for either input or output as desired by the code using it. The interrupt request (IRQ) is a hardware signal used to interrupt whatever's happening (in this case whoever's using the GPIO pin) and to make something else happen instead.
If the Linux kernel is not able to interrupt something when it needs to, then it can't do process context switching in a timely fashion, and the user experience gets choppier. Fine-grained context switching is a crucial part of the Linux kernel, and uninterruptible operations are ideally always kept to a minimum.
Many hardware chips, Jerome said, had no trouble providing working IRQs to all GPIOs simultaneously. But some, like the Amlogic system on a chip (SoC), had trouble, because they didn't have enough IRQs available to match the number of GPIO pins.
To handle these cases, there would have to be some code to handle the GPIO resource properly, for example by manually associating particular interrupts with particular GPIOs on the fly. However, Jerome didn't like this possibility for a couple of reasons. For one thing, the mechanism for doing it was itself not interruptible, so the benefit to context switching was decreased. For another thing, once the code made the association between an interrupt and a GPIO, there was no corresponding mechanism to free up that association. It would just hang around even if it wasn't used anymore. So as Jerome put it, "this approach leaks mappings." He also pointed out that there were already quite a number of GPIO drivers using this approach, which indicated even more strongly that some kind of solution should be found.
Another solution, he said, was "to create an empty domain to get a virq for each pin but delay the setup of the interrupt hierarchy to the 'irq_request_resources' callback. Testing this approach led me to some nasty race conditions in the interrupt handlers. I discussed this solution with Marc [Zyngier] and he told me that doing the setup of the interrupt hierarchy in the irqchip callbacks is 'too late'."
Given the problems with each of these possibilities, Jerome felt there was no clean solution at the moment. He offered a third alternative that would require a fair bit of implementation. First, he would define a pair of prepare/unprepare functions, which any given GPIO driver could implement if needed. He would also add new functions to the GPIO kernel API that would implement reference counting in order to share scarce IRQs among multiple GPIOs. Finally, he'd go back to existing GPIO user code in the kernel and update them to use the new interface.
He emphasized that the new approach would be a complete no-op for any drivers that didn't need it. But for those that did, it would provide the working IRQs to all GPIOs simultaneously.
Linus Walleij, Grygorii Strashko, and Marc Zyngier immediately dove into a technical implementation discussion with Jerome, with various strong objections and new directions proposed. Ultimately, there was absolutely no consensus reached. But it's clearly something a lot of people care about, because it means the difference between cleanly supporting Linux on a piece of hardware, or not.
Zack Brown
The Linux kernel mailing list comprises the core of Linux development activities. Traffic volumes are immense, often reaching 10,000 messages in a week, and keeping up to date with the entire scope of development is a virtually impossible task for one person. One of the few brave souls to take on this task is Zack Brown.
« Previous 1 2
Buy this article as PDF
(incl. VAT)