Что такое цепочка IRQ? Что делают chained_irq_enter
и chained_irq_exit
, ведь после возникновения прерывания линия IRQ отключается, а chained_irq_enter
вызывает функции, связанные с маскировкой прерываний. Если линия уже отключена, зачем маскировать прерывание?
что такое цепочка irq в linux, когда их нужно использовать?
Ответы (2)
что такое связанный irq?
Существует два подхода к вызову обработчиков прерываний для дочерних устройств в обработчике IRQ родительского (контроллера прерываний) устройства.
Цепные прерывания:
- "chained" means that those interrupts are just chain of function calls (for example, SoC's GPIO module interrupt handler is being called from GIC interrupt handler, just as a function call)
generic_handle_irq()
используется для цепочки прерываний- дочерние обработчики IRQ вызываются внутри родительского обработчика HW IRQ
- вы не можете вызывать функции, которые могут находиться в цепочке (дочерних) обработчиках прерываний, потому что они все еще находятся в атомарном контексте (аппаратное прерывание)
- этот подход обычно используется в драйверах для внутренних модулей GPIO SoC.
Вложенные прерывания
- "nested" means that those interrupts can be interrupted by another interrupt; but they are not really HW IRQs, but rather threaded IRQs
handle_nested_irq()
используется для создания вложенных прерываний- дочерние обработчики IRQ вызываются внутри нового потока, созданного функцией
handle_nested_irq()
; нам нужно, чтобы они запускались в контексте процесса, чтобы мы могли вызывать спящие функции шины (например, функции I2C, которые могут спать) - вы можете вызывать функции, которые могут спать внутри вложенных (дочерних) обработчиков прерываний
- этот подход обычно используется в драйверах для внешних чипов, таких как расширители GPIO, потому что они обычно подключаются к SoC через шину I2C, а функции I2C могут спать
Говоря о драйверах, рассмотренных выше:
irq-gic
драйвер используетCHAINED GPIO irqchips
подход для работы с системами с несколькими GIC; этот коммит добавляет, что функциональность- Драйвер
gpio-omap
(упомянутый выше) использует подходGENERIC CHAINED GPIO irqchips
. См. эту фиксацию. Он был преобразован из использования обычногоCHAINED GPIO irqchips
, так что в ядре реального времени он будет многопотоковым обработчиком IRQ, но в ядре, отличном от RT, это будет жесткий обработчик IRQ. - Драйвер gpio-max732x использует подход
NESTED THREADED GPIO irqchips
что делают
chained_irq_enter
иchained_irq_exit
Эти функции реализуют управление потоком аппаратных прерываний, то есть уведомляют микросхему контроллера прерываний, когда следует маскировать и демаскировать текущее прерывание.
Для контроллеров прерываний FastEOI (самый современный способ):
chained_irq_enter()
do nothingchained_irq_exit()
вызывает обратный вызовirq_eoi()
, чтобы сообщить контроллеру прерываний, что обработка прерывания завершена
Для контроллеров прерываний с возможностями маскирования/демаскирования/подтверждения
chained_irq_enter()
masks current interrupt, and acknowledges it if ack callback is set as wellchained_irq_exit()
демаскирует прерывание
потому что после возникновения прерывания линия irq отключена, но
chained_irq_enter
вызывает функции, связанные с маскировкой прерываний, если линия уже отключена, зачем маскировать прерывание?
Линия IRQ отключена. Но нам все еще нужно записать в регистр EOI в конце обработки прерывания. Или отправьте ACK для прерываний на уровне края.
Это объясняет, почему прерывания отключены в обработчике прерываний.
Прочтите саму документацию по ядру Linux, чтобы понять эти API:
https://www.kernel.org/doc/Documentation/gpio/driver.txt
Цепочки GPIO irqchips: обычно это тип, встроенный в SoC. Это означает, что существует быстрый обработчик IRQ для GPIO, который вызывается в цепочке из родительского обработчика IRQ, чаще всего системного контроллера прерываний. Это означает, что irqchip GPIO регистрируется с помощью irq_set_chained_handler() или соответствующей вспомогательной функции gpiochip_set_chained_irqchip(), и обработчик irqchip GPIO будет вызываться немедленно из родительского irqchip, при этом IRQ будут отключены. Затем GPIO irqchip вызовет что-то вроде этой последовательности в своем обработчике прерываний:
static irqreturn_t tc3589x_gpio_irq(int irq, void *data) chained_irq_enter(...); generic_handle_irq(...); chained_irq_exit(...);