serial: 8250_exar: Clear buffer before shutdown
When closing and shutting down the exar serial port, if the chip has not finished sending all of the data in its buffer, the remaining bytes will be lost. Hold off on the shutdown until the bytes have all been sent. Signed-off-by: Robert Middleton <robert.middleton@rm5248.com> Link: https://lore.kernel.org/r/20190801145640.26080-1-robert.middleton@rm5248.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
b2b4b8ed3c
commit
47b1747f70
|
@ -19,6 +19,7 @@
|
|||
#include <linux/string.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/8250_pci.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
|
@ -515,6 +516,27 @@ static irqreturn_t exar_misc_handler(int irq, void *data)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void
|
||||
exar_shutdown(struct uart_port *port)
|
||||
{
|
||||
unsigned char lsr;
|
||||
bool tx_complete = 0;
|
||||
struct uart_8250_port *up = up_to_u8250p(port);
|
||||
struct circ_buf *xmit = &port->state->xmit;
|
||||
int i = 0;
|
||||
|
||||
do {
|
||||
lsr = serial_in(up, UART_LSR);
|
||||
if (lsr & (UART_LSR_TEMT | UART_LSR_THRE))
|
||||
tx_complete = 1;
|
||||
else
|
||||
tx_complete = 0;
|
||||
msleep(1);
|
||||
} while (!uart_circ_empty(xmit) && !tx_complete && i++ < 1000);
|
||||
|
||||
serial8250_do_shutdown(port);
|
||||
}
|
||||
|
||||
static int
|
||||
exar_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
|
||||
{
|
||||
|
@ -555,6 +577,7 @@ exar_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
|
|||
uart.port.flags = UPF_SHARE_IRQ | UPF_EXAR_EFR | UPF_FIXED_TYPE | UPF_FIXED_PORT;
|
||||
uart.port.irq = pci_irq_vector(pcidev, 0);
|
||||
uart.port.dev = &pcidev->dev;
|
||||
uart.port.shutdown = exar_shutdown;
|
||||
|
||||
rc = devm_request_irq(&pcidev->dev, uart.port.irq, exar_misc_handler,
|
||||
IRQF_SHARED, "exar_uart", priv);
|
||||
|
|
Loading…
Reference in New Issue