Commit 636110be authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull serial driver fixes from Greg KH:
 "Here are two small serial driver fixes for 6.13-rc3.  They are:

   - ioport build fallout fix for the 8250 port driver that should
     resolve Guenter's runtime problems

   - sh-sci driver bugfix for a reported problem

  Both of these have been in linux-next for a while with no reported
  issues"

* tag 'tty-6.13-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty:
  tty: serial: Work around warning backtrace in serial8250_set_defaults
  serial: sh-sci: Check if TX data was written to device in .tx_empty()
parents 3de4f6d9 4e450dfd
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -467,7 +467,8 @@ static void set_io_from_upio(struct uart_port *p)
		break;
#endif
	default:
		WARN(1, "Unsupported UART type %x\n", p->iotype);
		WARN(p->iotype != UPIO_PORT || p->iobase,
		     "Unsupported UART type %x\n", p->iotype);
		p->serial_in = no_serial_in;
		p->serial_out = no_serial_out;
	}
+29 −0
Original line number Diff line number Diff line
@@ -157,6 +157,7 @@ struct sci_port {

	bool has_rtscts;
	bool autorts;
	bool tx_occurred;
};

#define SCI_NPORTS CONFIG_SERIAL_SH_SCI_NR_UARTS
@@ -850,6 +851,7 @@ static void sci_transmit_chars(struct uart_port *port)
{
	struct tty_port *tport = &port->state->port;
	unsigned int stopped = uart_tx_stopped(port);
	struct sci_port *s = to_sci_port(port);
	unsigned short status;
	unsigned short ctrl;
	int count;
@@ -885,6 +887,7 @@ static void sci_transmit_chars(struct uart_port *port)
		}

		sci_serial_out(port, SCxTDR, c);
		s->tx_occurred = true;

		port->icount.tx++;
	} while (--count > 0);
@@ -1241,6 +1244,8 @@ static void sci_dma_tx_complete(void *arg)
	if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
		uart_write_wakeup(port);

	s->tx_occurred = true;

	if (!kfifo_is_empty(&tport->xmit_fifo)) {
		s->cookie_tx = 0;
		schedule_work(&s->work_tx);
@@ -1731,6 +1736,19 @@ static void sci_flush_buffer(struct uart_port *port)
		s->cookie_tx = -EINVAL;
	}
}

static void sci_dma_check_tx_occurred(struct sci_port *s)
{
	struct dma_tx_state state;
	enum dma_status status;

	if (!s->chan_tx)
		return;

	status = dmaengine_tx_status(s->chan_tx, s->cookie_tx, &state);
	if (status == DMA_COMPLETE || status == DMA_IN_PROGRESS)
		s->tx_occurred = true;
}
#else /* !CONFIG_SERIAL_SH_SCI_DMA */
static inline void sci_request_dma(struct uart_port *port)
{
@@ -1740,6 +1758,10 @@ static inline void sci_free_dma(struct uart_port *port)
{
}

static void sci_dma_check_tx_occurred(struct sci_port *s)
{
}

#define sci_flush_buffer	NULL
#endif /* !CONFIG_SERIAL_SH_SCI_DMA */

@@ -2076,6 +2098,12 @@ static unsigned int sci_tx_empty(struct uart_port *port)
{
	unsigned short status = sci_serial_in(port, SCxSR);
	unsigned short in_tx_fifo = sci_txfill(port);
	struct sci_port *s = to_sci_port(port);

	sci_dma_check_tx_occurred(s);

	if (!s->tx_occurred)
		return TIOCSER_TEMT;

	return (status & SCxSR_TEND(port)) && !in_tx_fifo ? TIOCSER_TEMT : 0;
}
@@ -2247,6 +2275,7 @@ static int sci_startup(struct uart_port *port)

	dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);

	s->tx_occurred = false;
	sci_request_dma(port);

	ret = sci_request_irq(s);