Skip to content

Commit

Permalink
Merge tag 'tty-5.14-rc5' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/gregkh/tty

Pull tty/serial fixes from Greg KH:
 "Here are some small tty/serial driver fixes for 5.14-rc5 to resolve a
  number of reported problems.

  They include:

   - mips serial driver fixes

   - 8250 driver fixes for reported problems

   - fsl_lpuart driver fixes

   - other tiny driver fixes

  All have been in linux-next for a while with no reported problems"

* tag 'tty-5.14-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty:
  serial: 8250_pci: Avoid irq sharing for MSI(-X) interrupts.
  serial: 8250_mtk: fix uart corruption issue when rx power off
  tty: serial: fsl_lpuart: fix the wrong return value in lpuart32_get_mctrl
  serial: 8250_pci: Enumerate Elkhart Lake UARTs via dedicated driver
  serial: 8250: fix handle_irq locking
  serial: tegra: Only print FIFO error message when an error occurs
  MIPS: Malta: Do not byte-swap accesses to the CBUS UART
  serial: 8250: Mask out floating 16/32-bit bus bits
  serial: max310x: Unprepare and disable clock in error path
  • Loading branch information
Linus Torvalds committed Aug 8, 2021
2 parents 6a65554 + 341abd6 commit 6463e54
Show file tree
Hide file tree
Showing 10 changed files with 63 additions and 14 deletions.
3 changes: 2 additions & 1 deletion arch/mips/mti-malta/malta-platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ static struct plat_serial8250_port uart8250_data[] = {
.mapbase = 0x1f000900, /* The CBUS UART */
.irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_MB2,
.uartclk = 3686400, /* Twice the usual clk! */
.iotype = UPIO_MEM32,
.iotype = IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) ?
UPIO_MEM32BE : UPIO_MEM32,
.flags = CBUS_UART_FLAGS,
.regshift = 3,
},
Expand Down
5 changes: 3 additions & 2 deletions drivers/tty/serial/8250/8250_aspeed_vuart.c
Original file line number Diff line number Diff line change
Expand Up @@ -329,14 +329,15 @@ static int aspeed_vuart_handle_irq(struct uart_port *port)
{
struct uart_8250_port *up = up_to_u8250p(port);
unsigned int iir, lsr;
unsigned long flags;
unsigned int space, count;

iir = serial_port_in(port, UART_IIR);

if (iir & UART_IIR_NO_INT)
return 0;

spin_lock(&port->lock);
spin_lock_irqsave(&port->lock, flags);

lsr = serial_port_in(port, UART_LSR);

Expand Down Expand Up @@ -370,7 +371,7 @@ static int aspeed_vuart_handle_irq(struct uart_port *port)
if (lsr & UART_LSR_THRE)
serial8250_tx_chars(up);

uart_unlock_and_check_sysrq(port);
uart_unlock_and_check_sysrq_irqrestore(port, flags);

return 1;
}
Expand Down
5 changes: 3 additions & 2 deletions drivers/tty/serial/8250/8250_fsl.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@ struct fsl8250_data {
int fsl8250_handle_irq(struct uart_port *port)
{
unsigned char lsr, orig_lsr;
unsigned long flags;
unsigned int iir;
struct uart_8250_port *up = up_to_u8250p(port);

spin_lock(&up->port.lock);
spin_lock_irqsave(&up->port.lock, flags);

iir = port->serial_in(port, UART_IIR);
if (iir & UART_IIR_NO_INT) {
Expand Down Expand Up @@ -82,7 +83,7 @@ int fsl8250_handle_irq(struct uart_port *port)

up->lsr_saved_flags = orig_lsr;

uart_unlock_and_check_sysrq(&up->port);
uart_unlock_and_check_sysrq_irqrestore(&up->port, flags);

return 1;
}
Expand Down
5 changes: 5 additions & 0 deletions drivers/tty/serial/8250/8250_mtk.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,13 @@ static void mtk8250_dma_rx_complete(void *param)
struct dma_tx_state state;
int copied, total, cnt;
unsigned char *ptr;
unsigned long flags;

if (data->rx_status == DMA_RX_SHUTDOWN)
return;

spin_lock_irqsave(&up->port.lock, flags);

dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state);
total = dma->rx_size - state.residue;
cnt = total;
Expand All @@ -120,6 +123,8 @@ static void mtk8250_dma_rx_complete(void *param)
tty_flip_buffer_push(tty_port);

mtk8250_rx_dma(up);

spin_unlock_irqrestore(&up->port.lock, flags);
}

