serial: stm32: Merge hard IRQ and threaded IRQ handling into single IRQ handler
Subsystems (3)
PATCH v6 1/1 serial: stm32: Merge hard IRQ and threaded IRQ handling into single IRQ handler
Requesting an interrupt with IRQF_ONESHOT will run the primary handler in the hard-IRQ context even in the force-threaded mode. The force-threaded mode is used by PREEMPT_RT in order to avoid acquiring sleeping locks (spinlock_t) in hard-IRQ context. This combination makes it impossible and leads to "sleeping while atomic" warnings.
Use one interrupt handler for both handlers (primary and secondary) and drop the IRQF_ONESHOT flag which is not needed.
---
Cc: Alexandre Torgue <[email protected]>
Cc: Erwan Le Ray <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: Jiri Slaby <[email protected]>
Cc: Maxime Coquelin <[email protected]>
Cc: Sebastian Andrzej Siewior <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Valentin Caron <[email protected]>
Cc: [email protected]
Cc: [email protected]
To: [email protected]
---
V2: - Update patch subject, was:
serial: stm32: Move hard IRQ handling to threaded interrupt context
- Use request_irq() instead, rename the IRQ handler function
V3: - Update the commit message per suggestion from Sebastian
- Add RB from Sebastian
- Add Fixes tag
V4: - Remove uart_console() deadlock check from
stm32_usart_of_dma_rx_probe()
- Use plain spin_lock()/spin_unlock() instead of the _irqsave/_irqrestore variants in IRQ handler
- Add TB from Valentin
V5: - Add CC stable@
- Do not move the sr variable, removes one useless hunk from the patch
V6: - Replace uart_unlock_and_check_sysrq_irqrestore with uart_unlock_and_check_sysrq
and drop last instance of flags
--- drivers/tty/serial/stm32-usart.c | 33 +++++--------------------------- 1 file changed, 5 insertions(+), 28 deletions(-)
drivers/tty/serial/stm32-usart.c +5 -28
@@ -797,25 +797,11 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr)spin_unlock (&port->lock); } -if (stm32_usart_rx_dma_enabled (port)) -return IRQ_WAKE_THREAD ; -else -return IRQ_HANDLED ; -} - -static irqreturn_t stm32_usart_threaded_interrupt (int irq,void *ptr) -{ -struct uart_port *port = ptr; -struct tty_port *tport = &port->state->port; -struct stm32_port *stm32_port =to_stm32_port (port); -unsigned int size; -unsigned long flags; -/* Receiver timeout irq for DMA RX */ -if (!stm32_port->throttled) { -spin_lock_irqsave (&port->lock, flags); +if (stm32_usart_rx_dma_enabled (port) && !stm32_port->throttled) { +spin_lock (&port->lock); size =stm32_usart_receive_chars (port, false); -uart_unlock_and_check_sysrq_irqrestore (port, flags); +uart_unlock_and_check_sysrq (port);if (size)tty_flip_buffer_push (tport); }
@@ -1015,10 +1001,8 @@ static int stm32_usart_startup(struct uart_port *port)u32 val;int ret; - ret =request_threaded_irq (port->irq, stm32_usart_interrupt, - stm32_usart_threaded_interrupt, -IRQF_ONESHOT |IRQF_NO_SUSPEND , - name, port); + ret =request_irq (port->irq, stm32_usart_interrupt, +IRQF_NO_SUSPEND , name, port);if (ret)return ret;
@@ -1601,13 +1585,6 @@ static int stm32_usart_of_dma_rx_probe(struct stm32_port *stm32port,struct dma_slave_config config;int ret; -/* -* Using DMA and threaded handler for the console could lead to -* deadlocks. -*/ -if (uart_console (port)) -return -ENODEV ; - stm32port->rx_buf =dma_alloc_coherent (dev,RX_BUF_L , &stm32port->rx_dma_buf,GFP_KERNEL );
Signature · 1 line
2.39.0