Commit 02149609 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull tty and serial driver fixes from Greg KH:
 "Here are some small tty and serial driver fixes for 6.8-rc3 that
  resolve a number of reported issues. Included in here are:

   - rs485 flag definition fix that affected the user/kernel abi in -rc1

   - max310x driver fixes

   - 8250_pci1xxxx driver off-by-one fix

   - uart_tiocmget locking race fix

  All of these have been in linux-next for over a week with no reported
  issues"

* tag 'tty-6.8-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty:
  serial: max310x: prevent infinite while() loop in port startup
  serial: max310x: fail probe if clock crystal is unstable
  serial: max310x: improve crystal stable clock detection
  serial: max310x: set default value when reading clock ready bit
  serial: core: Fix atomicity violation in uart_tiocmget
  serial: 8250_pci1xxxx: fix off by one in pci1xxxx_process_read_data()
  tty: serial: Fix bit order in RS485 flag definitions
parents 809be620 b35f8dbb
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -302,7 +302,7 @@ static void pci1xxxx_process_read_data(struct uart_port *port,
	 * to read, the data is received one byte at a time.
	 */
	while (valid_burst_count--) {
		if (*buff_index > (RX_BUF_SIZE - UART_BURST_SIZE))
		if (*buff_index >= (RX_BUF_SIZE - UART_BURST_SIZE))
			break;
		burst_buf = (u32 *)&rx_buff[*buff_index];
		*burst_buf = readl(port->membase + UART_RX_BURST_FIFO);
@@ -311,7 +311,7 @@ static void pci1xxxx_process_read_data(struct uart_port *port,
	}

	while (*valid_byte_count) {
		if (*buff_index > RX_BUF_SIZE)
		if (*buff_index >= RX_BUF_SIZE)
			break;
		rx_buff[*buff_index] = readb(port->membase +
					     UART_RX_BYTE_FIFO);
+43 −10
Original line number Diff line number Diff line
@@ -237,6 +237,14 @@
#define MAX310x_REV_MASK		(0xf8)
#define MAX310X_WRITE_BIT		0x80

/* Port startup definitions */
#define MAX310X_PORT_STARTUP_WAIT_RETRIES	20 /* Number of retries */
#define MAX310X_PORT_STARTUP_WAIT_DELAY_MS	10 /* Delay between retries */

/* Crystal-related definitions */
#define MAX310X_XTAL_WAIT_RETRIES	20 /* Number of retries */
#define MAX310X_XTAL_WAIT_DELAY_MS	10 /* Delay between retries */

/* MAX3107 specific */
#define MAX3107_REV_ID			(0xa0)

@@ -583,7 +591,7 @@ static int max310x_update_best_err(unsigned long f, long *besterr)
	return 1;
}

static u32 max310x_set_ref_clk(struct device *dev, struct max310x_port *s,
static s32 max310x_set_ref_clk(struct device *dev, struct max310x_port *s,
			       unsigned long freq, bool xtal)
{
	unsigned int div, clksrc, pllcfg = 0;
@@ -641,12 +649,20 @@ static u32 max310x_set_ref_clk(struct device *dev, struct max310x_port *s,

	/* Wait for crystal */
	if (xtal) {
		unsigned int val;
		msleep(10);
		bool stable = false;
		unsigned int try = 0, val = 0;

		do {
			msleep(MAX310X_XTAL_WAIT_DELAY_MS);
			regmap_read(s->regmap, MAX310X_STS_IRQSTS_REG, &val);
		if (!(val & MAX310X_STS_CLKREADY_BIT)) {
			dev_warn(dev, "clock is not stable yet\n");
		}

			if (val & MAX310X_STS_CLKREADY_BIT)
				stable = true;
		} while (!stable && (++try < MAX310X_XTAL_WAIT_RETRIES));

		if (!stable)
			return dev_err_probe(dev, -EAGAIN,
					     "clock is not stable\n");
	}

	return bestfreq;
@@ -1271,7 +1287,7 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty
{
	int i, ret, fmin, fmax, freq;
	struct max310x_port *s;
	u32 uartclk = 0;
	s32 uartclk = 0;
	bool xtal;

	for (i = 0; i < devtype->nr; i++)
@@ -1334,6 +1350,9 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty
		goto out_clk;

	for (i = 0; i < devtype->nr; i++) {
		bool started = false;
		unsigned int try = 0, val = 0;

		/* Reset port */
		regmap_write(regmaps[i], MAX310X_MODE2_REG,
			     MAX310X_MODE2_RST_BIT);
@@ -1342,13 +1361,27 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty

		/* Wait for port startup */
		do {
			regmap_read(regmaps[i], MAX310X_BRGDIVLSB_REG, &ret);
		} while (ret != 0x01);
			msleep(MAX310X_PORT_STARTUP_WAIT_DELAY_MS);
			regmap_read(regmaps[i], MAX310X_BRGDIVLSB_REG, &val);

			if (val == 0x01)
				started = true;
		} while (!started && (++try < MAX310X_PORT_STARTUP_WAIT_RETRIES));

		if (!started) {
			ret = dev_err_probe(dev, -EAGAIN, "port reset failed\n");
			goto out_uart;
		}

		regmap_write(regmaps[i], MAX310X_MODE1_REG, devtype->mode1);
	}

	uartclk = max310x_set_ref_clk(dev, s, freq, xtal);
	if (uartclk < 0) {
		ret = uartclk;
		goto out_uart;
	}

	dev_dbg(dev, "Reference clock set to %i Hz\n", uartclk);

	for (i = 0; i < devtype->nr; i++) {
+1 −1
Original line number Diff line number Diff line
@@ -1084,8 +1084,8 @@ static int uart_tiocmget(struct tty_struct *tty)
		goto out;

	if (!tty_io_error(tty)) {
		result = uport->mctrl;
		uart_port_lock_irq(uport);
		result = uport->mctrl;
		result |= uport->ops->get_mctrl(uport);
		uart_port_unlock_irq(uport);
	}
+7 −6
Original line number Diff line number Diff line
@@ -145,12 +145,13 @@ struct serial_rs485 {
#define SER_RS485_ENABLED		_BITUL(0)
#define SER_RS485_RTS_ON_SEND		_BITUL(1)
#define SER_RS485_RTS_AFTER_SEND	_BITUL(2)
#define SER_RS485_RX_DURING_TX		_BITUL(3)
#define SER_RS485_TERMINATE_BUS		_BITUL(4)
#define SER_RS485_ADDRB			_BITUL(5)
#define SER_RS485_ADDR_RECV		_BITUL(6)
#define SER_RS485_ADDR_DEST		_BITUL(7)
#define SER_RS485_MODE_RS422		_BITUL(8)
/* Placeholder for bit 3: SER_RS485_RTS_BEFORE_SEND, which isn't used anymore */
#define SER_RS485_RX_DURING_TX		_BITUL(4)
#define SER_RS485_TERMINATE_BUS		_BITUL(5)
#define SER_RS485_ADDRB			_BITUL(6)
#define SER_RS485_ADDR_RECV		_BITUL(7)
#define SER_RS485_ADDR_DEST		_BITUL(8)
#define SER_RS485_MODE_RS422		_BITUL(9)

	__u32	delay_rts_before_send;
	__u32	delay_rts_after_send;