static void mtk8250_rx_dma(struct uart_8250_port *up)
Expand Down
7 changes: 7 additions & 0 deletions drivers/tty/serial/8250/8250_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -3836,6 +3836,12 @@ static const struct pci_device_id blacklist[] = {
{ PCI_VDEVICE(INTEL, 0x0f0c), },
{ PCI_VDEVICE(INTEL, 0x228a), },
{ PCI_VDEVICE(INTEL, 0x228c), },
{ PCI_VDEVICE(INTEL, 0x4b96), },
{ PCI_VDEVICE(INTEL, 0x4b97), },
{ PCI_VDEVICE(INTEL, 0x4b98), },
{ PCI_VDEVICE(INTEL, 0x4b99), },
{ PCI_VDEVICE(INTEL, 0x4b9a), },
{ PCI_VDEVICE(INTEL, 0x4b9b), },
{ PCI_VDEVICE(INTEL, 0x9ce3), },
{ PCI_VDEVICE(INTEL, 0x9ce4), },

Expand Down Expand Up @@ -3996,6 +4002,7 @@ pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board)
if (pci_match_id(pci_use_msi, dev)) {
dev_dbg(&dev->dev, "Using MSI(-X) interrupts\n");
pci_set_master(dev);
uart.port.flags &= ~UPF_SHARE_IRQ;
rc = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_ALL_TYPES);
} else {
dev_dbg(&dev->dev, "Using legacy interrupts\n");
Expand Down
17 changes: 12 additions & 5 deletions drivers/tty/serial/8250/8250_port.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,11 @@ static const struct serial8250_config uart_config[] = {
/* Uart divisor latch read */
static int default_serial_dl_read(struct uart_8250_port *up)
{
return serial_in(up, UART_DLL) | serial_in(up, UART_DLM) << 8;
/* Assign these in pieces to truncate any bits above 7. */
unsigned char dll = serial_in(up, UART_DLL);
unsigned char dlm = serial_in(up, UART_DLM);

return dll | dlm << 8;
}

/* Uart divisor latch write */
Expand Down Expand Up @@ -1297,9 +1301,11 @@ static void autoconfig(struct uart_8250_port *up)
serial_out(up, UART_LCR, 0);

serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO);
scratch = serial_in(up, UART_IIR) >> 6;

switch (scratch) {
/* Assign this as it is to truncate any bits above 7. */
scratch = serial_in(up, UART_IIR);

switch (scratch >> 6) {
case 0:
autoconfig_8250(up);
break;
Expand Down Expand Up @@ -1893,11 +1899,12 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
unsigned char status;
struct uart_8250_port *up = up_to_u8250p(port);
bool skip_rx = false;
unsigned long flags;

if (iir & UART_IIR_NO_INT)
return 0;

spin_lock(&port->lock);
spin_lock_irqsave(&port->lock, flags);

status = serial_port_in(port, UART_LSR);

Expand All @@ -1923,7 +1930,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
(up->ier & UART_IER_THRI))
serial8250_tx_chars(up);

uart_unlock_and_check_sysrq(port);
uart_unlock_and_check_sysrq_irqrestore(port, flags);

return 1;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/tty/serial/fsl_lpuart.c
Original file line number Diff line number Diff line change
Expand Up @@ -1415,7 +1415,7 @@ static unsigned int lpuart_get_mctrl(struct uart_port *port)

static unsigned int lpuart32_get_mctrl(struct uart_port *port)
{
unsigned int mctrl = 0;
unsigned int mctrl = TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
u32 reg;

reg = lpuart32_read(port, UARTCTRL);
Expand Down
3 changes: 2 additions & 1 deletion drivers/tty/serial/max310x.c
Original file line number Diff line number Diff line change
Expand Up @@ -1293,7 +1293,8 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty
freq = uartclk;
if (freq == 0) {
dev_err(dev, "Cannot get clock rate\n");
return -EINVAL;
ret = -EINVAL;
goto out_clk;
}

if (xtal) {
Expand Down
6 changes: 4 additions & 2 deletions drivers/tty/serial/serial-tegra.c
Original file line number Diff line number Diff line change
Expand Up @@ -1045,9 +1045,11 @@ static int tegra_uart_hw_init(struct tegra_uart_port *tup)

if (tup->cdata->fifo_mode_enable_status) {
ret = tegra_uart_wait_fifo_mode_enabled(tup);
dev_err(tup->uport.dev, "FIFO mode not enabled\n");
if (ret < 0)
if (ret < 0) {
dev_err(tup->uport.dev,
"Failed to enable FIFO mode: %d\n", ret);
return ret;
}
} else {
/*
* For all tegra devices (up to t210), there is a hardware
Expand Down
24 changes: 24 additions & 0 deletions include/linux/serial_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,25 @@ static inline void uart_unlock_and_check_sysrq(struct uart_port *port)
if (sysrq_ch)
handle_sysrq(sysrq_ch);
}

static inline void uart_unlock_and_check_sysrq_irqrestore(struct uart_port *port,
unsigned long flags)
{
int sysrq_ch;

if (!port->has_sysrq) {
spin_unlock_irqrestore(&port->lock, flags);
return;
}

sysrq_ch = port->sysrq_ch;
port->sysrq_ch = 0;

spin_unlock_irqrestore(&port->lock, flags);

if (sysrq_ch)
handle_sysrq(sysrq_ch);
}
#else /* CONFIG_MAGIC_SYSRQ_SERIAL */
static inline int uart_handle_sysrq_char(struct uart_port *port, unsigned int ch)
{
Expand All @@ -531,6 +550,11 @@ static inline void uart_unlock_and_check_sysrq(struct uart_port *port)
{
spin_unlock(&port->lock);
}
static inline void uart_unlock_and_check_sysrq_irqrestore(struct uart_port *port,
unsigned long flags)
{
spin_unlock_irqrestore(&port->lock, flags);
}
#endif /* CONFIG_MAGIC_SYSRQ_SERIAL */

/*
Expand Down

0 comments on commit 6463e54

Please sign in to comment.