Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

serial: 8250: Add serial8250_handle_irq_locked()

8250_port exports serial8250_handle_irq() to HW specific 8250 drivers.
It takes port's lock within but a HW specific 8250 driver may want to
take port's lock itself, do something, and then call the generic
handler in 8250_port but to do that, the caller has to release port's
lock for no good reason.

Introduce serial8250_handle_irq_locked() which a HW specific driver can
call while already holding port's lock.

As this is new export, put it straight into a namespace (where all 8250
exports should eventually be moved).

Tested-by: Bandal, Shankar <shankar.bandal@intel.com>
Tested-by: Murthy, Shanth <shanth.murthy@intel.com>
Cc: stable <stable@kernel.org>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Link: https://patch.msgid.link/20260203171049.4353-4-ilpo.jarvinen@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Ilpo Järvinen and committed by
Greg Kroah-Hartman
8324a54f 8002d6d6

+17 -8
+16 -8
drivers/tty/serial/8250/8250_port.c
··· 18 18 #include <linux/irq.h> 19 19 #include <linux/console.h> 20 20 #include <linux/gpio/consumer.h> 21 + #include <linux/lockdep.h> 21 22 #include <linux/sysrq.h> 22 23 #include <linux/delay.h> 23 24 #include <linux/platform_device.h> ··· 1783 1782 } 1784 1783 1785 1784 /* 1786 - * This handles the interrupt from one port. 1785 + * Context: port's lock must be held by the caller. 1787 1786 */ 1788 - int serial8250_handle_irq(struct uart_port *port, unsigned int iir) 1787 + void serial8250_handle_irq_locked(struct uart_port *port, unsigned int iir) 1789 1788 { 1790 1789 struct uart_8250_port *up = up_to_u8250p(port); 1791 1790 struct tty_port *tport = &port->state->port; 1792 1791 bool skip_rx = false; 1793 - unsigned long flags; 1794 1792 u16 status; 1795 1793 1796 - if (iir & UART_IIR_NO_INT) 1797 - return 0; 1798 - 1799 - uart_port_lock_irqsave(port, &flags); 1794 + lockdep_assert_held_once(&port->lock); 1800 1795 1801 1796 status = serial_lsr_in(up); 1802 1797 ··· 1825 1828 else if (!up->dma->tx_running) 1826 1829 __stop_tx(up); 1827 1830 } 1831 + } 1832 + EXPORT_SYMBOL_NS_GPL(serial8250_handle_irq_locked, "SERIAL_8250"); 1828 1833 1829 - uart_unlock_and_check_sysrq_irqrestore(port, flags); 1834 + /* 1835 + * This handles the interrupt from one port. 1836 + */ 1837 + int serial8250_handle_irq(struct uart_port *port, unsigned int iir) 1838 + { 1839 + if (iir & UART_IIR_NO_INT) 1840 + return 0; 1841 + 1842 + guard(uart_port_lock_irqsave)(port); 1843 + serial8250_handle_irq_locked(port, iir); 1830 1844 1831 1845 return 1; 1832 1846 }
+1
include/linux/serial_8250.h
··· 195 195 void serial8250_do_set_divisor(struct uart_port *port, unsigned int baud, 196 196 unsigned int quot); 197 197 int fsl8250_handle_irq(struct uart_port *port); 198 + void serial8250_handle_irq_locked(struct uart_port *port, unsigned int iir); 198 199 int serial8250_handle_irq(struct uart_port *port, unsigned int iir); 199 200 u16 serial8250_rx_chars(struct uart_8250_port *up, u16 lsr); 200 201 void serial8250_read_char(struct uart_8250_port *up, u16 lsr);