Commit 02149609 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'tty-6.8-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty

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
......@@ -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);
......
......@@ -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);
regmap_read(s->regmap, MAX310X_STS_IRQSTS_REG, &val);
if (!(val & MAX310X_STS_CLKREADY_BIT)) {
dev_warn(dev, "clock is not stable yet\n");
}
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)
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++) {
......
......@@ -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);
}
......
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment