Skip to content

Commit 8324a54

Browse files
ij-intelgregkh
authored andcommitted
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 <[email protected]> Tested-by: Murthy, Shanth <[email protected]> Cc: stable <[email protected]> Reviewed-by: Andy Shevchenko <[email protected]> Signed-off-by: Ilpo Järvinen <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 8002d6d commit 8324a54

2 files changed

Lines changed: 17 additions & 8 deletions

File tree

drivers/tty/serial/8250/8250_port.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/irq.h>
1919
#include <linux/console.h>
2020
#include <linux/gpio/consumer.h>
21+
#include <linux/lockdep.h>
2122
#include <linux/sysrq.h>
2223
#include <linux/delay.h>
2324
#include <linux/platform_device.h>
@@ -1782,20 +1783,16 @@ static bool handle_rx_dma(struct uart_8250_port *up, unsigned int iir)
17821783
}
17831784

17841785
/*
1785-
* This handles the interrupt from one port.
1786+
* Context: port's lock must be held by the caller.
17861787
*/
1787-
int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
1788+
void serial8250_handle_irq_locked(struct uart_port *port, unsigned int iir)
17881789
{
17891790
struct uart_8250_port *up = up_to_u8250p(port);
17901791
struct tty_port *tport = &port->state->port;
17911792
bool skip_rx = false;
1792-
unsigned long flags;
17931793
u16 status;
17941794

1795-
if (iir & UART_IIR_NO_INT)
1796-
return 0;
1797-
1798-
uart_port_lock_irqsave(port, &flags);
1795+
lockdep_assert_held_once(&port->lock);
17991796

18001797
status = serial_lsr_in(up);
18011798

@@ -1828,8 +1825,19 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
18281825
else if (!up->dma->tx_running)
18291826
__stop_tx(up);
18301827
}
1828+
}
1829+
EXPORT_SYMBOL_NS_GPL(serial8250_handle_irq_locked, "SERIAL_8250");
18311830

1832-
uart_unlock_and_check_sysrq_irqrestore(port, flags);
1831+
/*
1832+
* This handles the interrupt from one port.
1833+
*/
1834+
int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
1835+
{
1836+
if (iir & UART_IIR_NO_INT)
1837+
return 0;
1838+
1839+
guard(uart_port_lock_irqsave)(port);
1840+
serial8250_handle_irq_locked(port, iir);
18331841

18341842
return 1;
18351843
}

include/linux/serial_8250.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl);
195195
void serial8250_do_set_divisor(struct uart_port *port, unsigned int baud,
196196
unsigned int quot);
197197
int fsl8250_handle_irq(struct uart_port *port);
198+
void serial8250_handle_irq_locked(struct uart_port *port, unsigned int iir);
198199
int serial8250_handle_irq(struct uart_port *port, unsigned int iir);
199200
u16 serial8250_rx_chars(struct uart_8250_port *up, u16 lsr);
200201
void serial8250_read_char(struct uart_8250_port *up, u16 lsr);

0 commit comments

Comments
 (0)